4

我正在使用 redis 为我的 Web 应用程序实现社交流和通知系统。我是 redis 的新手,我对哈希及其效率有些怀疑。

我已经阅读了这篇很棒的 Instagram 帖子 ,并计划实施他们类似的解决方案以减少存储空间。

正如他们的博客中提到的,他们确实喜欢这样

为了利用散列类型,我们将所有媒体 ID 存储到 1000 的存储桶中(我们只取 ID,除以 1000 并丢弃余数)。这决定了我们落入哪个键;接下来,在位于该键的散列中,媒体 ID 是散列中的查找键,用户 ID 是值。举个例子,给定媒体 ID 1155315,这意味着它落入桶 1155 (1155315 / 1000 = 1155):

HSET "mediabucket:1155" "1155315" "939"
HGET "mediabucket:1155" "1155315"
> "939"

因此,他们没有将1000 个单独的键存储在一个带有数千个查找键的哈希中。我的疑问是为什么我们不能将查找键值增加到更大。

例如: Media ID of 1155315 will fall into mediabucket:115 by dividing it by 10000 甚至更大。

他们为什么要解决一个具有 1000 个查找键的哈希桶。为什么他们不能拥有一个具有 100000 个查找键的哈希桶。这与效率有关吗?

我需要您对在我的 Web 应用程序中实施有效方法的建议。

PS请!不要说stackoverflow不是用来提建议的,我也不知道去哪里寻求帮助。

谢谢!

4

2 回答 2

6

是的,这与效率有关。

我们向总是乐于助人的 Redis 核心开发人员之一 Pieter Noordhuis 征求意见,他建议我们使用 Redis 哈希。Redis 中的哈希是可以非常有效地在内存中编码的字典;Redis 设置 'hash-zipmap-max-entries' 配置哈希可以具有的最大条目数,同时仍能有效编码。我们发现这个设置最好在 1000 左右;更高,HSET 命令将导致明显的 CPU 活动。有关更多详细信息,您可以查看 zipmap 源文件。

小散列以一种特殊的方式(zipmaps)编码,即内存高效,但操作 O(N) 而不是 O(1)。因此,使用一个具有 100k 字段的 zipmap 而不是 100 个具有 1k 字段的 zipmap,您不会获得内存收益,但您的所有操作都会慢 100 倍。

于 2012-07-01T12:18:00.870 回答
2

基本上,他们希望存储在单个哈希中的值的数量不超过 1000。很可能,他们设置了 Redis 实例配置以很好地使用这个数字(你的集合hash-zipmap-max-entries)。

每次哈希超过指定的元素数量或元素大小时,它将被转换为真正的哈希表,并且内存节省将丢失。

-- http://redis.io/topics/memory-optimization

据我了解,您的问题是“为什么正好是 1000 而不是更多?” 嗯,这是因为他们必须在空间效率和速度之间做出选择。节省空间的表示具有操作复杂性O(N),不像O(1)普通哈希那样 - 它慢 N 倍,但占用的内存更少。

他们测试了不同的值,发现 1000 是一个很好的折衷解决方案 - 占用空间不大,但仍然足够快。

于 2012-07-01T12:22:56.920 回答