当前位置:网站首页>Redis(5)----浅谈压缩列表
Redis(5)----浅谈压缩列表
2022-06-26 07:17:00 【cb414】
1,前言
压缩列表(ziplist)是列表键和哈希键的底层实现之一。
当列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么是短字符串,Redis就会用压缩列表作为列表键的底层实现
Redis的其他数据结构相关如下:
简单动态字符串
链表
字典
整数集合
2,压缩列表
2.1,列表结构
压缩列表是Redis为了节约内存开发的,是由一系列特殊编码的连续内存块组成的顺序型数据结构,一个压缩列表可以包含任意多个节点(entry
),每个节点可以保存一个字节数组或者一个整数值。
下面是各个部分的详细说明:
属性 | 类型 | 长度 | 用途 |
---|---|---|---|
zlbytes | uint32_t | 4字节 | 记录整个压缩列表占用的内存字数:在对压缩列表进行内存重分配或者计算zlend的位置时使用 |
zltail | uint32_t | 4字节 | 记录压缩列表表尾节点距离压缩列表的起始地址有多少字节:通过这个偏移量,程序无需遍历整个压缩列表就可以确定表尾节点的地址 |
zllen | uint16_t | 2字节 | 记录了压缩列表包含的节点数量:当这个属性的值小于UINT16_MAX(65535)时,这个属性的值就是压缩列表包含节点的数量;当这个值等于UINT16_MAX,节点的真是数量需要遍历整个压缩列表后才能计算得出 |
entryX | 列表节点 | 不定 | 压缩列表包含的各个节点,节点的长度由节点保存的内容决定 |
zlend | uint8_t | 1字节 | 特殊值0xFF(十进制255),用于标记压缩列表的末端 |
以下面的压缩列表为例
zlbytes
:该值是0x50(十进制的80),表示压缩列表的总长度位80字节zltail
:该值是0x3c(十进制的60),假如此时有一个指针p
指向压缩列表起始地址,那么用该指针加上偏移量60就可以计算出表尾节点entry3
的地址zllen
:该值是0x3(十进制的3),表示该压缩列表包含三个节点
2.2,列表节点结构
每个压缩列表节点都可以保存一个字节数组或者一个整数值
如果是字节数组:
- 长度小于等于63(26-1)字节的字节数组
- 长度小于等于16383(214-1)字节的字节数组
- 长度小于等于4 294 967 295(232-1)字节的字节数组
如果是整数值的话:
- 4位长,介于0-12之间的无符号整数
- 1字节长的有符号整数
- 3字节长的有符号整数
int16_t
类型整数int32_t
类型整数int64_t
类型整数
每个列表节点的结构示意图如下:
2.2.1,previous_entry_length
节点的previous_entry_length
属性以字节为单位,记录了前一个节点的长度,该属性长度可以是一个字节也可以是五个字节。
- 如果前一个节点的长度小于254字节,那么
previous_entry_length
属性的长度为1字节;前一字节的长度就保存在这一个字节里面 - 如果前一字节的长度大于等于254字节,那么
previous_entry_length
属性的长度为5字节;其中属性的第一字节就会被设置为0xFE
(十进制254),而之后的四个字节则用于保存前一节点的长度
示例
- 图7-5表示前一个结点的长度为0x05(十进制5个字节)
- 图7-6中,
0xFE
表示这是一个五字节长的previous_entry_length
属性,而之后的0x00002766
(十进制10086)才是前一节点的长度
好处
因为previous_entry_length
记录了前一节点的长度,所以只要拿到当前节点的地址,就能实现从表尾节点向表头方向进行遍历操作(用当前指针减去previous_entry_length
属性的值就能获得上一节点的起始地址)
2.2.2,encoding
上面提及到,压缩列表节点可以保存字节数组或者整数,encoding
属性就是用来表示当前节点的存储数据类型和长度
- 一字节长、两字节长或者五字节长:值的最高位为00、01或者10代表的是字节数组编码,这种编码表示节点的
content
属性存储的是字节数组。数组的长度由encoding
出去最高两位之后的其他位记录 - 一字节长:值的最高位以11开头的是整数编码,这种编码表示
content
属性存储的是整数值,整数值的类型和长度由encoding
出去最高两位之后的其他位记录。
2.2.3,content
节点的content
属性负责保存节点值,节点值可以是一个字节数组或者整数,值得类型和长度由encoding
属性决定。
图7-9是一个存储字节数组的节点
- 编码最高位是00,表示节点保存的是字节数组
- 编码后六位是字节数组的长度,也就是十进制的11
content
表示该节点存储的是hello world
图7-10是一个存储整数值的节点- 编码
11000000
表示节点保存的是一个int16_t
类型的整数值 content
属性表示保存的是10086
2.3,连锁更新
回忆上面每个节点的结构中,都有一个previous_entry_length
用于存储前一个节点的长度。
如果前一节点的长度小于254,则该节点的previous_entry_length
用一个字节表示,反之需要五个字节。
考虑这样的一种极端情况:
- 一个压缩列表A中,存储了10个数据,而每个数据的长度都是介于250-253个字节之间
- 此时往第一个节点(称其为节点e1)前面,插入一个新的节点(称其为节点n),而这个节点的长度是大于254个字节的
- 这时会导致一个问题,节点e1要记录节点n的长度,并且由于节点n的长度大于254,所以e1的
previous_entry_length
需要由原先的一个字节扩展为五个字节 - 而e1的
previous_entry_length
扩展会导致e1节点长度介于254-257之间,这会导致e1的后续节点也引发相应的previous_entry_length
扩展,并且后续的所有节点都会发生这种问题 - 为了让每个列表的
previous_entry_length
属性都符合压缩列表对于节点的要求,程序需要不断地对压缩列表执行空间重分配
上述这种特殊情况下产生的连续多次空间扩展操作称之为”连锁更新“。除了添加新节点有可能引发连锁更新外,删除某个节点也有可能引发。
实际上连锁更新发生的条件并不常见;并且即使出现连锁更新,只要被更新的节点数量不多,就不会导致任何影响。
边栏推荐
- How to convert Unicode into Chinese characters in Excel
- Oracle中计算除法——解决除数为零报错
- One chip realizes functions such as spray 𞓜 ws2812 drive | key touch | LED display | voice broadcast chip and simplifies the design of humidifier products
- I3wm get window class
- How to quickly merge multiple PDF files?
- [image segmentation] blood vessel extraction from retinal fundus images based on maximum principal curvature with matlab code
- 职场“大冤种”,不仅身累,心也被掏空……
- Liujinhai, chief architect of zhongang Mining: according to the analysis of fluorite supply and demand, it is estimated that the fluorine coating market has great potential
- China imported wine circulation and investment market survey and Future Development Trend Outlook report 2022-2027
- Rust中的过程宏
猜你喜欢
Tetradecanoxy tetraphenylporphyrin methacrylate mm-tpp-14c; Cetanoxy tetraphenyl porphyrin methacrylate mm-tpp-16c; Purple solid; Qiyue supply
3D porphyrin MOF (mof-p5) / 3D porphyrin MOF (mof-p4) / 2D cobalt porphyrin MOF (ppf-1-co) / 2D porphyrin COF (POR COF) / supplied by Qiyue
Alkynyl crosslinked porphyrin based polyimide materials (ppbpi-h-cr, ppbpi Mn cr.ppbpi Fe Cr); Metalloporphyrin based polyimide (ppbpi Mn, ppbpi FE) supplied by Qiyue
大厂面试TCP协议经典十五连问!22张图让你彻底弄明白
Pytorch builds CNN LSTM hybrid model to realize multivariable and multi step time series forecasting (load forecasting)
Installation homebrew error summary
缓存使用
PXRD, IR, TGA of two-dimensional porphyrin COF (POR COF) /cof (2D pdpor COF) - supplied by Qiyue
How to publish function computing (FC) through cloud effect
专业课-代码题记录
随机推荐
Paths with a certain value in a binary tree (1) (2) (3) (Sword finger offer)
QPS
大厂面试TCP协议经典十五连问!22张图让你彻底弄明白
Cocoscreator plays spine animation
MySQL operation database
同花顺究竟如何开户,网上开户是否安全么?
Kalman filter_ Recursive Processing
MySQL'replace into'has a self incrementing ID of the pit. There is a problem with the backup opportunity
Porphyrin based polyimide ppbpis (ppbpi-pa, ppbpi-pepa and ppbpi-pena); Crosslinked porphyrin based polyimide (ppbpi-pa-cr, ppbpi-pepa-cr, ppbpi-pena-cr) reagent
Qt基础教程:QString
[image detection] image target size measurement system based on morphology with matlab code
专业课-代码题记录
5,10,15,20-tetra (4-bromophenyl) porphyrin (h2tppbr4) /5.2.15,10,15,20-tetra [4-[(3-aminophenyl) ethynyl] phenyl] porphyrin (tapepp) Qiyue porphyrin reagent
MXNet对NIN网络中的网络的实现
C#实现给DevExpress中GridView表格指定列添加进度条显示效果——代码实现方式
Detailed materials of applying for residence permit in non local Beijing
When asked during the interview, can redis master-slave copy not answer? These 13 pictures let you understand thoroughly
MySQL storage and custom functions
SQL query statement
网络io,磁盘io