Redis数据结构三之压缩列表
本文首发于公众号:Hunter后端
原文链接:Redis数据结构三之压缩列表
本篇笔记介绍压缩列表。
在 Redis 3.2 版本之前,压缩列表是列表对象、哈希对象、有序集合对象的的底层实现之一。
因为压缩列表本身结构上的一些缺陷,压缩列表这个结构被替换了,但是压缩列表结构本身有一些可取之处,并且替换它的新结构 listpack 与之很相似,所以我们这里还是介绍一下压缩列表的结构和存储
1、压缩列表的结构
压缩列表是 Redis 为了节约内存而开发的,由一个连续内存块组成的顺序型数据结构。
它的组成结构如下:
| zlbytes | zltail | zllen | entry1 | entry2 | ... | entryN | zlend |
压缩列表的英文名是 ziplist,所以它的属性都是 zl 开头。
1. 列表属性介绍
zlbytes
zlbytes 长度为 4 字节,记录整个压缩列表占用的内存字节数
zltail
zltail 长度为 4 字节,记录压缩列表最后一个节点,也就是我们结构示例中的 entryN 到 zlbytes 的地址之间的偏移量。
zllen
zllen 长度为 2 字节,记录的是压缩列表包含的节点数量,也就是结构中的 N。
zlend
zlend 长度为 1 字节,它的值为 0xFF(十进制 255),用于标记压缩列表的末端。
2. 压缩列表节点属性介绍
对于每一个 entry 节点,也就是压缩列表中的元素节点,它的结构示意如下:
| previous_entry_length | encoding | content |
previous_entry_length
previous_entry_length 属性记录的是压缩列表中前一个节点的长度
previous_entry_length 属性本身的长度可以是 1 字节或者 5 字节
如果前一节点的长度小于 254 字节,那么 previous_entry_length 属性的长度为 1 字节,前一个节点的长度保存在这个字节里
如果前一节点的长度大于等于 254 字节,那么 previous_entry_length 属性的长度为 5 字节,第一个字节被设置成 0xFE(也就是 254),之后的四个字节用于前一节点的长度。
通过 previous_entry_length 属性,我们可以通过当前节点的地址和 previous_entry_length 属性,计算出前一个节点的起始地址,压缩列表的从表尾到表头的遍历操作就是使用这个原理一个节点一个节点往前回溯实现的。
encoding
encoding 属性记录了节点的 content 属性所保存数据的类型以及长度。
encoding 的值如果是一字节长,且值的最高位以 11 开头,那么表示是整数编码,表示 content 属性保存着整数值。
encoding 的值为 一字节、两字节、五字节长,且值的最高位为 00、01、10 则表示是字节数组编码
content
content 属性保存的是节点的值,可以是一个字节数组或者整数,值的类型和长度由节点的 encoding 属性决定。
2、 连锁更新
在压缩列表的节点属性中,previous_entry_length 属性的长度是根据前一节点的长度来进行赋值的,如果前一节点的长度小于 254 字节,那么下一节点的 previous_entry_length 属性长度为 1 字节,如果前一节点的长度大于等于 254 字节,那么下一节点的 previous_entry_length 属性为 5 字节。
那么在这种情况下,就存在一种较为极端的情况,那就是压缩列表中每个节点的长度都在 250 - 253 字节之间,这时候,如果在表头插入一个长度大于等于 254 字节的节点,那么相对应的第二个节点的 previous_entry_length 的长度就要从 1 字节变为 4 字节,那么该节点的整体长度就大于等于 254 字节。
依此类推,压缩列表的每一个节点的长度都会产生连锁反应,长度都会逐个变成大于等于 254 字节长度,程序就需要不断地对压缩列表执行空间重分配的操作。
Redis 将这种在特殊情况下产生的连续多次空间扩展操作称为连锁更新。
除了新增节点这种情况,还有一种删除节点也可能造成连锁更新的情况,比如有这么几个节点,big 节点的长度大于等于 254 字节,small 节点长度小于254 字节,e1 到 eN 的节点长度都在 250-253 字节之间。
| zlbytes | zltail | zllen | big | small | entry1 | entry2 | ... | entryN | zlend |
这时候,删除 small 节点,entry1 节点的前节点的长度就会从 250-253 变成大于等于 254,因此 entry1 节点的 previous_entry_length 长度就会变成 5 字节,entry1 整体长度就会大于等于 254 字节,依次之后每个节点都会这样产生连锁更新。
尽管连锁更新的复杂度较高,但它真正造成性能问题的几率是很低的:
首先,压缩列表里要恰好有多个连续的、长度介于 250-253 字节之间的节点,连锁反应才有可能被引发
其次,即使出现连锁更新,但只要被更新的节点数量不多,就不会对性能造成任何影响,比如对只拥有三五个节点的压缩列表进行连锁更新。
3、压缩列表缺点
压缩列表虽然能节约内存,但仍然存在一些缺点:
- 需要通过遍历操作来查找节点,元素过多时会造成查询效率低下
- 对压缩列表节点进行新增或者修改时,可能会造成连锁更新的问题
如果想获取更多后端相关文章,可扫码关注阅读:

