Redis底层数据结构解析

String 数据结构详解

String 底层数据类型

  • int:如果value可以转换成一个long类型的数字,那么就用int保存value。只有整数才会使用int,如果是浮点数,Redis内部其实是先将浮点数转化成字符串,然后保存。
  • 数字长度超过 20 不会用 int 类型保存
  • 数字值小于 1000 时,直接指向内存,类似 java 的 Integer,值为 -128~127 时,从缓存读取。
  • embstr:如果value是一个字符串类型,并且长度小于44字节的字符串,那么Redis就会用embstr保存。代表embstr的底层数据结构是SDS(Simple Dynamic String 简单动态字符串)

将 redis 对象和SDS 数据结构一次性分配在连续的内存当中。SDS 数据结构放在 redisobject 对象后面。
优点: 快速创建销毁,数据布局好,访问更快。

  • raw:如果value是一个字符串类型,并且长度大于44字节,就会用raw保存。

Hash 数据结构详解

Hash 底层数据类型

根据 hash-max-listpack-entries 和 hash-max-listpack-value 这两个配置参数结合保存的键值对决定使用哪种数据类型。

如果键值对个数小于 hash-max-listpack-entries 值或者所有键值对的字符串总长度小于 hash-max-listpack-value 的值,就使用 listpack。

否则使用 hashtable。数据量增大的时候可由 listpack 升级为 hashtable,但是 hashtable 不能降级为 listpack。

  • hash-max-listpack-entries:限制 value 里键值对的个数,默认 512。
  • hash-max-listpack-value:限制 value 里所有字符串的长度,默认 64M。

listpack 和 ziplist

redis6 以前都是用 ziplist,redis7 开始都用了 listpack。

ziplist
是一种内存紧凑型的数据结构,占用连续的一块内存空间,整个数据结构类似于数组,两端都可以 push 和 pop,时间复杂度都是 O(1)。

ziplist 的节点的结构如下

  • prevlen:前一个节点的长度,为了支持反向遍历。

如果前面节点的长度在 1~254 之间,prevlen 长度为 1 字节;如果前面节点长度超过 254 字节,prevlen 长度为 5 字节。

  • encoding:编码类型
  • content:数据

ziplist 缺点
可能发生连锁更新问题。

当每个节点的长度都在 250~253,这时向头节点插入一个长度超过 253 的 entry,那么前头节点的 prevlen 需要从 1 字节扩充到 5 字节,前头节点扩充之后整体长度超过了 253,它的后一个节点的 prevlen 也需要扩充,以此类推,所有的节点都需要重新调整空间。

这种特殊情况下产生的连续多次空间扩展操作,称为连锁更新。

在这里插入图片描述
listpack

listpack 和 ziplist 的主要区别是 listpack 解决了连锁更新的问题。listpack 的整体结构和 ziplist 差不多, 通过使 prevlen 存储的自己的长度的方式解决的。

List 数据结构详解

List 底层数据类型

  • listpack:数据量少的时候用 listpack。通过参数 list-max-listpack-size 判定数据量的多少。

list-max-listpack-size : 值为正数的时候表示超过多少节点个数算大数据量;值为负数的时候根据节点大小来判断,推荐 -1(4kb) 或 -2(8kb)。

  • quicklist:数据量多的时候用 listpack。

listpack 底层类似数组结构,查询数据快,更新数据慢,链表结构更新数据快,查询数据慢,单独使用哪一种都有效率问题,qiuklist 集两种结构精华,使用链表加数组的方式存储。

整体是一个链表结构,不过每个链表节点存储内容指针指向的是具体保存数据的 listpack 结构。

Set 数据结构详解

Set 底层数据类型

  • intset:如果 value 是都不超过 64 位的数字,使用 intset。
  • listpack
  • hashtable

这两个参数决定使用 listpack 还是 hashtable,和 hash 数据类型的规则一样。
set-max-listpack-entries: 默认 128
set-max-listpack-value :默认 64M

ZSet 数据结构详解

ZSet 底层数据类型

  • listpack
  • skiplist(跳表):使用空间换时间的解决方案,适合数据量大,读多写少的场景。

zset-max-listpack-entries: 默认 128
zset-max-listpack-value: 默认 64

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值