redis数据结构之压缩列表


Posted in Redis onMarch 21, 2022
目录

压缩列表是列表键和哈希键的底层实现之一。当一个列表键只包含少量列表项,并且每个列表项要么就是小整数,要么就是长度比较短的字符串,redis就会使用压缩列表来做列表键的底层实现

当一个哈希键只包含少量键值对,并且每个键值对的键和值要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做哈希键的底层实现。

压缩列表是Redis为了节约内存而开发的是由一系列特殊编码的连续内存块组成的顺序型数据结构,一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值

ziplist 数据结构:压缩列表各个组成部分

redis数据结构之压缩列表

压缩列表各个组成部分详细说明:

redis数据结构之压缩列表

压缩列表节点的构成:

每个压缩列表节点可以保存一个字节数组或者一个整数值,其中字节数组可以是以下三种长度的其中一种

长度小于等于63字节的字节数组

长度小于等于16383字节的字节数组

长度小于等于4294967295字节的字节数组

数值则可以是以下六种长度的其中一种:

  • 1:  4位长介于0至12之间的无符号整数
  • 2:1字节长的有符号整数
  • 3: 3字节长的有符号整数
  • 4:int16类型整数
  • 5:int32类型整数
  • 6 : int64类型整数

压缩列表的数据结构:

redis数据结构之压缩列表

压缩列表是redis为了节约内存而开发的,由一系列特殊编码的连续内存块组成的顺序型数据结构。一个压缩列表可以包含任意多个节点,每个节点保存一个字节数组或者一个整数值。

创建一个空的ziplist:

/*
 * 新创建一个空 ziplist
 * 
 * 复杂度:O(1)
 *
 * 返回值:新创建的 ziplist
 */
unsigned char *ziplistNew(void) {
    // 分配 2 个 32 bit,一个 16 bit,以及一个 8 bit
    // 分别用于 <zlbytes><zltail><zllen> 和 <zlend>
    unsigned int bytes = ZIPLIST_HEADER_SIZE+1;
    unsigned char *zl = zmalloc(bytes);

    // 设置长度
    ZIPLIST_BYTES(zl) = intrev32ifbe(bytes);

    // 设置表尾偏移量
    ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(ZIPLIST_HEADER_SIZE);

    // 设置列表项数量
    ZIPLIST_LENGTH(zl) = 0;

    // 设置表尾标识
    zl[bytes-1] = ZIP_END;

    return zl;
}

压缩列表包含任意多个压缩列表节点,每个节点可以保存一个字节数组或者一个整数值。

压缩列表组成部分:

  • zlbytes:记录整个压缩列表占用的内存字节数
  • zltail:记录压缩列表表尾节点距离压缩列表的起始地址的字节数
  • entryX:列表节点
  • zlend:用于标记压缩列表的末端

压缩列表节点的构成:

  • preivous_entry_length:记录压缩列表中前一个节点的长度
  • encoding:记录节点content属性保存数据的类型以及长度
  • content:负责保存节点的值,值的类型和长度由节点的encoding属性决定。

当我们知道一个指向某个节点起始地址的指针,那么通过这个指针以及这个节点的preivous_entry_length属性,我们可以一直向前一个节点回溯,最终到达压缩列表的表头节点。

连锁更新:

每个节点的preivous_entry_length属性记录前一个节点的长度

如果前一个节点长度小于254字节,preivous_entry_length属性需要用1字节长的空间来保存这个长度值

如果前一个节点长度大于等于254字节,preivous_entry_length属性需要用5字节长的空间来保存这个长度值

如果前一个节点长度变大,这个节点的preivous_entry_length就要扩展,这个节点的扩展引起下一个节点的扩展,这就是连锁更新

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

在添加新节点和删除节点都可能引发连锁更新。

连锁更新最坏情况下需要对压缩列表进行N次空间重分配操作,每次空间重分配的最坏复杂度为O(N),所以连锁更新的最坏复杂度为O(N的平方),平均复杂度为O(N)

总结:

压缩列表是为了节约内存而开发的顺序型数据结构,它是列表键和哈希键的底层实现之一,压缩列表可以包含多个节点,每个节点可以保存一个字节数组或整数值,添加新节点或删除节点可能引发连锁更新操作,这种操作出现几率不高。

