redis5大对象的底层编码、使用条件和优劣势总结
1.redis5大对象底层编码
类型 |
编码 |
对象 |
REDIS_STRING |
REDIS_ENCODING_INT |
使用整数值实现的字符串对象 |
REDIS_ENCODING_EMBSTR |
使用embstr编码的简单动态字符串实现的字符串对象 |
|
REDIS_ENCODING_RAW |
使用简单动态字符串实现的字符串对象 |
|
REDIS_LIST |
REDIS_ENCODING_ZIPLIST |
使用压缩列表实现的列表对象 |
REDIS_ENCODING_LINKEDLIST |
使用双端链表实现的列表对象 |
|
REDIS_HASH |
REDIS_ENCODING_ZIPLIST |
使用压缩列表实现的哈希对象 |
REDIS_ENCODING_HT |
使用字典实现的哈希对象 |
|
REDIS_SET |
REDIS_ENCODING_INTSET |
使用整数集合实现的集合对象 |
REDIS_ENCODING_HT |
使用字典实现的集合对象 |
|
REDIS_ZSET |
REDIS_ENCODING_ZIPLIST |
使用压缩列表实现的有序集合对象 |
REDIS_ENCODING_SKIPLIST |
使用跳跃表和字典实现的有序集合对象 |
2.redis对象使用不同编码的条件
类型 |
编码 |
条件 |
备注 |
REDIS_STRING |
REDIS_ENCODING_INT |
保存的是整数值,并且这个整数值可以用long类型表示 |
|
REDIS_ENCODING_EMBSTR |
保存的是字符串值,并且这个字符串值的长度<= 32
|
|
|
REDIS_ENCODING_RAW |
保存的是字符串值,并且这个字符串值的长度 > 32 |
|
|
REDIS_LIST |
REDIS_ENCODING_ZIPLIST |
同时满足: 所有的字符串元素的长度 < 64 保存的元素个数 < 512 |
list-max-ziplist-value和 list-max-ziplist-entries选项修改 |
REDIS_ENCODING_LINKEDLIST |
有一个条件满足: 有一个字符串元素的长度 >= 64 保存的元素个数 >= 512 |
|
|
REDIS_HASH |
REDIS_ENCODING_ZIPLIST |
同时满足: 所有的字符串元素的长度 < 64 保存的元素个数 < 512 |
|
REDIS_ENCODING_HT |
有一个条件满足: 有一个字符串元素的长度 >= 64 保存的元素个数 >= 512 |
|
|
REDIS_SET |
REDIS_ENCODING_INTSET |
同时满足: 保存的所有元素都是整数值 保存的元素个数 < 512 |
|
REDIS_ENCODING_HT |
有一个条件满足: 有一个元素不是整数值 保存的元素个数 >= 512 |
|
|
REDIS_ZSET |
REDIS_ENCODING_ZIPLIST |
同时满足: 所有的字符串元素长度 < 64 保存的元素个数 < 128 |
|
REDIS_ENCODING_SKIPLIST |
有一个条件满足: 有一个字符串元素长度 >= 64 保存的元素个数 >= 128 |
3.redis不同编码的优劣势
类型 |
编码 |
优劣势 |
REDIS_STRING |
REDIS_ENCODING_INT |
|
REDIS_ENCODING_EMBSTR |
优势: 1.字符串对象的所有数据都保存在一块连续的内存里,更好利用缓存 2.内存分配和释放各自只有一次 劣势: 1.不支持修改操作 2.连续空间不好开辟 |
|
REDIS_ENCODING_RAW |
|
|
REDIS_LIST |
REDIS_ENCODING_ZIPLIST |
优势: 1.使用的是连续内存块,存储和读取效率高 劣势: 1.不利于插入和删除这种需要频繁申请和释放内存的操作 2.ziplist长度很长时,需要分配连续空间大,一次realloc重新分配内存时要耗费更长的空间。 |
REDIS_ENCODING_LINKEDLIST |
优势: 1.插入和删除的时间复杂度很低 劣势: 1.每个节点需要维护两个指针,增加开销 2.每个节点都是单独的内存块,地址不一定连续,导致内存回收时内存碎片率高 3.访问时间复杂度较高
现在REDIS_LIST统一用”quicklist”数据结构。 |
|
REDIS_HASH |
REDIS_ENCODING_ZIPLIST |
劣势: 1.每次插入或修改引发的realloc操作会有更大概率造成内存拷贝,降低性能 2.当ziplist数据项过多,查找指定的数据项的性能会遍历,需要遍历整个list |
REDIS_ENCODING_HT |
|
|
REDIS_SET |
REDIS_ENCODING_INTSET |
|
REDIS_ENCODING_HT |
|
|
REDIS_ZSET |
REDIS_ENCODING_ZIPLIST |
|
REDIS_ENCODING_SKIPLIST |
优势: 同时使用了哈希表和跳跃表来实现。 使用哈希表,可以在o(1)内获取指定成员的分数:zscore 使用跳跃表,可以o(logn)的时间复杂度执行范围型操作:zrange、zrank,而不需要排序。 |
来源:《redis设计与实现》