【问题标题】:fast large scale key-value store for a php program用于 php 程序的快速大规模键值存储
【发布时间】:2012-01-28 02:29:50
【问题描述】:

我正在为我的一个项目开发一个全文索引系统。作为索引页面过程的一部分,它将数据拆分为非常非常多的非常小的片段。

我已经得到片段的大小低至 20-30 字节的常量,并且可能更小,它基本上是 2 个 8 字节整数和一个浮点数,构成了实际数据。

由于我正在寻找的规模和由此产生的件数,我正在寻找 mysql 的替代品,它在价值设置远低于我的目标时显示出重大问题。

我目前的想法是键值存储是最好的选择,我已经相应地调整了我的代码。

我尝试了一个数字,但由于某种原因,它们的扩展性似乎都比 mysql 还要小。

我希望存储数亿或数十亿或更多键值对,因此我需要一些不会随着大小而导致性能大幅下降的东西。

我已经尝试过 memcachedb、membase 和 mongo,虽然它们都很容易设置,但没有一个适合我。

由于所需的密钥数量和可用内存有限,membase 的问题最多。写入速度在这里非常重要,因为这是一个非常接近均衡的工作量,我写了一次,然后读回几次并存储它以供最终更新。

我不需要太多的删除性能,我更喜欢可以很好地集群的东西,因为我希望最终能够跨机器扩展,但它现在需要在单台机器上工作。

我也希望使这个项目易于部署,因此简单的设置会更好。该项目是用php编写的,因此需要从php轻松访问。

我不需要行或其他更高级别的抽象,在这种情况下它们大多没用,我已经从我的一些其他测试中制作了代码以获取键值存储,这似乎可能是最快的,因为我只有 2 个可以从第三个键控的行中检索到的东西,因此几乎没有额外的工作来使用键值存储。有谁知道任何可以像这样扩展的易于使用的项目?

我正在使用这个存储来存储三个数字的单独集合,(大小取决于它们在 mysql 中的存储方式,在其他存储位置可能不正确) 2 个八字节整数,一个用于 ID document 和一个用于单词的 ID 以及该单词在文档中所占比例的浮点表示(作品出现的次数除以文档中的单词数)。此数据的索引是单词 id 和文档 id 所属的范围,每次我需要检索此数据时,它将是给定单词 id 的所有结果。我目前将单词 id、范围和该单词/范围组合的计数器分别转换为数字的二进制表示,并将它们连接起来形成密钥以及 2 位数字,以说明我存储的该密钥的值,文档 ID 或浮点值。

性能测量有点主观,查看将数据放入或从存储中取出数据的过程的输出,查看它处理文档的速度以及快速刷新我的统计计数器,以跟踪更准确的统计数据当我使用每种存储方法时,系统正在工作并查看差异。

【问题讨论】:

  • 你在亚马逊上试过 SimpleDB 吗? aws.amazon.com/simpledb
  • 请在您的问题中添加一些示例性数据。关键是什么?价值是多少?
  • memcachedb 怎么会比 MySQL 慢?你是如何衡量绩效的?您是否需要并发?你是如何进行测试的?你是在单机上测试的吗?您的 PHP 程序如何访问这些值?您需要提供更多信息,例如每秒至少需要多少次写入。
  • 我没有尝试过简单的数据库,但 10GB 的限制很容易导致这么大的数据集出现问题,更不用说这是在托管服务器上完成的,我宁愿保持成本为此,不会增加太多成本。我之前已经看到这个数据集很容易增长到超过 10GB。
  • 我没有具体的最小值,但我可以给出一个很好的估计,我需要在单台机器上每秒至少 2-3k 读取和 2-3k 写入,并且可能至少在集群上每秒5-10k。我确实需要并发,但我不需要即时一致性,但需要相当快速的一致性,比如在 1-5 分钟内。

标签: php nosql key-value key-value-store


【解决方案1】:

你需要提供更多关于你真正想做的事情的数据......

根据您对快速大规模的定义,您有多种选择:

等等..列表变得非常大..

编辑 1:

根据这篇文章,我想说你看看卡桑德拉或伏地魔。 Cassandra 不是一个简单的 KV 存储 per se,因为您可以存储比 K -> V 更复杂的对象

如果您想使用 PHP 检查 cassandra,请查看 phpcassa。但redis 也是一个不错的选择,如果你设置一个副本。

【讨论】:

  • redis 会像 voldemort 一样进入我的列表进行调查,但我担心你要么误解了我的需求,要么误解了 memcache 是什么,memcache 是一个临时内存缓存,我正在寻找持久性存储比存储在我的 RAM 中的要大得多,我研究的一些东西是基于 memcache 的,但 memcache 本身并不是一个真正的选择。如果 Redis 只有非常少量的 RAM,它将如何处理这种数量的内容,它是否可以处理仅在磁盘上的大部分数据?
  • 使用 memcache 进行临时存储和异步队列分发任务以写入磁盘。磁盘将成为您的 I/O 瓶颈,而那里的每一个软件,无论多么好,都只能与您最薄弱的环节——硬盘驱动器一样快。最初存储在内存中,稍后写入磁盘。
  • KV存储,这就是我的回答。那你可以看看cassandra。没有什么,我的意思是没有什么只适用于磁盘会足够快。您需要一个解决方案:ram + disk。但是根据您提供的信息很难给出正确的建议。
  • 我是不是对 KV 存储有误解,我的理解只是将一个 key 与一个 value 联系起来,没有更高层次的抽象。我认为 KV 存储并没有暗示任何存储支持它的内容。我对这种数据存储方法不熟悉,所以我可能不完全理解它。
  • 我会研究一下 cassandra,从 php 中使用它有多容易?
【解决方案2】:

这里添加一些上面没有提到的产品和想法:

  • OrientDB - 这是一个图形/文档数据库,但您可以使用它来存储非常小的“文档” - 它非常快速、高度可扩展,并且经过优化以处理大量记录。

  • Berkeley DB - Berkeley DB 是一种键值对存储,用于许多图形和文档数据库的核心 - 据说有一个与 PHP 兼容的 SQLite 兼容 API。

  • shmop - 如果您愿意做一些肮脏的工作,共享内存操作可能是一种可能的方法。如果您的记录很小且大小固定,这可能对您有用 - 使用固定的记录大小并用零填充。

  • handlersocket - 这个已经开发很久了,不知道靠谱不它基本上让您可以在“较低级别”使用 MySQL,几乎就像键/值存储一样。因为你绕过了查询解析器等。它通常比 MySQL 快得多。

如果您有固定的记录大小、写入少而读取多,您甚至可以考虑读取/写入平面文件/从平面文件读取/写入。可能远不及读取/写入共享内存的速度,但可能值得考虑。我建议您专门针对您的项目要求权衡所有利弊,不仅针对产品,还针对您能想到的任何方法。您的要求并不完全是“主流”,解决方案可能不如选择合适的产品那么明显。

【讨论】:

    猜你喜欢
    • 2020-07-14
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    • 2011-06-12
    • 1970-01-01
    • 2015-02-03
    相关资源
    最近更新 更多