Redis数据结构三之压缩列表的更多相关文章
- Redis学习之ziplist压缩列表源码分析
一.压缩列表ziplist在redis中的应用 1.做列表键 当一个列表键只包含少量列表项,并且每个列表项要么是小整数,要么是短字符串,那么redis会使用压缩列表作为列表键的底层实现 2.哈希键 当 ...
- 图解Redis之数据结构篇——压缩列表
前言 同整数集合一样压缩列表也不是基础数据结构,而是 Redis 自己设计的一种数据存储结构.它有点儿类似数组,通过一片连续的内存空间,来存储数据.不过,它跟数组不同的一点是,它允许存储的数据 ...
- [redis读书笔记] 第一部分 数据结构与对象 压缩列表
压缩列表是为了节省内存而设计的,是列表键和哈希键的底层实现之一. 压缩列表的逻辑如下,
- redis源码之压缩列表ziplist
压缩列表ziplist1.简介连续,无序的数据结构.压缩列表是 Redis 为了节约内存而开发的, 由一系列特殊编码的连续内存块组成的顺序型(sequential)数据结构. 2.组成 属性 类型 长 ...
- redis 底层数据结构 压缩列表 ziplist
压缩列表是列表键和哈希键的底层实现之一.当一个列表键只包含少量列表项,并且每个列表项要么就是小整数,要么就是长度比较短的字符串,redis就会使用压缩列表来做列表键的底层实现 当一个哈希键只包含少量键 ...
- Redis数据结构之压缩列表
压缩列表是Redis为了节约内存而开发的,由一系列特殊编码的连续内存块组成的顺序型数据结构.一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值. 一.压缩列表结构1. 压缩列 ...
- Redis 底层数据结构之压缩列表
文章参考:<Redis 设计与实现>黄建宏 压缩列表 压缩列表 ziplist 是列表键和哈希键的底层实现之一.当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比 ...
- Redis压缩列表原理与应用分析
摘要 Redis是一款著名的key-value内存数据库软件,同时也是一款卓越的数据结构服务软件.它支持字符串.列表.哈希表.集合.有序集合五种数据结构类型,同时每种数据结构类型针对不同的应用场景又支 ...
- Redis压缩列表
此篇文章是主要介绍Redis在数据存储方面的其中一种方式,压缩列表.本文会介绍1. 压缩列表(ziplist)的使用场景 2.如何达到节约内存的效果?3.压缩列表的存储格式 4. 连锁更新的问题 5 ...
- redis 笔记01 简单动态字符串、链表、字典、跳跃表、整数集合、压缩列表
文中内容摘自<redis设计与实现> 简单动态字符串 1. Redis只会使用C字符串作为字面量,在大多数情况下,Redis使用SDS(Simple Dynamic String,简单动态 ...
随机推荐
- Python3程序捕获Ctrl+C终止信号
技术背景 对于一些连续运行或者长时间运行的Python程序而言,如服务器的后端,或者是长时间运行的科学计算程序.当我们涉及到一些中途退出的操作时,比如使用Ctrl+C来退出正在运行的程序.这种场景的出 ...
- Activiti7开发(三)-流程实例
目录 0.前言 1.创建流程实例 2.撤销申请(未实现) 3.查看审批历史(流程实例) 4.查看审批高亮图 0.前言 流程实例是与业务相关联的,先介绍一下业务:用户申请物品,领导进行审批(同意/拒绝) ...
- 《程序员的自我修养》学习笔记——ELF 文件结构介绍【第二弹】
ELF 文件结构介绍 文件头 以 ELF 文件64位版本为例: e_ident [ELF魔数 16byte] 1-4字节:ELF 文件都必须相同的标识码,分别为 0x7F,0x45,0x4C,0x46 ...
- Linux耳机音响独立输出
记得之前在用Ubuntu系统的时候,耳机和音响(线缆输出和模拟耳机输出)只能单独插一个,如果两个设备同时插入主机,将会导致只能耳机输出,即使选择后置音响(线缆输出)也不会有声音.在Windows下,即 ...
- 8.XSS和CSRF漏洞
XSS和CSRF漏洞 目录 XSS和CSRF漏洞 XSS漏洞介绍 XSS分类 利用XSS漏洞如何实行攻击 利用XSS盗取用户的Cookie 利用XSS实行钓鱼 利用XSS进行键盘监控 CSRF漏洞介绍 ...
- Android系统服务DropBoxManagerService详解与实践应用
作者:vivo 互联网客户端团队- Ma Lian 借助系统DropBoxManagerService对于系统文件目录dropbox管理的设计,了解其文件管理的规则.运行机制.读写机制.管控机制,根据 ...
- [Linux]异常配置专题之重复配置的有效性:系统/环境变量 | hosts
1 文由 在项目中经常遇到这种情况,1个hosts文件里同一IP 或 域名存在多个映射配置,那么到底哪个有效?环境变量亦有此问题. 问题本身不难,只是为了避免混淆,进行专门记录,以加深记忆. 2 ho ...
- [Linux]./configure | make | make install的工作过程与原理
经常使用的Linux编译/安装命令,有必要了解一下原理了. step1 ./configure 配置与编译前检查 通常由软件开发商编写一个检测程序(configure或config)来检测用户的操作环 ...
- Java设计模式 —— 适配器模式
9 适配器模式 9.1 结构型模式 结构型模式(Structural Pattern) 关注如何将现有类或对象组织在一起形成更强大的结构.结构型模式根据描述目标不同可以分为两种: 类结构型模式:关心类 ...
- Java 框架面试题-Spring Boot自定义配置与自动配置共存
Spring Boot 是一个快速开发框架,可以简化 Spring 应用程序的开发,其中自定义配置是其中一个非常重要的特性. 在 Spring Boot 中,自定义配置允许开发者以自己的方式来配置应用 ...