Mr Dk.'s BlogMr Dk.'s Blog
  • 🦆 About Me
  • ⛏️ Technology Stack
  • 🔗 Links
  • 🗒️ About Blog
  • Algorithm
  • C++
  • Compiler
  • Cryptography
  • DevOps
  • Docker
  • Git
  • Java
  • Linux
  • MS Office
  • MySQL
  • Network
  • Operating System
  • Performance
  • PostgreSQL
  • Productivity
  • Solidity
  • Vue.js
  • Web
  • Wireless
  • 🐧 How Linux Works (notes)
  • 🐧 Linux Kernel Comments (notes)
  • 🐧 Linux Kernel Development (notes)
  • 🐤 μc/OS-II Source Code (notes)
  • ☕ Understanding the JVM (notes)
  • ⛸️ Redis Implementation (notes)
  • 🗜️ Understanding Nginx (notes)
  • ⚙️ Netty in Action (notes)
  • ☁️ Spring Microservices (notes)
  • ⚒️ The Annotated STL Sources (notes)
  • ☕ Java Development Kit 8
GitHub
  • 🦆 About Me
  • ⛏️ Technology Stack
  • 🔗 Links
  • 🗒️ About Blog
  • Algorithm
  • C++
  • Compiler
  • Cryptography
  • DevOps
  • Docker
  • Git
  • Java
  • Linux
  • MS Office
  • MySQL
  • Network
  • Operating System
  • Performance
  • PostgreSQL
  • Productivity
  • Solidity
  • Vue.js
  • Web
  • Wireless
  • 🐧 How Linux Works (notes)
  • 🐧 Linux Kernel Comments (notes)
  • 🐧 Linux Kernel Development (notes)
  • 🐤 μc/OS-II Source Code (notes)
  • ☕ Understanding the JVM (notes)
  • ⛸️ Redis Implementation (notes)
  • 🗜️ Understanding Nginx (notes)
  • ⚙️ Netty in Action (notes)
  • ☁️ Spring Microservices (notes)
  • ⚒️ The Annotated STL Sources (notes)
  • ☕ Java Development Kit 8
GitHub
  • ⛸️ Redis Implementation
    • Part 1 - 数据结构与对象

      • Chapter 2 - 简单动态字符串
      • Chapter 3 - 链表
      • Chapter 4 - 字典
      • Chapter 5 - 跳跃表
      • Chapter 6 - 整数集合
      • Chapter 7 - 压缩列表
      • Chapter 8 - 对象
    • Part 2 - 单机数据库的实现

      • Chapter 9 - 数据库
      • Chapter 10 - RDB 持久化
      • Chapter 11 - AOF 持久化
      • Chapter 12 - 事件
      • Chapter 13 - 客户端
      • Chapter 14 - 服务器
    • Part 3 - 多机数据库的实现

      • Chapter 15 - 复制
      • Chapter 16 - Sentinel
      • Chapter 17 - 集群
    • Part 4 - 独立功能的实现

      • Chapter 18 - 发布与订阅
      • Chapter 19 - 事务
      • Chapter 21 - 排序
      • Chapter 22 - 二进制位数组
      • Chapter 23 - 慢查询日志

Chapter 7 - 压缩列表

Created by : Mr Dk.

2020 / 06 / 01 16:45

Nanjing, Jiangsu, China


Ziplist Definition

当列表项中要么是 小整数值,要么是 较短的字符串 时,Redis 使用压缩列表来作为列表键的底层实现。压缩列表由一系列特殊编码的连续内存块组成的顺序结构,其中可以包含任意多个结点,每个结点可以用于保存一个字节数组或整数值。

AttributeTypeLengthDescription
zlbytesuint32_t4B记录整个压缩列表的字节长度
zltailuint32_t4B列表中最后一个结点距离列表起始地址的偏移 (不需遍历就能确定表尾结点位置)
zllenuint16_t2B列表中的结点数量 (当数量超过其能表示的最大范围时,需要遍历整个列表才能得到结果)
entryX列表结点不一定各个结点
zlenduint8_t1B0xFF,标记压缩列表末端

Ziplist Node Definition

  • previous_entry_length - 前一结点长度 (这样就可以通过当前结点计算出前一个结点的位置)
  • encoding - 当前结点的编码方式
  • content - 当前结点的内容

如果前一结点的长度小于 254B,previous_entry_length 用一个字节来表示;否则,就使用五个字节 - 第一字节为 0xFE,剩余四个字节表示长度。编码方式也类似,不同的编码方式对应了不同的长度。

连锁更新

当前一结点的长度超过 254B 阈值时,后续结点就需要将 1B 的 previous_entry_length 修改为 5B 的表示形式,从而引发后续结点也变长了。如果比较倒霉,后续结点又会发生连锁的更新。类似地,从列表中删除元素时,也存在这种可能。但是在实际的使用中,发生这种情况的概率很低。

疑问

结点的内容是直接存在列表中,还是只在列表中保存了指向内容的指针?如果结点的内容发生变化,长度发生变化,那么后续结点的内容是不是也会跟着在内存中后移?这样会不会存在性能问题?

Edit this page on GitHub
Prev
Chapter 6 - 整数集合
Next
Chapter 8 - 对象