1.概述

  压缩列表是一块连续的内存空间,元素之间紧挨着存储,没有任何冗余空间。

  Redis 为了节约内存空间使用,zset 和 hash 容器对象在元素个数较少的时候,采用压缩列表 (ziplist) 进行存储。3.2.0版本之前, 当 List 容器对象在元素个数较少的时候,也采用压缩列表 (ziplist) 进行存储, 3.2.0之后 List 全部使用 quickList(快速列表).

2. zipList 基本结构

struct ziplist<T> {
int32 zlbytes; // 4 byte, 记录整个压缩列表占用内存字节数,在内存分配或者计算 zlend 的位置时使用
int32 zltail_offset; // 4 byte, 最后一个元素距离压缩列表起始位置的偏移量,用于快速定位到最后一个节点
int16 zllength; // 2 byte, 元素个数当属性值 < 65535 时, 属性值表示节点个数, 当属性值 = 65535 时, 真实节点个数需要遍历压缩列表才能计算得出
T[] entries; // 元素节点列表,节点之间挨个紧凑存储,无冗余空间
int8 zlend; // 1 byte,标志压缩列表的结束,值恒为 0xFF
}

压缩列表为了支持双向遍历,所以才会有 ztail_offset 这个字段,用来快速定位到最后一个元素,然后倒着遍历。

3. entry 基本结构

  每个压缩列表的节点可以保存一个字节数组或者一个整数值.

struct entry {
int<var> prevlen; // 前一个 entry 的字节长度, 前一个节点长度小于254字节,则该属性用一个字节表示, 否则(大于等于254字节)用五个字节表示,第一个字节被设置为0xFE(254), 后四个字节表示前一个节点长度
int<var> encoding; // 记录了节点的 content 属性所保存的数据的类型及长度. 当属性长度为 1 2 5 字节,值最高位为 00 01 10 时表示为字节数组, 数组长度有编码去除最高2位之后的其他位记录, 当属性长度为 1 字节长, 最高位以 11 开头表示是整数编码,整数的类型和长度有编码去除最高2位的其他位表示
optional byte[] content; // 保存节点的值, 可以是一个字节数组或者整数.
}

4. 连锁更新

    当压缩列表有多个连续的且长度介于250字节到253字节的节点,连锁更新才可能被触发.实际中这种情况并不多见.

  其次, zipList 本来就是元素较少的情况下使用的数据结构, 所有更新节点的数量也并不会太多, 对性能造成的影响并不大.

  prevlen 属性的字节长度引起的连锁更新

    有N个节点的长度都是介于250字节到254字节之间, 当增加了一个新的节点 ,该节点的 prevlen 属性值字节长度为五个字节,则下一个节点的 prevlen  属性则变为五个字节, 其总体长度也介于254字节到257字节之间,下下一个节点也发生同样的变化.之后后续节点都要进行更新操作.

5. 内存分配

  因为 ziplist 都是紧凑存储,没有冗余空间 (对比一下 Redis 的字符串结构)。节点的增删都会影响其结构

  插入一个新的元素就需要调用 realloc 扩展内存。取决于内存分配器算法和当前的 ziplist 内存大小,realloc 可能会重新分配新的内存空间,并将之前的内容一次性拷贝到新的地址,也可能在原有的地址上进行扩展,这时就不需要进行旧内容的内存拷贝.

  当删除一个元素后, 后面的节点则要向前移动

