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. UGUI图集

    Editor->Project Settings 下面有sprite packer的模式.Disabled表示不启用它,Enabled For Builds 表示只有打包的时候才会启用它,Alw ...

  2. Jetty配置

    类似TomCat 登陆官网www.eclipse.org Download下载Jetty zip压缩版 解压到文件夹,打开idea的Config->Jetty-server->Local- ...

  3. 微信小程序组件的使用

    1.在page同级目录下新建components文件夹,然后新建目录test,新建组件test 2.新建在page目录下新建目录,然后新建page页面.注意:每新建一个页面,都要修改app.json文 ...

  4. (4)4 larger-than-life lessons from soap operas

    https://www.ted.com/talks/kate_adams_4_larger_than_life_lessons_from_soap_operas/transcript 00:12In ...

  5. 计算给定多项式在给定点X处的值

    //计算多项式求值 //计算多项式求值#include<iostream>#include<ctime>#include<cmath>using namespace ...

  6. Bagging和Boosting的区别

    转:http://www.cnblogs.com/liuwu265/p/4690486.html Bagging和Boosting都是将已有的分类或回归算法通过一定方式组合起来,形成一个性能更加强大的 ...

  7. 如何通过Openssl实现私有CA,并为HTTP服务提供TLS/SLL安全机制

    原文链接:http://guodayong.blog.51cto.com/263451/1181059 Openssl是SSL的开源实现(可以免费下载应用程序),是一种安全机密程序,主要用于提高远程登 ...

  8. leetcode - [1]Reverse Words in a String

    Question: Reverse Words in a String Given an input string, reverse the string word by word. For exam ...

  9. c 语言申明头文件和实现分开简单例子

    很多时候,看到很多c函数的声明和实现是分开的.声明放在头文件,实现却放在另一个文件,最后函数被其他文件调用. 下面以简单例子说明. 一.声明部分 /* test.h */ #include <s ...

  10. java锁类型

    转载链接在每个锁类型后边 线程锁类型 1.自旋锁 ,自旋,jvm默认是10次吧,有jvm自己控制.for去争取锁 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchroni ...