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. PHP字符串大小写转换函数

    string strtolower(string $str) 将字符串转换为小写 string strtoupper(string $str) 将字符串转换为大写 $str1 = 'html'; $s ...

  2. Java:斐波那契数列

    斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10 ...

  3. css过渡动画

    具体代码:1.水平翻转-moz-transform:scale(-1,1);-webkit-transform:scale(-1,1);-o-transform:scale(-1,1);transfo ...

  4. 836. Rectangle Overlap

    class Solution { public: bool isRectangleOverlap(vector<int>& rec1, vector<int>& ...

  5. k-SLAM:k-mer Sorted List Alignment and Metagenomics

    k-SLAM 是基于大量高通量宏基因组序列数据分析的比对程序,它基于k-mer技术上在reads和序列之间进行比较,然后用Smith-Waterman算法验证.校准是连接在一起组成一个伪组装用来提高特 ...

  6. PHP的设计模式之工厂模式

    以前写代码老觉得,搞那么多乱七八槽的设计模式干嘛啊,这不是自己找罪受嘛.现在在这次的API开发过程中才晓得设计模式的厉害,真的是境界不到,永远不能领悟呀.还好坚持编码这么久,终于进入设计模式的运用了, ...

  7. 2018.11.01 NOIP训练 图论(线段树+倍增+dfs序)

    传送门 一道挺妙的题. 对于询问点(u,v),如右图所示,我们可以发现存在一个点m在u->v的路径中,m子树的点到u是最近的,m子树外到v是最近的.其中dis(u,m)=(dis(u,v)-1) ...

  8. 百度地图经纬度和地址互转(Java代码)

    这是基于springmvc+mybatis 的一个controller.如果不是这个框架,可以把方法实体抽到自己写的一个类中,然后再测试 package com.uwitec.controller.s ...

  9. 设置vue启动项目后默认显示的页面

    通过配置路由,可以设置vue项目启动后默认显示的页面.路由的path设置为path:"/",启动项目后就会显示默认的组件页面. import Vue from 'vue' impo ...

  10. 证明2x2正交矩阵专置后还是正交矩阵

    [ x1  x2 y1   y2] x1^2+y1^2=1 x2^2 + y2^2=1 x1*x2  + y1*y2=0 如果专置后还是 x1^2 + x2^2=1 y1^2  +y2^2=1 x1* ...