Redis底层数据结构

 摘自为了拿捏 Redis 数据结构,我画了 40 张图(完整版)_redis中的平面-CSDN博客

String的底层是(简单动态字符串SDS)

List的底层是(quicklist(双向链表,压缩列表))

Hash的底层是(listpack,哈希表)

Set的底层是(哈希表,整数集合)

ZSet底层(listpack,跳表)

哈希桶存放的是指向键值对数据的指针(dictEntry*),这样通过指针就能找到键值对数据.

SDS

内容

len:字符串长度,获取字符串长度时间复杂度为O(1)

alloc:分配的空间长度,修改字符串时,通过alloc-len计算剩余空间大小,进而判断剩余空间是否满足,如果不满足,则会自动扩展,无需手动分配也不会出现缓冲区溢出问题

flags:sds类型,表示不同类型的sds,保存不同大小的字符串,节省空间。同时设计__attribute__ ((packed))属性,按照实际字节对齐,节省内存

buf []:字节数据,保存实际数据,不仅可以保存字符串还可以保存二进制数据

优点:高效长度计算,高效修改,二进制安全,节省内存

双向链表

在ListNode基础上再次封装list数据结构

结构:

head:头指针

tail:尾指针,指向最后一个node,因此获取第一个和最后一个node时间复杂度为O(1)

len:节点数量,获取节点数量时间复杂度为O(1)

dup,free,match函数为节点设置类型,因此链表节点可以保存不同类型的值

缺陷:内存不连续,无法很好利用cpu缓存;链表结构内存开销大

压缩列表ziplist

内存紧凑,占用一整块内存空间,可以利用cpu缓存

结构

表头 + entry + 表尾zlend

zlbytes:记录整个压缩链表内存大小;zltail:列表尾偏移量,尾部节点距起始地址字节;zllen:节点数量;zlend,结尾点,0xFF(255)

entry:prevlen:前一个节点长度,如果前一个节点长度小于254字节,那么prevlen属性占用1个字节,否则占用5个字节

encoding:当前entry数据类型和长度,当前节点数据为整数,则使用1字节;为字符串,则根据大小,使用1/2/5个字节

data:数据

优点:节省内存

缺陷:查找复杂度高;连锁更新,重新分配内存,因此适用于节点不多场景

哈希表 hash

数组+哈希桶

优点:以O(1)时间复杂度查询数据

使用链式哈希解决哈希冲突

rehash

Redis定义俩个哈希表

步骤:1.先将数据写入哈希表1,哈希表2此时为分配空间

2.触发rehash时,给哈希表2分配空间,一般是哈希表的两倍

3.将哈希表1数据迁入哈希表2

4.迁移完成,哈希表1空间释放,将哈希表2设置为哈希表1,哈希表1设置为哈希表2

缺陷:如果哈希表1数据量比较大,迁移数据时间长,阻塞Redis

改进:使用渐进式rehash,分多次迁移

触发条件

负载因子 (已保存节点数量/哈希表大小),当负载因子>=1,并且Redis没有执行RDB快照或AOF时;当负载因子>=5时,不论有没有执行RDB和AOF重写,都会rehash

整数集合 inset

结构

encoding:编码方式

length:元素数量

contents:保存元素的数组

整数集合升级:当集合中的元素元素都是同一种类型时,如int16,那么每个元素就占用16个字节,如果新增元素为int32,那么所有元素都会扩展成int32

优点:节省内存

不支持降级

跳表 zskiplist

多层有序链表,比如一个链表1-》2-》3-》4-》5

头节点有3层,L2,L1,L0

L0层5个节点,L0-》1-》2-》3-》4-》5

L1层3个节点,L1-》2-》5

L2层1个节点,L2-》3

查找4这个节点,先通过L2层查找到3,然后遍历到4,只查找两次

quicklist 

(双向链表+压缩列表)

通过控制链表节点中的压缩列表的大小或元素个数,避免连锁更新问题。

quicklist结构

head(链表头),tail(链表尾),count(所有元素个数),len(quicklistNodes个数)

quiclistNode结构

prev(前一个quicklistNode),next(后一个quicklistNode),zl(压缩列表字节大小),sz(压缩列表元素个数),count(ziplist元素个数)

listpack

特点:节点中不包含前一个节点的长度,从而避免连锁更新

listpack 总字节数

listpack 元素数量

listpack entry包含:encoding(元素编码类型),data(实际存放的数据),len(encoding+data的总长度)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值