Redis---ZipList(压缩列表)的更多相关文章

  1. Redis学习之ziplist压缩列表源码分析

    一.压缩列表ziplist在redis中的应用 1.做列表键 当一个列表键只包含少量列表项,并且每个列表项要么是小整数,要么是短字符串,那么redis会使用压缩列表作为列表键的底层实现 2.哈希键 当 ...

  2. Redis 源码简洁剖析 05 - ziplist 压缩列表

    ziplist 是什么 Redis 哪些数据结构使用了 ziplist? ziplist 特点 优点 缺点 ziplist 数据结构 ziplist 节点 pre_entry_length encod ...

  3. 【Redis】ziplist压缩列表

    压缩列表 压缩列表是列表和哈希表的底层实现之一: 如果一个列表只有少量数据,并且数据类型是整数或者比较短的字符串,redis底层就会使用压缩列表实现. 如果一个哈希表只有少量键值对,并且每个键值对的键 ...

  4. Redis源代码分析(六)--- ziplist压缩列表

    ziplist和之前我解析过的adlist列表名字看上去的非常像.可是作用却全然不同.之前的adlist主要针对的是普通的数据链表操作. 而今天的ziplist指的是压缩链表.为什么叫压缩链表呢.由于 ...

  5. redis 5.0.7 源码阅读——压缩列表ziplist

    redis中压缩列表ziplist相关的文件为:ziplist.h与ziplist.c 压缩列表是redis专门开发出来为了节约内存的内存编码数据结构.源码中关于压缩列表介绍的注释也写得比较详细. 一 ...

  6. Redis压缩列表原理与应用分析

    摘要 Redis是一款著名的key-value内存数据库软件,同时也是一款卓越的数据结构服务软件.它支持字符串.列表.哈希表.集合.有序集合五种数据结构类型,同时每种数据结构类型针对不同的应用场景又支 ...

  7. Redis底层探秘(四):整数集合及压缩列表

    整数集合 整数集合(intset)是集合键的底层实现之一,当一个集合只包含 整数值元素,并且这个集合的元素数量不多时,Redis就会使用郑书记和作为集合键的底层实现. 整数集合的实现 整数集合是red ...

  8. Redis 的底层数据结构(压缩列表)

    上一篇我们介绍了 redis 中的整数集合这种数据结构的实现,也谈到了,引入这种数据结构的一个很大的原因就是,在某些仅有少量整数元素的集合场景,通过整数集合既可以达到字典的效率,也能使用远少于字典的内 ...

  9. redis源码之压缩列表ziplist

    压缩列表ziplist1.简介连续,无序的数据结构.压缩列表是 Redis 为了节约内存而开发的, 由一系列特殊编码的连续内存块组成的顺序型(sequential)数据结构. 2.组成 属性 类型 长 ...

  10. redis 底层数据结构 压缩列表 ziplist

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

随机推荐

  1. Web中的四大作用域对象

    request:请求对象 类型:HttpServletRequest session:表示一次会话,可以处理一个用户多个页面之间的请求 application:标识web应用上下文,类型:Servle ...

  2. centos下利用yum安装LAMP(Linux+Apache+MySQL+PHP)及配置

    先说下我的实践配置,centos6.5(64位),联网 安装前准备:关闭防火墙 service iptables stop 安装MySQL 打开终端,root用户 1 yum install mysq ...

  3. 2018.11.14 uoj#34. 多项式乘法(ntt)

    传送门 今天学习nttnttntt. 其实递归方法和fftfftfft是完全相同的. 只不过fftfftfft的单位根用的是复数中的东西,而nttnttntt用的是数论里面有相同性质的原根. 代码: ...

  4. MYSQL 事务测试

    mysql 事务测试 创建张表 lock1 增加字段 id,name . 增加两条记录 1,a 2,b 启动第一个会话 BEGIN; update lock1 set name='c' where i ...

  5. java Concurrent包学习笔记(五):Semaphore

    一.Semaphore 是什么  信号量Semaphore是一个并发工具类,用来控制可同时并发的线程数,其内部维护了一组虚拟许可,构造函数初始化的时候可以指定许可的总数量 每次线程执行操作时先通过ac ...

  6. 图解TCP/IP(一)

    IP(Internet Protocol) IP/ICMP -数据链路层的主要作用是在互连同一种数据链路的节点之间进行包传递.而一旦跨越多种数据链路,就需要借助网络层. -配备IP的设备,但是不进行路 ...

  7. linux source命令的用法

    source命令用法:source FileName作用:在当前bash环境下读取并执行FileName中的命令.(如把ls写入a.txt,然后source a.txt 就会执行ls命令,列出目录)注 ...

  8. js 上传文件

    <input id="file_Up" name="file_Up" type="file" onchange="getFi ...

  9. 使用Expression tree访问类的属性名称与值

    表达式树Expression是Linq中一项比较重要的功能,对其深刻了解Lamda以及计算表达式有很大的帮助. 下面是利用 Expression<Func<Object>>[] ...

  10. java中的标识符、关键字、保留字

    Java中关键字(keyword)和保留字(reservedword) Keyword :Java的关键字对java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等. Reserv ...