Redis数据结构之压缩列表-ziplist
为了节约内存,在zset和hash容器对象元素个数较少时,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的更多相关文章
- Redis数据结构之压缩列表
压缩列表是Redis为了节约内存而开发的,由一系列特殊编码的连续内存块组成的顺序型数据结构.一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值. 一.压缩列表结构1. 压缩列 ...
- redis源码之压缩列表ziplist
压缩列表ziplist1.简介连续,无序的数据结构.压缩列表是 Redis 为了节约内存而开发的, 由一系列特殊编码的连续内存块组成的顺序型(sequential)数据结构. 2.组成 属性 类型 长 ...
- redis 5.0.7 源码阅读——压缩列表ziplist
redis中压缩列表ziplist相关的文件为:ziplist.h与ziplist.c 压缩列表是redis专门开发出来为了节约内存的内存编码数据结构.源码中关于压缩列表介绍的注释也写得比较详细. 一 ...
- Redis 底层数据结构之压缩列表
文章参考:<Redis 设计与实现>黄建宏 压缩列表 压缩列表 ziplist 是列表键和哈希键的底层实现之一.当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比 ...
- Redis实现之压缩列表
压缩列表 压缩列表(ziplist)是列表键和哈希键的底层实现之一,当一个列表键只包含少量列表项,并且每个列表项要嘛是整数值,要嘛是比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现. ...
- Redis数据结构之快速列表-quicklist
链表 在Redis的早期版本中,存储list列表结构时,如果元素少则使用压缩列表ziplist,否则使用双向链表linkedlist // 链表节点 struct listNode<T> ...
- redis 底层数据结构 压缩列表 ziplist
压缩列表是列表键和哈希键的底层实现之一.当一个列表键只包含少量列表项,并且每个列表项要么就是小整数,要么就是长度比较短的字符串,redis就会使用压缩列表来做列表键的底层实现 当一个哈希键只包含少量键 ...
- Redis 的底层数据结构(压缩列表)
上一篇我们介绍了 redis 中的整数集合这种数据结构的实现,也谈到了,引入这种数据结构的一个很大的原因就是,在某些仅有少量整数元素的集合场景,通过整数集合既可以达到字典的效率,也能使用远少于字典的内 ...
- 快速整透Redis中的压缩列表到底是个啥
压缩列表简介 压缩列表(ziplist)是由一个连续内存组成的顺序型数据结构.一个压缩列表可以包含任意多个节点,每个节点上可以保存一个字节数组或整数值.它是Redis为了节省内存空间而开发的. 压缩列 ...
随机推荐
- C++基础知识随记
一.什么情况必须使用初始化列表的方式声明构造函数? 1.包含常量类型的成员 2.包含引用类型的成员 3.包含没有默认构造函数的类类型成员 4.优点:对于包含有类类型成员的类来说,省去了调用一次默认构造 ...
- Struct和Union的sizeof计算
struct 结构体的大小不是简单的成员相加,要考虑存储空间的字节对齐 1.空结构体的大小为1 2.含有static的结构体在计算大小时不算上static变量,因为static存储在全局数据空间,而s ...
- Notepad++中直接运行python
点击进入幕布视图浏览 https://mubu.com/doc/a8VGCUfqqw 一.使用Notepad++编辑python文件,并直接运行 1.用notepad++打开python文件.或者新建 ...
- 迭代器,生成器,yield,yield from理解
迭代器 说到迭代器就得想说可迭代对象Iterable,实现了__iter__()方法的对象都是可迭代对象,例如很多容器,list ,set, tuples.使用iter方法可以把一个可迭代对象变成迭代 ...
- JsonSchema 启蒙
jsonSchema 的应用场景有很多,毕竟现在各个接口传输数据基本都是json,比如你做测试想对部分json字段进行校验或者统计你该如何写?解析json获取字段然后if else?不是说不可以但是也 ...
- 配置基于python的VIM环境
配置基于python的VIM环境 安装插件管理工具 为防止过多插件管理的麻烦,首先安装vim的插件管理工具Vundle.vundle本身的github软件已经有相关的中文文档,地址如下: vundle ...
- caffer的三种文件类别
solver文件 是一堆超参数,比如迭代次数,是否用GPU,多少次迭代暂存一次训练所得参数,动量项,权重衰减(即正则化参数),基本的learning rate,多少次迭代打印一次loss,以及网络结构 ...
- Ubuntu下串口工具
一.Kermit 1.安装: sudo apt-get install ckermit 2.配置: sudo gedit /etc/kermit/kermrc 3.在文件末端添加如下内容 : set ...
- ES6 数组扩展(总结)
1.扩展运算符 将一个数组转为用逗号分隔的参数序列 console.log(1, ...[2, 3, 4], 5) // 1 2 3 4 5 2.Array.from() 将两类对象转为真正的数组 类 ...
- jQuery与Vue的区别、从jQuery到Vue框架优点总结
一.两者的区别 1.数据与视图分离 2.数据驱动视图 二.从jQuery到Vue框架的总结 1.数据与视图分离,解耦 2.数据驱动视图,只关心数据,DOM操作已经被框架封装