Redis:大密钥集的高效密钥分片

Posted

技术标签:

【中文标题】Redis:大密钥集的高效密钥分片【英文标题】:Redis: Efficient key sharding for large key set 【发布时间】:2014-12-18 17:17:05 【问题描述】:

我遇到了一个问题,我的服务器内存超出了我的容量。我需要减小数据库大小,以便我仍然可以使用 Redis。我的应用程序是一个庞大的键/值存储,其中键是用户给定的文本字符串(目录/文件路径)。这些值是指向我创建的对象的非常简单的指针。所以它是一个对象存储。问题是我有一个 PB 的对象,其中一个对象可能是 100K 字节。我实际上可以将平均对象限制为不少于 1M 字节,因此 10^15 / 10^6 = 10^9 个对象。因为每个对象都需要一个密钥,即 10^9 或 1G 个密钥。如果每个键/值对为 100 字节,则 RAM 中为 100GB。这几乎适合具有 128GB RAM 的服务器,但它并不是服务器中唯一发生的事情。如果可以的话,我想减少足迹。

问题是往哪个方向走?我尝试压缩输入键,但在我的测试中它实际上比原来的要大,因为它是一个很短的字符串而不是一个文档。我曾考虑为较小的文件使用不同的数据存储,比如 1G 以下。这将减少我需要放入 Redis 的内容。我还考虑过使用一种散列算法,该算法有意重叠并分箱键,然后将散列增量作为值放入合并的键中。如果这太令人困惑,这里是一个虚构的例子:

Key    Hash
A       15gh2
B       15gh2
C       4Tgnx

然后我将存储在 Redis 中: V(15gh2) = A, B, A-Value=A-Object, B-Value=B-Object

V(4Tgnx) = C

可能有一种代数表示的正确方法,但我不知道该怎么做。 “A-Object”是我指向 A 对象的指针。我想要做的是最终得到更少的密钥,基于我读过的一些关于密钥比 Redis 哈希值更昂贵的帖子(不要将“Redis 哈希”与“哈希”算法混淆)。我可以访问http://ieeexplore.ieee.org/ 完整数据库来搜索有关该主题的论文。我不太确定我应该在查询字段中搜索什么?我尝试了诸如“哈希链”之类的东西,但这似乎是针对加密而不是高效的数据库存储。任何解决方案的想法或更大的研究路径都将不胜感激。

更新:如 cmets 部分所述,这些值或我所说的“A-Object”、“B-Object”是编码的“指针”,它们是指向对象的路径。这些是 XFS 文件系统中的实际文件。它们可以简单地编码为“1:6:2”以指向路径“/data/d0001/d0006/d0002”。所以只需要存储一个非常短的值“1:6:2”。

【问题讨论】:

如果没有更多关于您的 KV 对的详细信息,我只能提供模糊的想法。我首先想到的是我指向的对象中的数据是如何表示的?我真的需要我在那里使用的所有字节吗?例如,当浮点数足够时我是否使用双打?等等。如果您可以减小 Value 对象的大小(或指向的对象的大小),似乎您将获得最大的收益。 这些值是另一个目录树中的“最终”路径。我说“最终”是因为我可以完全控制布局,它们只需要 XFS 文件系统中的每个对象一个文件。所以编码可以非常紧凑,因为我知道路径的前缀,它只是唯一的标识符。例如,我创建了一个结构非常规则的目录树。假设 d0001/d0004/d0002 可能是对象的“路径”。但我可以将其编码为“1:4:2”,例如作为值。这有帮助吗? 是的,这有帮助。然后我要注意的是 1:4:2,1、4 和 2 是存储为整数(4 个或 8 个字节)还是一个字符(每个 1 个字节)?然后你只需要决定你需要什么(每个深度的值范围)而不使用任何额外的字节。如果您可以拥有的最大的是 d9999 -> 9999,那么您当然不需要 8 字节的 int 来存储它,2 字节就足够了。如果您没有 2 字节数据类型,您可以在 4 字节(或 8 字节)int 中创建一个或保留空间:前 2 个字节 = 级别 1,接下来的 2 个字节 = 级别 2,等等。也许你'已经在做这种风格的东西了 是的,好点。我目前没有做任何优化,我只是开始在这方面工作。所以现在它是一个字符串值,我只是把它变成一个路径。所以我也在考虑为这个值做最紧凑的固定位整数表示。更让我难过的是钥匙。 另一件要考虑的事情是:您是否需要同时在内存中存储所有这些 KV 对?或者,你是否可以一次为每个 CPU 生成 1GB 的数据,让每个 CPU 进行处理,然后当一个 CPU 完成时,再为它生成另外的 1GB?那么您在任何给定时间都只使用#CPUs GB。 【参考方案1】:

处理这么多数据的标准方法是跨多个服务器对数据进行分区。

请参阅 http://redis.io/topics/partitioning 以获取有关如何执行此操作的建议。

【讨论】:

以上是关于Redis:大密钥集的高效密钥分片的主要内容,如果未能解决你的问题,请参考以下文章

Redis 如何高效安全删除大 Hash Key

AWS DynamoDB - 分区密钥和密钥分片

R中的高效方法是将新列添加到具有大数据集的数据框中

具有大型(70,000+ 项)数据集的高效 jQuery 实时搜索

用于 MongoDB API 的分片密钥和 Azure CosmosDB

算法如何设计--高效的大数据匹配算法