【问题标题】:Redis — best way to store a large map (dictionary)Redis — 存储大地图的最佳方式(字典)
【发布时间】:2015-07-17 06:00:05
【问题描述】:

我需要做的是存储一对一的映射。该数据集由大量相同类型的键值对(10M+)组成。例如,可以在 Java 中使用 HashMap 对象的单个实例来存储此类数据。

第一种方法是存储大量键值对,如下所示:

SET map:key1 value1
...
SET map:key900000 value900000
GET map:key1

第二种选择是使用单个“哈希”:

HSET map key1 value
...
HSET map key900000 value900000
HGET map key1

Redis Hashes 有一些方便的命令(HMSETHMGETHGETALL 等),而且它们不会污染键空间,所以这看起来是一个更好的选择。但是,使用这种方法时是否有任何性能或内存方面的考虑?

【问题讨论】:

  • 这实际上是一个推荐的使用模式来使用 Redis 节省一些 RAM - redis.io/topics/…

标签: redis


【解决方案1】:

是的,正如Itamar Haber 所说,你应该看看这个redis memory optimization guide。但您还应该记住以下几点:

  1. 首选 HSET 而非 KEYS。 Redis 仅在关键空间管理上就消耗了大量内存。简单(粗略)而言,1 个具有 1,000,000 个键的 HSET 所消耗的内存比 1,000,000 个具有一个值的键所消耗的内存少 10 倍。
  2. 如果内存是主要目标,则保持 HSET 大小小于 hash-max-zipmap-entries 和有效 hash-max-zipmap-value。请务必了解 hash-max-zipmap-entrieshash-max-zipmap-value 的含义。另外,花点时间阅读一下 ziplist。
  3. 您实际上不想使用 10M+ 键处理 hash-max-zipmap-entries;相反,您应该将一个 HSET 分成多个插槽。例如,您将 hash-max-zipmap-entries 设置为 10,000。因此,要存储 10M+ 个密钥,您需要 1000+ 个 HSET 密钥,每个密钥 10,000 个。作为一个粗略的经验法则:crc32(key) % maxHsets。
  4. 阅读strings in redis 并使用基于此结构的实际内存管理的KEY 名称(在HSET 中)长度。简单来说,将密钥长度保持在 7 个字节以下,每个密钥花费 16 个字节,但一个 8 字节密钥每个花费 48 个字节。为什么?了解simple dynamic strings

阅读以下内容可能很有用:

【讨论】:

  • 查看peterbe.com/plog/understanding-redis-hash-max-ziplist-entries 上的图表,其中将数据库总内存占用与不同的存储方式进行了比较。
  • #3 选项非常好。存储密钥将为您提供 zipmap 的优势,并大大减少 redis 中主键的数量。同时 put 和 get 仍然是 O(1) 操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-20
  • 1970-01-01
  • 1970-01-01
  • 2022-01-12
  • 2011-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多