Redis对象
概述
在前面的一系列文章中介绍了关于redis中主要数据结构,包括简单动态字符串SDS,链表,字典,整数集合,压缩列表等等
Redis并没有直接使用这些数据结构来实现其数据库,而是基于这些数据结构创建了一个对象系统
在redis的对象系统中,有五种类型的对象,分别为
-
字符串对象
-
列表对象
-
哈希对象
-
集合对象
-
有序集合对象
使用对象系统的好处
- 校验命令是否可执行
redis可以在执行命令前根据对象的类型来判断该对象是否可以执行给定的命令
- 优化对象在不同场景下的使用效率
可以针对不同的使用场景来为对象设置多种不同的数据结构实现
-
基于对象系统实现基于引用计数计数的内存回收系统
-
对象被设计为带有访问时间记录信息,用于计算数据库键的空转时长等
对象系统
redis使用对象来表示数据库中的键和值,每当我们向数据库新建一个键值对时,redis就会创建至少两个对象,一个对象用作键对象,一个用作值对象
举个栗子:SET msg "Hello World"
redis会在数据库中创建一个包含字符串值"msg"的键对象,和一个包含字符串值"Hello World"的值对象
结构定义
typedef struct redisObject {
// 类型
unsigned type:4;
// 编码
unsigned encoding:4;
// 指向底层实现数据结构的指针
void *ptr;
// ...
}
其中type属性就表示对象的类型,即上面的五种类型
encoding属性记录了对象所使用的编码(即使用的是何种的数据结构作为对象的底层实现的)
ptr指针指向对象的底层实现数据结构,而底层采用何种数据结构是由encoding属性决定的
不同类型对象/编码/一览表
对象 | type属性常量 | TYPE命令输出值 | 编码属性常量 | OBJECT ENCODING 命令输出值 | ptr底层数据结构 |
---|---|---|---|---|---|
字符串 | REDIS_STRING | "string" | REDIS_ENCODING_INT | "int" | 整数值 |
字符串 | REDIS_STRING | "string" | REDIS_ENCODING_EMBSTR | "embstr" | embstr 编码的简单动态字符串SDS |
字符串 | REDIS_STRING | "string" | REDIS_ENCODING_RAW | "raw" | 简单动态字符串SDS |
列表 | REDIS_LIST | "list" | REDIS_ENCODING_ZIPLIST | "ziplist" | 压缩列表 |
列表 | REDIS_LIST | "list" | REDIS_ENCODING_ LINKEDLIST | "linkedlist" | 双端链表 |
哈希 | REDIS_HASH | "hash" | REDIS_ENCODING_ZIPLIST | "ziplist" | 使用压缩列表实现的哈希对象 |
哈希 | REDIS_HASH | "hash" | REDIS_ENCODING_ HT | "hashtable" | 使用字典实现的哈希对象 |
集合 | REDIS_SET | "set" | REDIS_ENCODING_INTSET | "intset" | 使用整数集合实现的集合对象 |
集合 | REDIS_SET | "set" | REDIS_ENCODING_HT | "hashtable" | 使用字典实现的集合对象 |
有序集合 | REDIS_ZSET | "zset" | REDIS_ENCODING_ZIPLIST | "ziplist" | 使用压缩列表实现的有序集合对象 |
有序集合 | REDIS_ZSET | "zset" | REDIS_ENCODING_SKIPLIST | "skiplist" | 使用调表和字典实现的有序集合对象 |
redis根据对象使用场景的不同,通过encoding属性来设定对象所使用的具体编码类型,而不是为特定类型的对象关联一种固定的编码,极大的提升了redis的灵活性和效率
举个栗子:
当列表对象中包含的元素较少时,redis会使用压缩列表作为列表对象的底层实现
-
由于压缩列表在内存中是一个连续块的方式保存的元素,会比双端链表这样的分离式存储更容易被载入到缓存中
-
当元素越来越多时,列表对象就会使用双端链表,因为其功能更强,更适合保存大量元素
总结
-
redis采用的对象系统是基于各种数据结构抽象出来的,其对象中有一个属性encoding记录了该对象底层所使用的数据结构的类型
-
redis对象的type属性标识对象属于五种对象类型的哪一种
-
redis对象的ptr属性指向了底层实现的数据结构
-
基于对象的概念redis可以作很多诸如命令校验,对象空转时长等等校验
-
针对对象使用的场景不同,redis可以针对不同场景选择不同的数据结构实现,提高灵活性的同时亦可以提高对象使用效率
后续文章会分析Redis中的五种对象的具体实现