gpt4 book ai didi

performance - Redis 内存使用量比数据多 10 倍

转载 作者:IT王子 更新时间:2023-10-28 23:29:43 26 4
gpt4 key购买 nike

我正在尝试在 redis 中存储一个单词表。表演很棒。

我的方法是创建一个名为“words”的集合并通过“sadd”添加每个新单词。

当添加一个 15.9 MB 且包含大约一百万字的文件时,redis-server 进程会消耗 160 MB 的内存。为什么我使用了 10 倍的内存,有没有更好的方法来解决这个问题?

最佳答案

这是任何高效的数据存储所期望的:单词必须在内存中以由指针链接的单元格的动态数据结构进行索引。结构元数据、指针和内存分配器内部碎片的大小是数据比相应平面文件占用更多内存的原因。

Redis 集以哈希表的形式实现。这包括:

  • 以几何方式增长的指针数组(2 的幂)
  • 当增量重新散列处于事件状态时,可能需要第二个数组
  • 表示哈希表中条目的单链表单元格(3 个指针,每个条目 24 个字节)
  • Redis 对象包装器(每个值一个)(每个条目 16 个字节)
  • 实际数据本身(每个都以 8 个字节为前缀表示大小和容量)

以上所有大小都是针对 64 位实现给出的。考虑到内存分配器开销,对于使用 jemalloc 分配器 (>= 2.4) 的最新版本的 Redis,Redis 每个集合项(在数据之上)至少占用 64 个字节

Redis 提供 memory optimizations对于某些数据类型,但它们不涵盖字符串集。如果你真的需要优化集合的内存消耗,你可以使用一些技巧。我不会只为 160 MB 的 RAM 执行此操作,但如果您有更大的数据,您可以这样做。

如果您不需要集合的并集、交集、差集功能,那么您可以将单词存储在哈希对象中。好处是如果哈希对象足够小,Redis 可以使用 zipmap 自动优化哈希对象。 zipmap 机制在 Redis >= 2.6 中已被 ziplist 取代,但想法是一样的:使用可放入 CPU 缓存中的序列化数据结构,以获得性能和紧凑的内存占用。

为了保证散列对象足够小,数据可以按照某种散列机制进行分布。假设你需要存储1M个项目,添加一个词可以通过以下方式实现:

  • 以 10000 为模(在客户端完成)
  • HMSET 单词:[hashnum] [word] 1

而不是存储:

words => set{ hi, hello, greetings, howdy, bonjour, salut, ... }

你可以存储:

words:H1 => map{ hi:1, greetings:1, bonjour:1, ... }
words:H2 => map{ hello:1, howdy:1, salut:1, ... }
...

要检索或检查单词的存在,它是相同的(散列并使用 HGET 或 HEXISTS)。

使用此策略,如果哈希的模数为根据 zipmap 配置(或 Redis >= 2.6 的 ziplist)选择:

# Hashes are encoded in a special way (much more memory efficient) when they
# have at max a given number of elements, and the biggest element does not
# exceed a given threshold. You can configure this limits with the following
# configuration directives.
hash-max-zipmap-entries 512
hash-max-zipmap-value 64

注意:这些参数的名称已随着 Redis >= 2.6 更改。

这里,1M 项的模 10000 意味着每个哈希对象有 100 个项,这将保证所有这些项都存储为 zipmaps/ziplists。

关于performance - Redis 内存使用量比数据多 10 倍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10004565/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com