「Redis数据结构」RedisObject
创始人
2024-03-19 12:29:49
0

「Redis数据结构」RedisObject

文章目录

  • 「Redis数据结构」RedisObject
    • 一、概述
    • 二、结构
    • 三、编码方式
    • 四、小结
    • 五、参考

一、概述

redisObject对象非常重要,Redis对象的类型内部编码内存回收共享对象等功能,都需要redisObject支持。

redis 不是一个普通的 key-value存储器,其中 key 类型一般为字符串,而 value 类型则为 redis 对象(redis object)redis 对象可以绑定各种类型的数据,如 string、list 和 set等等。


二、结构

RedisObject

  • 使用者的角度来看,⼀个Redis节点包含多个database(非cluster模式下默认是16个,cluster模式下只能是1个),而一个database维护了从key space到object space的映射关系。这个映射关系的key是string类型,⽽value可以是多种数据类型,比如:string, list, hash、set、sorted set等。我们可以看到,key的类型固定是string,而value可能的类型是多个。
  • Redis内部实现的⾓度来看,database内的这个映射关系是用⼀个dict来维护的。dict的key固定用⼀种数据结构来表达就够了,这就是动态字符串sds。而value则比较复杂,为了在同⼀个dict内能够存储不同类型的value,这就需要⼀个通⽤的数据结构,这个通用的数据结构就是robj,全名是redisObject。

image-20221205012924009


三、编码方式

对象的 ptr 指针指向对象的底层实现数据结构, 而这些数据结构由对象的 encoding 属性决定。

encoding 属性记录了对象所使用的编码, 也即是说这个对象使用了什么数据结构作为对象的底层实现

Redis中会根据存储的数据类型不同,选择不同的编码方式,共包含11种不同类型:

编号编码方式说明
0OBJ_ENCODING_RAWraw编码动态字符串
1OBJ_ENCODING_INTlong类型的整数的字符串
2OBJ_ENCODING_HThash表(字典dict)
3OBJ_ENCODING_ZIPMAP已废弃
4OBJ_ENCODING_LINKEDLIST双端链表
5OBJ_ENCODING_ZIPLIST压缩列表
6OBJ_ENCODING_INTSET整数集合
7OBJ_ENCODING_SKIPLIST跳表
8OBJ_ENCODING_EMBSTRembstr的动态字符串
9OBJ_ENCODING_QUICKLIST快速列表
10OBJ_ENCODING_STREAMStream流

每种类型的对象都至少使用了两种不同的编码

类型编码对象
REDIS_STRINGREDIS_ENCODING_INT使用整数值实现的字符串对象。
REDIS_STRINGREDIS_ENCODING_EMBSTR使用 embstr 编码的简单动态字符串实现的字符串对象。
REDIS_STRINGREDIS_ENCODING_RAW使用简单动态字符串实现的字符串对象。
REDIS_LISTREDIS_ENCODING_ZIPLIST使用压缩列表实现的列表对象。
REDIS_LISTREDIS_ENCODING_LINKEDLIST使用双端链表实现的列表对象。
REDIS_HASHREDIS_ENCODING_ZIPLIST使用压缩列表实现的哈希对象。
REDIS_HASHREDIS_ENCODING_HT使用字典实现的哈希对象。
REDIS_SETREDIS_ENCODING_INTSET使用整数集合实现的集合对象。
REDIS_SETREDIS_ENCODING_HT使用字典实现的集合对象。
REDIS_ZSETREDIS_ENCODING_ZIPLIST使用压缩列表实现的有序集合对象。
REDIS_ZSETREDIS_ENCODING_SKIPLIST使用跳跃表和字典实现的有序集合对象。

使用 OBJECT ENCODING 命令可以查看一个数据库键的值对象的编码:

redis> SET msg "hello wrold"
OKredis> OBJECT ENCODING msg
"embstr"redis> SET story "long long long long long long ago ..."
OKredis> OBJECT ENCODING story
"raw"redis> SADD numbers 1 3 5
(integer) 3redis> OBJECT ENCODING numbers
"intset"redis> SADD numbers "seven"
(integer) 1redis> OBJECT ENCODING numbers
"hashtable"

