关注我,能够获取最新知识、经典面试题以及微服务技术分享面试
在Redis中会涉及不少数据结构,好比SDS,双向链表、字典、压缩列表、整数集合等等。Redis会基于这些数据结构自定义一个对象系统,并且自定义的对象系统有不少好处。redis
经过对如下的Redis对象系统的学习,能够了解Redis设计原理以及初衷,为了咱们在使用Redis的时候,更加可以理解到其原理和定位问题。数据库
Redis基于上述的数据结构自定义一个Object 系统,Object结构:数据结构
redisObject结构: typedef struct redisObject{ //类型 unsigned type:4; //编码 unsigned encoding:4; //指向底层实现数据结构的指针 void *ptr; ….. }
Object 系统包含五种Object:app
Redis使用对象来表示数据库中的键和值,即每新建一个键值对,至少建立有两个对象,并且使用对象的具备如下好处:微服务
1. redis能够在执行命令前会根据对象的类型判断一个对象是否能够执行给定的命令 2. 针对不一样的使用场景,为对象设置不一样的数据结构实现,从而优化对象的不一样场景夏的使用效率 3. 对象系统还能够基于引用计数计数的内存回收机制,自动释放对象所占用的内存,或者还可让多个数据库键共享同一个对象来节约内存。 4. redis对象带有访问时间记录信息,使用该信息能够进行优化空转时长较大的key,进行删除!
对象的ptr指针指向对象的底层现实数据结构,而这些数据结构由对象的encoding属性决定,对应关系:学习
编码常量 | 编码对应的底层数据结构 |
---|---|
REDIS_ENCODING_INT | long类型的整数 |
REDIS_ENCODING_EMBSTR | embstr编码的简单动态字符串 |
REDIS_ENCODING_RAW | 简单动态字符串 |
REDIS_ENCODING_HT | 字典 |
REDIS_ENCODING_LINKEDLIST | 双向链表 |
REDIS_ENCODING_ZIPLIST | 压缩列表 |
REDIS_ENCODING_INTSET | 整数集合 |
REDIS_ENCODING_SKIPLIST | 跳跃表和字典 |
每种Object对象至少有两种不一样的编码,对应关系:优化
类型 | 编码 | 对象 |
---|---|---|
String | int | 整数值实现 |
String | embstr | sds实现 <=39 字节 |
String | raw | sds实现 > 39字节 |
List | ziplist | 压缩列表实现 |
List | linkedlist | 双端链表实现 |
Set | intset | 整数集合使用 |
Set | hashtable | 字典实现 |
Hash | ziplist | 压缩列表实现 |
Hash | hashtable | 字典使用 |
Sorted set | ziplist | 压缩列表实现 |
Sorted set | skiplist | 跳跃表和字典 |
字符串对象编码能够int 、raw或者embstr,若是保存的值为整数值且这个值能够用long类型表示,使用int编码,其余编码相似。ui
好比:int编码的String Object编码
redis> set number 520 ok redis> OBJECT ENCODING number "int"
String Object结构:
### String 对象之间的编码转换
int编码的字符串对象和embstr编码的字符串对象在条件知足的状况下,会被转换为raw编码的字符串对象。
好比:对int编码的字符串对象进行append命令时,就会使得原来是int变为raw编码字符串
list对象能够为ziplist或者为linkedlist,对应底层实现ziplist为压缩列表,linkedlist为双向列表。
Redis>RPUSH numbers “Ccww” 520 1
用ziplist编码的List对象结构:
用linkedlist编码的List对象结构:
当list对象能够同时知足如下两个条件时,list对象使用的是ziplist编码:
1. list对象保存的全部字符串元素的长度都小于64字节 2. list对象保存的元素数量小于512个,
不能知足这两个条件的list对象须要使用linkedlist编码。
Hash对象的编码能够是ziplist或者hashtable
其中,ziplist底层使用压缩列表实现:
hashtable底层使用字典实现,Hash对象种的每一个键值对都使用一个字典键值对保存:
好比:HSET命令
redis>HSET author name "Ccww" (integer) redis>HSET author age 18 (integer) redis>HSET author sex "male" (integer)
ziplist的底层结构:
hashtable底层结构:
当list对象能够同时知足如下两个条件时,list对象使用的是ziplist编码:
1. list对象保存的全部字符串元素的长度都小于64字节 2. list对象保存的元素数量小于512个,
不能知足这两个条件的hash对象须要使用hashtable编码
Note:这两个条件的上限值是能够修改的,可查看配置文件hash-max-zaiplist-value和hash-max-ziplist-entries
Set对象的编码能够为intset或者hashtable
inset编码Set对象结构:
redis> SAD number 1 3 5
hashtable编码Set对象结构:
redis> SAD Dfruits “apple” "banana" " cherry"
使用intset编码:
1. set对象保存的全部元素都是整数值 2. set对象保存的元素数量不超过512个
不能知足这两个条件的Set对象使用hashtable编码
ZSet对象的编码 能够为ziplist或者skiplist
ziplist编码,每一个集合元素使用相邻的两个压缩列表节点保存,一个保存元素成员,一个保存元素的分值,而后根据分数进行从小到大排序。
ziplist编码的ZSet对象结构:
Redis>ZADD price 8.5 apple 5.0 banana 6.0 cherry
skiplist编码的ZSet对象使用了zset结构,包含一个字典和一个跳跃表
Type struct zset{ Zskiplist *zsl; dict *dict; ... } skiplist编码的ZSet对象结构
当ZSet对象同时知足如下两个条件时,对象使用ziplist编码
1. 有序集合保存的元素数量小于128个 2. 有序集合保存的全部元素的长度都小于64字节
不能知足以上两个条件的有序集合对象将使用skiplist编码。
Note:能够经过配置文件中zset-max-ziplist-entries和zset-max-ziplist-vaule