Redis 对象

2022-09-28  本文已影响0人  wayyyy

前面已经介绍了 SDS,双端链表,字典,整数集合,压缩列表等数据结构,但是Redis 并没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构,创建了一个对象系统:

redis 使用这些对象来表示数据库中的键和值。

typedef struct redisObject {
    unsigned type;
    unsigned encoding;
    void* ptr;  
    int refcount;    //  引用计数
}
object.png

类型

对于redis保存的键值对来说:

对象的type属性记录了对象的类型。

redis > SET msg "hello world"
OK
redis > TYPE msg
string

编码

对象的ptr指针指向对象的底层实现数据结构,而这些数据结构由对象的encoding属性决定。
使用OBJECT ENCODING命令可以查看一个数据库键的值对象的编码

redis> SET msg "hello world"
OK
redis> OBJECT ENCODING msg
"emstr"
type encoding 对象
REDIS_STRING REDIS_ENCODING_INT 使用整数值实现的字符串对象
REDIS_STRING REDIS_ENCODING_EMBSTR 使用embstr编码的简单动态字符串实现的字符串对象
REDIS_STRING REDIS_ENCODING_RAW 使用简单动态字符串实现的字符串对象
REDIS_LIST REDIS_ENCODING_ZIPLIST 使用压缩列表实现的列表对象
REDIS_LIST REDIS_ENCODING_LINKEDLIST 使用双端链表实现的列表对象
REDIS_HASH

类型检查与命令多态

Redis 中用于操作键的命令基本上可以分为2类:

类型检查

类型特定命令进行的类型检查是通过来实现,在执行一个类型特定命令之前,服务器会先检查输入数据库键的值对象是否为执行命令所需的类型。

多态命令

Redis 除了根据值对象的类型来判断键是否能够执行指定的命令之外,还会根据值对象的编码方式,选择正确的命令实现代码来执行命令。

比如列表对象有ziplistlinkedlist2种编码可以使用,比如现在可以对一个键执行LLEN命令,

完整实现过程如图:

LLEN key.png

内存回收

C语言并不具备内存自动回收功能,所以Redis在自己的对象系统中构建了一个引用计数实现的内存回收机制。

typedef struct redisObject {
    // ...
    int refcount;    //  引用计数
} robj;

对象空转时长

typedef struct redisObject {
    // ...
    unsigned lru:22;    //  引用计数
} robj;

lru记录了对象最后一次被命令程序访问的时间。使用OBJECT IDLETIME可以打印出给定键的空转时长,这一空转时长就是通过当前时间 - lru时间。

redis > SET msg "hello world"
OK

# 等待一段时间
redis> OBJECT IDLETIME msg
(integer) 20

# 访问

# redis> OBJECT IDLETIME msg
(integer) 0

键的空转时就是:

上一篇下一篇

猜你喜欢

热点阅读