OBJECT ENCODING 对不同编码的输出

对象所使用的底层数据结构编码常量OBJECT ENCODING 命令输出
整数REDIS_ENCODING_INT"int"
embstr 编码的简单动态字符串(SDS)REDIS_ENCODING_EMBSTR"embstr"
简单动态字符串REDIS_ENCODING_RAW"raw"
字典REDIS_ENCODING_HT"hashtable"
双端链表REDIS_ENCODING_LINKEDLIST"linkedlist"
压缩列表REDIS_ENCODING_ZIPLIST"ziplist"
整数集合REDIS_ENCODING_INTSET"intset"
跳跃表和字典REDIS_ENCODING_SKIPLIST"skiplist"

通过 encoding 属性来设定对象所使用的编码, 而不是为特定类型的对象关联一种固定的编码, 极大地提升了 Redis 的灵活性和效率, 因为 Redis 可以根据不同的使用场景来为一个对象设置不同的编码, 从而优化对象在某一场景下的效率。

举个例子, 在列表对象包含的元素比较少时, Redis 使用压缩列表作为列表对象的底层实现:

  • 因为压缩列表比双端链表更节约内存, 并且在元素数量较少时, 在内存中以连续块方式保存的压缩列表比起双端链表可以更快被载入到缓存中;
  • 随着列表对象包含的元素越来越多, 使用压缩列表来保存元素的优势逐渐消失时, 对象就会将底层实现从压缩列表转向功能更强、也更适合保存大量元素的双端链表上面;

其他类型的对象也会通过使用多种不同的编码来进行类似的优化。


四、小结

  • redisObjec是联结两个层面的数据结构的桥梁。
  • 为多种数据类型提供一种统一的表示方式。
  • 允许同一类型的数据采用不同的内部表示,从而在某些情况下尽量节省内存。
  • 支持对象共享和引用计数。当对象被共享的时候,只占用一份内存拷贝,进一步节省内存。

五、参考

对象的类型与编码

redisObject详解

相关内容

热门资讯

原创 民... 如今,律师这个职业在社会上的口碑并不特别好,主要原因是有些律师缺乏正义感。在律师圈里,有一些知名律师...
为促进民用航空事业高质量发展提... 法治日报全媒体记者 蒲晓磊 2025年12月27日,十四届全国人大常委会第十九次会议表决通过新修订的...
宁夏:严惩恶意欠薪违法犯罪 维... 原标题:严惩恶意欠薪违法犯罪 维护劳动者合法权益(主题) 宁夏:部署开展治理欠薪冬季专项行动(副题)...
镇江长江锚地纠纷,“枫警” 联... 现场 扬子晚报网12月27日讯(通讯员 滕超 记者 姜天圣)12月27日上午,长江镇江段定易洲锚地,...
原创 七... 他的名字叫余海水,虽然年已77岁,但他多次凭借聪明才智,在监狱里巧妙地演绎了一出又一出的障眼法。尽管...
玉泉区十大继承律师排名推荐:张... 在呼和浩特玉泉区的法律服务领域,继承纠纷往往牵涉复杂的情感纠葛与财产分配难题。当亲情与利益交织,一位...
笔架山街道联动多方力量调处纠纷 本报记者 范天娇 本报通讯员 闫大平 王文宗 “多亏了街道的调解团队,小区停车难的问题这么快就解决了...
原创 高... 日本媒体近日透露,首相高市早苗可能会在12月26日参拜靖国神社。这个日期的选择非常微妙,一方面避开了...
财政部:2026年继续实施更加... 全国财政工作会议12月27日至28日在北京召开。会议指出,2026年继续实施更加积极的财政政策。一是...
政策调整背后的思考:当科技奖励... 作为一名关注地方政策与企业发展自媒体博主,近期注意到葫芦岛市总工会此前发布的《支持科技型中小微企业发...