到此这篇关于redis数据结构之压缩列表 的文章就介绍到这了,更多相关redis压缩列表 内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Redis 相关文章推荐
redis连接被拒绝的解决方案
Apr 12 Redis
解析Redis Cluster原理
Jun 21 Redis
redis 存储对象的方法对比分析
Aug 02 Redis
Redis读写分离搭建的完整步骤
Sep 14 Redis
Redis+Lua脚本实现计数器接口防刷功能(升级版)
Feb 12 Redis
高并发下Redis如何保持数据一致性(避免读后写)
Mar 18 Redis
Redis超详细讲解高可用主从复制基础与哨兵模式方案
Apr 07 Redis
详解Redis的三种常用的缓存读写策略步骤
May 06 Redis
Redis基本数据类型Zset有序集合常用操作
Jun 01 Redis
使用Redis实现分布式锁的方法
Jun 16 Redis
浅谈Redis变慢的原因及排查方法
Jun 21 Redis
Redis高可用集群redis-cluster详解
使用Redis实现点赞取消点赞的详细代码
Mar 20 #Redis
Redis集群节点通信过程/原理流程分析
redis数据一致性的实现示例
高并发下Redis如何保持数据一致性(避免读后写)
Mar 18 #Redis
redis击穿 雪崩 穿透超详细解决方案梳理
Redis调用Lua脚本及使用场景快速掌握
You might like
浅谈PHP强制类型转换,慎用!
2013/06/06 PHP
深入理解PHP中的Session和Cookie
2013/06/21 PHP
深入理解PHP 数组之count 函数
2016/06/13 PHP
来自国外的页面JavaScript文件优化
2010/12/08 Javascript
Jquery中Ajax 缓存带来的影响的解决方法
2011/05/19 Javascript
extjs3 combobox取value和text案例详解
2013/02/06 Javascript
jquery 提交值不为空的元素示例代码
2013/05/10 Javascript
javascript自定义startWith()和endWith()的两种方法
2013/11/11 Javascript
jquery简单实现滚动条下拉DIV固定在头部不动
2013/11/25 Javascript
jquery1.10给新增元素绑定事件的方法
2014/03/06 Javascript
当某个文本框成为焦点时即清除文本框内容
2014/04/28 Javascript
jquery列表拖动排列(由项目提取相当好用)
2014/06/17 Javascript
微信浏览器内置JavaScript对象WeixinJSBridge使用实例
2015/05/25 Javascript
js html css实现复选框全选与反选
2016/10/09 Javascript
jQuery编写textarea输入字数限制代码
2017/03/23 jQuery
Node.js命令行/批处理中如何更改Linux用户密码浅析
2018/07/22 Javascript
VUE Elemen-ui之穿梭框使用方法详解
2021/01/19 Javascript
JS禁用右键、禁用Ctrl+u、禁用Ctrl+s、禁用F12的实现代码
2020/12/01 Javascript
python局部赋值的规则
2013/03/07 Python
Python实现115网盘自动下载的方法
2014/09/30 Python
python daemon守护进程实现
2016/08/27 Python
Python匿名函数及应用示例
2019/04/09 Python
pytorch实现用CNN和LSTM对文本进行分类方式
2020/01/08 Python
Python通过4种方式实现进程数据通信
2020/03/12 Python
HTML5 3D衣服摇摆动画特效
2016/03/17 HTML / CSS
英国最大的美妆产品在线零售商之一:Beauty Bay
2017/09/29 全球购物
Theo + George官方网站:都柏林时尚品牌
2019/04/08 全球购物
Nordgreen手表德国官方网站:丹麦极简主义手表
2019/10/31 全球购物
英国经济型酒店品牌:Travelodge
2019/12/17 全球购物
八年级物理教学反思
2014/01/19 职场文书
认购协议书范本
2014/04/22 职场文书
1亿有多大教学反思
2014/05/01 职场文书
村长反四风问题个人对照检查材料
2014/09/21 职场文书
党的群众路线对照检查材料范文
2014/09/24 职场文书
写作之关于描写老人的好段摘抄
2019/11/14 职场文书
Python requests用法和django后台处理详解
2022/03/19 Python