您现在的位置是:亿华云 > 系统运维
原来Redis的五种数据类型数底层结构是这样的
亿华云2025-10-03 13:42:17【系统运维】3人已围观
简介在Redis中会涉及很多数据结构,比如SDS,双向链表、字典、压缩列表、整数集合等等。Redis会基于这些数据结构自定义一个对象系统,而且自定义的对象系统有很多好处。通过对以下的Redis对象系统的学
在Redis中会涉及很多数据结构,数据数底比如SDS,类型双向链表、层结字典、构样压缩列表、数据数底整数集合等等。类型Redis会基于这些数据结构自定义一个对象系统,层结而且自定义的构样对象系统有很多好处。
通过对以下的数据数底Redis对象系统的学习,可以了解Redis设计原理以及初衷,类型为了我们在使用Redis的层结时候,更加能够理解到其原理和定位问题。构样
Redis 对象
Redis基于上述的数据数底数据结构自定义一个Object 系统,Object结构:
redisObject结构: typedef struct redisObject{ //类型 unsigned type:4; //编码 unsigned encoding:4; //指向底层实现数据结构的类型指针 void *ptr; ….. }Object 系统包含五种Object:
String:字符串对象 List:列表对象 Hash:哈希对象 Set:集合对象 ZSet:有序集合Redis使用对象来表示数据库中的键和值,即每新建一个键值对,层结至少创建有两个对象,而且使用对象的具有以下好处:
1. redis可以在执行命令前会根据对象的类型判断一个对象是否可以执行给定的命令
2. 针对不同的使用场景,为对象设置不同的数据结构实现,从而优化对象的不同场景夏的使用效率
3. 对象系统还可以基于引用计数计数的高防服务器内存回收机制,自动释放对象所占用的内存,或者还可以让多个数据库键共享同一个对象来节约内存。
4. redis对象带有访问时间记录信息,使用该信息可以进行优化空转时长较大的key,进行删除!
对象的ptr指针指向对象的底层现实数据结构,而这些数据结构由对象的encoding属性决定,对应关系:
每种Object对象至少有两种不同的编码,对应关系:
String对象
字符串对象编码可以int 、raw或者embstr,如果保存的值为整数值且这个值可以用long类型表示,使用int编码,其他编码类似。
比如:int编码的String Object
redis> set number 520 ok redis> OBJECT ENCODING number "int"String Object结构:
String 对象之间的编码转换
int编码的字符串对象和embstr编码的字符串对象在条件满足的情况下,会被转换为raw编码的字符串对象。
比如:对int编码的字符串对象进行append命令时,就会使得原来是int变为raw编码字符串
List对象
list对象可以为ziplist或者为linkedlist,对应底层实现ziplist为压缩列表,云服务器提供商linkedlist为双向列表。
Redis>RPUSH numbers “Ccww” 520 1用ziplist编码的List对象结构:
用linkedlist编码的List对象结构:
List对象的编码转换:
当list对象可以同时满足以下两个条件时,list对象使用的是ziplist编码:
1. list对象保存的所有字符串元素的长度都小于64字节
2. list对象保存的元素数量小于512个,
不能满足这两个条件的list对象需要使用linkedlist编码。
Hash对象
Hash对象的编码可以是ziplist或者hashtable
其中,ziplist底层使用压缩列表实现:
保存同一键值对的两个节点紧靠相邻,键key在前,值vaule在后 先保存的键值对在压缩列表的表头方向,后来在表尾方向hashtable底层使用字典实现,Hash对象种的每个键值对都使用一个字典键值对保存:
字典的键为字符串对象,保存键key 字典的值也为字符串对象,保存键值对的值比如:HSET命令
redis>HSET author name "Ccww" (integer) redis>HSET author age 18 (integer) redis>HSET author sex "male" (integer)ziplist的底层结构:
hashtable底层结构:
Hash对象的编码转换:
当list对象可以同时满足以下两个条件时,list对象使用的亿华云计算是ziplist编码:
1. list对象保存的所有字符串元素的长度都小于64字节
2. list对象保存的元素数量小于512个,
不能满足这两个条件的hash对象需要使用hashtable编码
Note:这两个条件的上限值是可以修改的,可查看配置文件hash-max-zaiplist-value和hash-max-ziplist-entries
Set对象:
Set对象的编码可以为intset或者hashtable
intset编码:使用整数集合作为底层实现,set对象包含的所有元素都被保存在intset整数集合里面 hashtable编码:使用字典作为底层实现,字典键key包含一个set元素,而字典的值则都为nullinset编码Set对象结构:
redis> SAD number 1 3 5hashtable编码Set对象结构:
redis> SAD Dfruits “apple” "banana" " cherry"Set对象的编码转换:
使用intset编码:
1. set对象保存的所有元素都是整数值
2. set对象保存的元素数量不超过512个
不能满足这两个条件的Set对象使用hashtable编码
ZSet对象
ZSet对象的编码 可以为ziplist或者skiplist
ziplist编码,每个集合元素使用相邻的两个压缩列表节点保存,一个保存元素成员,一个保存元素的分值,然后根据分数进行从小到大排序。
ziplist编码的ZSet对象结构:
Redis>ZADD price 8.5 apple 5.0 banana 6.0 cherryskiplist编码的ZSet对象使用了zset结构,包含一个字典和一个跳跃表
Type struct zset{ Zskiplist *zsl; dict *dict; ... }skiplist编码的ZSet对象结构
ZSet对象的编码转换
当ZSet对象同时满足以下两个条件时,对象使用ziplist编码
1. 有序集合保存的元素数量小于128个
2. 有序集合保存的所有元素的长度都小于64字节
不能满足以上两个条件的有序集合对象将使用skiplist编码。
Note:可以通过配置文件中zset-max-ziplist-entries和zset-max-ziplist-vaule
很赞哦!(21)
上一篇: 如何将gRPC与Guice相结合
下一篇: 数据架构中的数据问题