redis数据结构与对象

OBJECT ENCODING KEY //查看对象的底层编码

OBJECT REFCOUNT KEY //查看对象的引用计数

OBJECT IDLETIME KEY //查询对象的空转时长

类型常量 对象的名称

REDIS_STRING 字符串对象 string

REDIS_LIST 列表对象 list

REDIS_HASH 哈希对象 hash

REDIS_SET 集合对象 set

REDIS_ZSET 有序集合对象 zset

编码和底层实现

OBJECT ENCODING KEY //查看

编码常量 编码所对应的底层数据结构

REDIS_ENCODING_INT long 类型的整数

REDIS_ENCODING_EMBSTR embstr 编码的简单动态字符串

REDIS_ENCODING_RAW 简单动态字符串

REDIS_ENCODING_HT 字典

REDIS_ENCODING_LINKEDLIST 双端链表

REDIS_ENCODING_ZIPLIST 压缩列表

REDIS_ENCODING_INTSET 整数集合

REDIS_ENCODING_SKIPLIST 跳跃表和字典

不同类型和编码的对象

类型 编码 对象

REDIS_STRING REDIS_ENCODING_INT 使用整数值实现的字符串对象。int

REDIS_STRING REDIS_ENCODING_EMBSTR 使用 embstr 编码的简单动态字符串实现的字符串对象。embstr

REDIS_STRING REDIS_ENCODING_RAW 使用简单动态字符串实现的字符串对象。raw

REDIS_LIST REDIS_ENCODING_ZIPLIST 使用压缩列表实现的列表对象。ziplist

REDIS_LIST REDIS_ENCODING_LINKEDLIST 使用双端链表实现的列表对象。linkedlist

REDIS_HASH REDIS_ENCODING_ZIPLIST 使用压缩列表实现的哈希对象。ziplist

REDIS_HASH REDIS_ENCODING_HT 使用字典实现的哈希对象。hashtable

REDIS_SET REDIS_ENCODING_INTSET 使用整数集合实现的集合对象。intset

REDIS_SET REDIS_ENCODING_HT 使用字典实现的集合对象。hashtable

REDIS_ZSET REDIS_ENCODING_ZIPLIST 使用压缩列表实现的有序集合对象。ziplist

REDIS_ZSET REDIS_ENCODING_SKIPLIST 使用跳跃表和字典实现的有序集合对象。skiplist

字符串对象编码转换

int 编码的字符串对象和 embstr 编码的字符串对象在条件满足的情况下, 会被转换为 raw 编码的字符串对象。

对于 int 编码的字符串对象来说, 如果我们向对象执行了一些命令, 使得这个对象保存的不再是整数值, 而是一个字符串值, 那么字符串对象的编码将从 int 变为 raw 。

在下面的示例中, 我们通过 APPEND 命令, 向一个保存整数值的字符串对象追加了一个字符串值, 因为追加操作只能对字符串值执行, 所以程序会先将之前保存的整数值 10086 转换为字符串值 "10086" , 然后再执行追加操作, 操作的执行结果就是一个 raw 编码的、保存了字符串值的字符串对象:

列表对象编码转换

当列表对象可以同时满足以下两个条件时, 列表对象使用 ziplist 编码:

列表对象保存的所有字符串元素的长度都小于 64 字节;

列表对象保存的元素数量小于 512 个;

不能满足这两个条件的列表对象需要使用 linkedlist 编码。

ps:

因为压缩列表比双端链表更节约内存, 并且在元素数量较少时, 在内存中以连续块方式保存的压缩列表比起双端链表可以更快被载入到缓存中;

随着列表对象包含的元素越来越多, 使用压缩列表来保存元素的优势逐渐消失时, 对象就会将底层实现从压缩列表转向功能更强、也更适合保存大量元素的双端链表上面;

哈希对象编码转换

当哈希对象可以同时满足以下两个条件时, 哈希对象使用 ziplist 编码:

哈希对象保存的所有键值对的键和值的字符串长度都小于 64 字节;

哈希对象保存的键值对数量小于 512 个;

不能满足这两个条件的哈希对象需要使用 hashtable 编码。

ps:

这两个条件的上限值是可以修改的, 具体请看配置文件中关于 hash-max-ziplist-value 选项和 hash-max-ziplist-entries 选项的说明。

集合对象编码转换

当集合对象可以同时满足以下两个条件时, 对象使用 intset 编码:

集合对象保存的所有元素都是整数值;

集合对象保存的元素数量不超过 512 个;

不能满足这两个条件的集合对象需要使用 hashtable 编码。

ps:

第二个条件的上限值是可以修改的, 具体请看配置文件中关于 set-max-intset-entries 选项的说明。

有序集合对象编码的转换

当有序集合对象可以同时满足以下两个条件时, 对象使用 ziplist 编码:

有序集合保存的元素数量小于 128 个;

有序集合保存的所有元素成员的长度都小于 64 字节;

不能满足以上两个条件的有序集合对象将使用 skiplist 编码。

ps:

以上两个条件的上限值是可以修改的, 具体请看配置文件中关于 zset-max-ziplist-entries 选项和 zset-max-ziplist-value 选项的说明。

ps: 内容来自<redis设计与实现>这本书