Redis hash 的底层结构主要有两种数据结构:ziplist(压缩列表) 和 hashtable(哈希表)。根据 hash 的大小和配置,Redis 会选择最适合的数据结构来存储 hash。
1. Ziplist(压缩列表)
压缩列表是一种经过特殊编码的双端链表,用来存储小的哈希对象。它是一种内存高效的方式,适用于字段数目较少且字段值较小的哈希对象。
特点:
- 存储紧凑,减少内存占用。
- 适合存储少量小数据。
- 通过顺序扫描操作,读取和写入速度快。
使用场景: 当 hash 的字段数量较少,并且每个字段的值都比较小时,Redis 会使用 ziplist 存储该 hash。
2. Hashtable(哈希表)
哈希表是 Redis 存储大 hash 对象的主要数据结构。它使用标准的哈希表实现,提供 O(1) 时间复杂度的读写操作。
特点:
- 提供快速的 O(1) 时间复杂度的读写操作。
- 内存消耗较大,适用于较大的 hash 对象。
- 在扩展或收缩时可能会导致重新哈希,产生一定的开销。
使用场景: 当 hash 的字段数量较多,或者字段的值较大时,Redis 会使用 hashtable 存储该 hash。
底层实现的选择
Redis 会根据 hash 的字段数量和单个字段值的大小来选择使用哪种数据结构。默认情况下,当以下两个条件之一满足时,Redis 会使用 hashtable 来存储 hash:
1、Hash 对象中字段的数量超过了 hash-max-ziplist-entries(默认值为 512)。
2、Hash 对象中任意字段的值超过了 hash-max-ziplist-value(默认值为 64 字节)。
这些配置项可以在 Redis 配置文件中进行调整,以适应具体应用的需求。
配置示例
在 Redis 配置文件中,您可以看到类似如下的配置项:
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
这些配置项的含义如下:
hash-max-ziplist-entries: 当 hash 的字段数量超过这个值时,Redis 会将数据结构从 ziplist 转换为 hashtable。
hash-max-ziplist-value: 当 hash 的任意字段值长度超过这个值时,Redis 会将数据结构从 ziplist 转换为 hashtable。
总结
Redis hash 底层通过压缩列表和哈希表两种数据结构实现,以在不同的使用场景下提供最佳的性能和内存使用效率。压缩列表适用于小规模的 hash,对内存利用率高;而哈希表则适用于大规模的 hash,提供快速的读写性能。