你对开源软件的要求太多了。
如果您有几十万美元的预算来购买一些企业级软件,那么有几个解决方案。开箱即用没有什么可以满足您的需求,但有些公司的产品与您正在寻找的产品相近。
“快速(因此将允许在其上执行查询)”
如果您有一个键值存储,那么一切都应该非常快。然而,问题变成了如果没有构建在键值存储之上的本体或数据模式,您最终将针对每个查询遍历整个数据库。您需要一个包含要存储的每种“类型”数据的键的索引。
在这种情况下,您通常可以对大约 15,000 台机器并行执行查询。瓶颈在于便宜的硬盘驱动器每秒可进行 50 次寻道。如果您的数据集适合 RAM,那么您的性能将非常高。但是,如果键存储在 RAM 中但没有足够的 RAM 来存储值,则系统将在几乎所有键值查找时转到磁盘。每个键都位于驱动器上的随机位置。
这将您限制为每台服务器每秒 50 次键值查找。而当键值对存储在 RAM 中时,在商用硬件(例如 Redis)上每台服务器每秒执行 10 万次操作并不罕见。
然而,串行磁盘读取性能非常高。我在串行读取时寻求驱动器达到 50 MB/s (800 Mb/s)。因此,如果您将值存储在磁盘上,则必须构建存储结构,以便可以串行读取需要从磁盘读取的值。
那就是问题所在。除非您将键值对完全存储在 RAM 中(或 RAM 中的键与 SSD 驱动器上的值),否则您无法在 vanilla 键值存储上获得良好的性能,或者如果您在密钥,然后将数据聚集在磁盘上,以便可以通过串行磁盘读取轻松检索给定类型的所有密钥。
如果一个键有多种类型(例如,如果您在数据库中有数据类型继承关系),那么该键将是多个索引表的一个元素。在这种情况下,您将不得不进行时空权衡来构造这些值,以便可以从磁盘中连续读取它们。这需要存储键值的冗余副本。
您想要的将比键值存储更高级,特别是如果您打算进行查询。然而,存储大文件的问题不是问题。假装您的系统最多可以键入 50 兆。然后,您只需将 1 gig 文件分解为 50 meg 段,并为每个段值关联一个键。使用简单的服务器可以直接将您想要的文件部分转换为键值查找操作。
实现冗余的问题更加困难。很容易为服务器“源代码”或“部分文件”键值表,以便在特定服务器死机时,可以以线速 (1 Gb/s) 将服务器的数据重建到备用服务器上。通常,您可以使用“心跳”系统检测服务器死亡,如果服务器在 10 秒内没有响应,则会触发该系统。甚至可以针对部分文件编码的键值表进行键值查找,但这样做效率低下,但仍然为您提供了服务器故障事件的备份。一个更大的问题是,几乎不可能使备份保持最新,并且数据可能已经存在 3 分钟。如果您进行大量写入,备份功能将引入一些性能开销,
我不是在故障模式下维护数据库一致性和完整性约束的专家,所以我不确定这个要求会带来什么问题。如果您不必担心这一点,它会大大简化系统的设计及其要求。
快速(因此将允许在其上执行查询)
首先,当您的数据库这么大时,忘记连接或任何比 n*log(n) 扩展速度更快的操作。您可以做两件事来替换通常用连接实现的功能。您可以对数据进行结构化以便不需要进行连接,也可以“预编译”正在执行的查询并进行时空折衷并预先计算连接并将它们存储起来以供提前查找.
对于语义网络数据库,我认为我们将看到人们预先编译查询并进行时间-空间权衡,以便在即使是中等大小的数据集上也能获得不错的性能。我认为这可以由数据库后端自动和透明地完成,而不需要应用程序程序员的任何努力。然而,我们才刚刚开始看到企业数据库为关系数据库实施这些技术。据我所知,没有开源产品能做到这一点,如果有人试图为水平可扩展数据库中的链接数据这样做,我会感到惊讶。
对于这些类型的系统,如果您有额外的 RAM 或存储空间,则出于性能原因,最好使用它来预先计算和存储常见子查询的结果,而不是为键值存储添加更多冗余。预先计算结果并按您要查询的键排序,以将 n^2 连接转换为 log(n) 查找。任何比 n*log(n) 扩展性差的查询或子查询都需要执行其结果并将其缓存在键值存储中。
如果您正在执行大量写入,则缓存的子查询将比它们被处理的速度更快地失效,并且没有性能优势。处理缓存子查询的缓存失效是另一个棘手的问题。我认为一个解决方案是可能的,但我还没有看到它。
欢迎来到地狱。您不应该期望再过 20 年才能免费获得这样的系统。
到目前为止,似乎没有满足我提到的标准的数据库或键值存储,即使在提供 100 分的赏金之后,问题也没有得到回答!
你在祈求奇迹。等待 20 年,直到我们拥有开源奇迹数据库,否则您应该愿意为根据您的应用程序需求定制的解决方案付费。