为了节约内存,在zsethash容器对象元素个数较少时,Redis会采用压缩列表(ziplist)进行存储。

压缩列表是一块连续的内存空间,元素之间紧挨着存储,不存在冗余

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

结构

// 压缩列表
struct ziplist<T> {
int32 zlbytes; // 压缩列表占用的内存字节数
int32 zltail_offset; // 记录表尾节点距离起始地址有多少个字节,用于快速定位最后一个元素
int16 zllength; // 压缩列表包含的节点数
T[] entries; // 压缩列表包含的所有节点
int8 zlend; // 特殊值0xFF,标记压缩列表结尾
} ziplist;

  

// 列表节点
struct entry {
int<val> prevlen; // 前一个entry节点的长度
int<val> encoding; // 节点的content属性保存的数据的类型
optional byte[] content; // 节点的值
} entry;

  

prevlen字段长度是1个字节或5个字节:

  • 前一个节点长度小于254:使用1个字节

  • 前一个节点长度大于等于254:使用5个字节

增加元素

由于ziplist是紧凑存储的,没有冗余空间,所以每一次插入新的元素都需要调用realloc扩展内存。取决于内存分配算法和当前ziplist内存大小,realloc可能重新分配内存空间然后进行拷贝,也可能直接在原地址上进行扩展,不进行拷贝。

如果ziplist占据内存太大,realloc重新分配内存和拷贝会产生很大的消耗,所以ziplist不适合存储大型字符串,存储元素也不宜过多。

级联更新

由于每一个entry都有一个prevlen属性,该属性可能是1个字节或5个字节,取决于前一个元素的长度,所以在前一个元素长度变更,即长度由大于等于254变为小于254或由小于254变为大于等于254时,会导致后一个节点的prevlen属性更新。

如果后一个节点长度是253,则该节点的后续节点也需要更新,依此类推,可能导致后续所有的节点都需要进行更新,这种在特殊情况下产生的连续多次空间扩展操作称之为级联更新

级联更新在最坏情况下需要对ziplist执行N次内存重分配操作,而每次分配的最坏复杂度为O(N),所以级联更新的最坏复杂度为O(N^2)

尽管级联更新的复杂度较高,但是该操作造成性能问题的几率很低:

  • 需要ziplist中恰好有多个连续的、长度介于250~253个字节的节点才可能引发连续更新,该情况很少见

  • 即使出现级联更新,只要被更新的节点数量不多,就不会对性能产生影响

Redis数据结构之压缩列表-ziplist的更多相关文章

  1. Redis数据结构之压缩列表

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

  2. redis源码之压缩列表ziplist

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

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

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

  4. Redis 底层数据结构之压缩列表

    文章参考:<Redis 设计与实现>黄建宏 压缩列表 压缩列表 ziplist 是列表键和哈希键的底层实现之一.当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比 ...

  5. Redis实现之压缩列表

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

  6. Redis数据结构之快速列表-quicklist

    链表 在Redis的早期版本中,存储list列表结构时,如果元素少则使用压缩列表ziplist,否则使用双向链表linkedlist // 链表节点 struct listNode<T> ...

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

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

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

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

  9. 快速整透Redis中的压缩列表到底是个啥

    压缩列表简介 压缩列表(ziplist)是由一个连续内存组成的顺序型数据结构.一个压缩列表可以包含任意多个节点,每个节点上可以保存一个字节数组或整数值.它是Redis为了节省内存空间而开发的. 压缩列 ...

随机推荐

  1. linux下安装JMeter(小白教程)

    用windows平台测试时,会受到网络条件的影响,导致测试结果不够准确,尤其是高并发的情况下,需要能够精准的测试请求的响应时长,对于网络的要求更加苛刻.在这样的情况下,可以考虑在linux服务器端安装 ...

  2. C语言博客作业02

    2.1 一.请仔细阅读<提问的智慧>,用自己的话描述你的收获,并举例子说明应该如何提问. 答:1.提问是思考的另一种方式,一个好的提问能体现出我们在认真的,聪明的思考; 2.做什么事情都要 ...

  3. 前端面试题,js预处理部分小结,函数声明提升和变量声明提升

    博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/11/25/%e5%89%8d%e7%ab%af%e9%9d%a2%e8%af%95%e9% ...

  4. display的inline-block替代float的一些场景

    一.横向菜单 inline-block是不换行的块级元素,对于使用ul-li结构的网页顶部横向导航菜单非常有用. 如果不使用inline-block属性,只能使用float来浮动每个li元素,写起来比 ...

  5. Java面试宝典(1)Java基础部分

    Java面试宝典 题目,日积月累,等到出去面试时,一切都水到渠成,面试时就自然会游刃有余了. 答题时,先答是什么,再答有什么作用和要注意什么(这部分最重要,展现自己的心得) 答案的段落分别,层次分明, ...

  6. js将数字转换成货币形式的字符

    因为UI图上有的地方需要将数字转成货币形式的,例如:1234567转成  1,234,567  这样的,不过之前没弄过,然后在网上搜了下方法,参考了下面这篇文章 参考文章:JS将数字转成货币形式的简单 ...

  7. Nodejs进阶:密码加盐

    原理:就是在密码特定位置插入特定字符串后,再对修改后的字符串进行md5运算. demo var crypto=require("crypto"); function cryptPw ...

  8. vue 数字输入组件

    index.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...

  9. php操作redis--字典(hash)篇

    常用函数:hSet,hGet,hGetAll等. 应用场景:存储用户信息对象数据,包括id,姓名,年龄和生日,通过用户id来获取姓名,年龄等信息. 连接 $redis = new Redis(); $ ...

  10. elementUI 日期时间选择器 只能选择当前及之后的时间

    日期时间选择器  只能选择当前及之后的时间 <el-date-picker class="input-border-null" prefix-icon="el-ic ...