在内部,Redis 以最有效的方式存储字符串。将整数强制转换为 radix 10 字符串实际上会占用更多内存。
这是 Redis 存储字符串的方式 -
- 小于 10000 的整数存储在共享内存池中,并且没有任何内存开销。如果您愿意,可以通过更改redis.h 中的常量 REDIS_SHARED_INTEGERS并重新编译 Redis 来增加此限制。
- 大于 10000 且在 long 范围内的整数占用 8 个字节。
- 常规字符串采用 len(string) + 4 个字节作为长度 + 4 个字节用于标记可用空间 + 1 个字节作为空终止符 + 8 个字节作为 malloc 开销。
在您引用的示例中,它的问题是 8 个字节的长字符串和 21 个字节的字符串。
编辑 :
因此,如果我有一组数字都小于 10,000,Redis 如何存储我的集合?
这取决于你有多少元素。
如果您的集合中的元素少于 512 个(请参阅set-max-intset-entries
参考资料),那么该集合将存储为一个 IntSet。IntSet 是有序整数数组的美名。由于您的数字小于 10000,因此每个元素将使用 16 位。它(几乎)与 C 数组一样具有内存效率。
如果您有超过 512 个元素,则该集合将成为一个 HashTable。集合中的每个元素都包装在一个名为 的结构中robj
,该结构具有 16 个字节的开销。该robj
结构有一个指向共享整数池的指针,因此您无需为整数本身支付任何额外费用。最后,robj
实例存储在哈希表中,哈希表的开销与集合的大小成正比。
如果您对某个元素究竟消耗了多少内存感兴趣,请在您的数据集上运行redis-rdb-tools(免责声明:我是该工具的作者)。或者你可以阅读MemoryCallback类的源代码,注释解释了内存是如何布局的。