相关命令
type (key)
type 命令实际返回的就是当前键的数据结构类型,它们分别是:string(字符串)、list(列 表)、hash(哈希)、set(集合)、zset(有序集合)
但是,这些这是对外的数据结构,实际上 Redis 针对每种数据结构都有自己的底层内部编码实现,而且是多种实现,这样 Redis 会在合适的场景选择合适的内部编码
object encoding (key)
在 Redis 中,你可以使用 object encoding 命令来查看特定键的编码方式。这个命令会返回该键所使用的内部编码。
Redis 数据类型和对应内部编码
数据类型 | 内部编码 |
string | string |
int | |
smbstr | |
hash | hashtable |
ziplist | |
list | linkedlist |
ziplist | |
set | hashtable |
intset | |
zset | skiplist |
ziplist |
字符串(String)
Redis 的字符串是二进制安全的,它们可以存储任何类型的数据,如文本或二进制数据。字符串的最大长度为 512 MB。
- raw:直接存储字符串对象。当字符串长度较大时使用这种编码。
- embstr:将字符串和 Redis 对象头部合并存储。当字符串较短(小于 44 字节)时使用这种编码,以减少内存分配次数和空间消耗。
- int:对于可以表示为 64 位有符号整数的字符串,使用整数编码,节省存储空间。
哈希(Hash)
哈希是一个键值对集合,通常用于存储对象。
- ziplist:适用于小型哈希,将所有键值对存储在一个连续的内存块中。
- hashtable:对于较大的哈希,使用哈希表编码。
列表(List)
列表是按顺序排列的字符串集合,支持从头部或尾部推入和弹出元素。
- ziplist:适用于小型列表,将所有元素存储在一个连续的内存块中,适合存储少量元素或元素较短的列表。
- linkedlist:对于较大的列表,使用双向链表存储,每个节点包含一个指向前后节点的指针。
quicklist是 Redis 3.2 版本引入的一种编码方式,旨在结合 ziplist 和 linklist 的优点,提供更高效的内存使用和性能表现。
quicklist是一种将多个 ziplist链接在一起的双向链表。每个节点是一个 ziplist ,这种设计的目的是通过减少内存碎片和避免过多的内存分配来优化列表的性能。quicklist 结合了 ziplist 和 linklist 的优势,使得它在存储和操作列表时具有更好的性能和更低的内存开销。
集合(Set)
集合是无序的字符串集合,不允许重复元素。
- intset:适用于只包含整数值的小型集合。
- hashtable:对于大型集合或包含非整数值的集合,使用哈希表编码。
有序集合(Sorted Set)(zset)
- ziplist:适用于小型有序集合,将所有元素和评分存储在一个连续的内存块中。
- skiplist:对于较大的有序集合,使用跳表(skiplist)和哈希表的组合,以提供高效的范围查询和插入操作。
总结
Redis 这样设计有两个好处:
1)可以改进内部编码,而对外的数据结构和命令没有任何影响,这样一旦开发出更优秀的内部编码, 无需改动外部数据结构和命令,例如 Redis 3.2 提供了 quicklist,结合了 ziplist 和 linkedlist 两者的优势,为列表类型提供了一种更为优秀的内部编码实现,而对用户来说基本无感知。
2)多种内部编码实现可以在不同场景下发挥各自的优势,例如 ziplist 比较节省内存,但是在列表元素比较多的情况下,性能会下降,这时候 Redis 会根据配置选项将列表类型的内部实现转换为 linkedlist,整个过程用户同样无感知。