Redis 数据结构——robj

Redis的robj对象系统是其高效运作的基础。robj封装了多种数据结构,如sds、intset等,并通过type和encoding字段优化内存使用和查询速度。lru字段用于LRU和LFU淘汰策略,refcount支持对象复用,ptr指向实际数据。文章详细介绍了robj的各个字段及其作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、robj 介绍

Redis 的其他基本数据结构,比如 sds、intset、ziplist、linkedlist、dict、zskiplist,其实 Redis 并没有直接使用这些数据结构来实现键值对的数据库,而是在这些数据结构之上又包装了一层 RedisObject(对象)。

使用 robj的好处:

1、通过不同类型的对象,Redis 可以在执行命令之前,根据对象的类型来判断一个对象是否可以执行给定的命令。

2、可以针对不同的使用场景,为对象设置不同的实现,从而优化内存或查询速度。

二、robj 结构

image.png
robj 字段描述:
type:数据类型

encoding:编码方式

lru:根据 lru 或者 lfu 等不同算法,来存储相关值

refcount:引用计数

ptr:指向实际值的指针

1、type

type 记录了对象所保存值的类型,目前redis中包含以下几种类型:
image.png

2、encoding

encoding 表示为编码方式,如果说每个类型只有一种方式,那么其实 type 和 encoding 两个字段只需要保留一个即可,但 Redis 为了在各种情况下尽可能减少内存,对每种类型的数据在不同情况下有不同的编码格式,所以这里需要用额外的字段标识出来。目前有以下几种编码:
image.png
这里有个 OBJ_ENCODING_EMBSTR,这里着重介绍下。
image.png
从上面代码就可以看出,它是 robj 和 sds 的一个结合,将 sds 直接放在 robj 里,这里限制最多可以存放 44 字节长度的字符串(3.2 版本之前是 39 字节长度)。因为 robj 占 16 字节,sdshdr8 占 3 字节,’\0’一个字节,限制字符串最长为 44 就可以保证在 64 个字节里存放下所有内容 (16+3+1+44==64)。

3、lru

众所周知,Redis 提供了过期数据自动淘汰的策略,如何知道数据是否已经过期?按照什么样的策略淘汰数据?这俩问题的答案都和 lru 这个字段有关。

Redis 给了 lru 这个字段 24 位,但千万别以为字段名叫 lru 就认为它只是 LRU 淘汰策略中才会使用的,其实 LFU 用的也是这个字段。

我估计是 Redis 作者先写了 LRU 策略,所以直接就叫 lru 了,后来再加上 LFU 策略的时候直接复用这个字段了。

lru 字段在不同淘汰策略时有不同的含义:
1、当使用 LRU 策略时,它就是一个 24 位的秒级 unix 时间戳,代表这个数据在第多少秒被更新过。

2、但使用 LFU 策略时,24 位会被分为两部分,16 位的分钟级时间戳和 8 位的特殊计数器。

4、refcount

引用计数,表示这个 robj 目前被多少个地方应用,refcount 的出现为对象复用提供了基础。了解过垃圾回收的同学都知道有种回收策略就是采用计数器的方式,当 refcount 为 0 时,说明该对象已经没用了,就可以被回收掉了,Redis 的作者也实现了这种引用回收的策略。

5、ptr

这个就很简单了,前面几个字段是为 robj 提供 meta 信息,那该字段就是数据具体所在地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值