key/value对在Redis中是如何存储的

How key/value pairs are stored in Redis

我们使用Elasticache Redis节点来存储数据。

所有键的格式相同:
- 密钥是 md5 哈希 - 128 位(16 字节,32 个字符串字符字节)。
- 值为时间戳字符串 - 19 个字节。
总的来说,密钥大小为 32+19=51 bytes

我们有 84 917 361 百万个密钥。
我假设,Redis shell 消耗的总内存接近 84917361*51 = 4.03 gb

实际上,需要 11.07 gb
info 命令的输出: used_memory_human:11.07G

  1. 剩下的内存都花在什么上面了,7 gb?
  2. 有没有办法将 md5 存储为 16 字节散列,而不是 32 个字符的字符串?

谢谢,非常感谢任何帮助。

On what is spent rest of the memory, 7 gb?

简短回答:Redis 不将键和值存储为原始字符串

事实上,

  1. 密钥被包装成一个sdshdr结构(对于最新版本,它是一个更紧凑的结构),这有一些开销,例如字符串的长度。

  2. 值被包装成一个redisObject结构,这也有一些开销,例如对象编码,refcount.

  3. 当 Redis 将一对插入字典时,还有其他开销,例如next 指针和 key 指针在 dictEntry 结构中。

所有这些开销都消耗了剩余的内存。

为了提高内存效率,可以参考@Kevin Christopher Henry 提到的那篇文章(小hash可以节省很多redisObject的开销,可以用ziplist使元素在内存中更紧凑)。

Is there a way to store md5 as 16 bytes hash, not string with 32 characters?

使用哈希函数(例如 Murmurhash)为每个 md5 字符串创建摘要

这样就可以得到一个8字节(64位)的摘要。但是,您无法从 Murmurhash 摘要中获取原始 md5 字符串。所以如果你关心md5的值,你可以采用这种方法。