【读书笔记】Redis设计与实现(一 数据结构)

TL;DR

数据结构重点难点
跳表跳表/节点 结构体,查找复杂度节点的插入/删除
hashset结构体动态扩缩容,key冲突overflow,动态refresh机制
intset使用场景 ,结构体encoding更新
ziplist使用场景,结构体连锁更新场景复杂度
sdsstring,emstr结构体,扩容/缩容float/int-string转换
object结构体编码转换,类型检查与命令多态,GC与对象共享

跳表(skiplist)

两个结构:
zskiplist: 跳表结构体,记录头尾节点head/tail,长度len,最大层数level。

zskiplist_node: 跳表节点结构体,记录当前节点的层数、上一个节点BW(所以这是一个双向链表),当前节点的score,每一个节点最多有level个指向下一个节点的指针(当然可以比这个量少)在这里插入图片描述
下图每一列都可以认为是一个zskiplist_node,找到73需要21 - 62 - 70 - 73三次即可
在这里插入图片描述

hashset

Go语言的Map和Redis的Set比较
在这里插入图片描述

intset

intset是set的健的底层实现,顾名思义是int的set,包括int编码(int16,int64),长度,实际的int数组在这里插入图片描述
encoding=INTSET_ENC_INT16,length=5时,content占字节 165 = 80 B
encoding=INTSET_ENC_INT64,length=4时,content占字节 64
4 = 256 B
如果往encoding=INTSET_ENC_INT16的intset添加int64,会导致intset的encoding升级INTSET_ENC_INT64,造成content变为4倍;但是删掉这个int64后,encoding不会变回去

ziplist

ziplist是list键/hash键的实现(value是int/短string时),创建之后就是只读不写的结构体了
包括zlbytes 占字节数,zltail 尾节点offset,zllen 节点数,zlend 结尾
连锁更新 O(N^2): 在节点len<254链表头插入节点len>254的节点,造成所有节点的previous_entry_length从1B升级到2B
三个节点的ziplist
encoding=00001011代表string类型,content=“hello world”

字符串SDS

free 可用空间,len 分配空间,buf 实际的char数组,用’\0’结尾
长为11的string类型

对象

主要是type(什么)、encoding(编码方式)、ptr(指向数据结构的指针)
redisstring、list、hash、set、zset 5种对象,同样的对象,在不同的条件下编码方式会不一样,并且在满足特定条件的时候,编码方式会从占地方小的升级到占地方大的。
类型检查和命令多态
DEL, EXPIRE, TYPE,OBJECT 可以对所有key执行
对特定类型的命令
对特定类型的命令也要兼容不同的编码方式,比如LLEN => ziplist.ziplistLen / linkedlist.listLength
GC与对象共享
使用引用计数的GC机制,共享对象不包括字符串对象(只有整数字符串对象共享)
在这里插入图片描述
在这里插入图片描述
编码方式会从占地方小的升级到占地方大的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值