当前位置: 首页 > ds >正文

(ZipList入门笔记一)ZipList的节点介绍

ZipList是 Redis 中一种非常紧凑、节省内存的数据结构 Ziplist(压缩列表) 的内部内存布局。它被用于存储元素较少的 List、Hash 和 Zset。

下面我们来详细介绍每一个节点的含义:
在这里插入图片描述

1. zlbytes (ziplist bytes)

  • 含义: 整个压缩列表占用的总字节数。
  • 类型: 32位无符号整数(uint32_t),固定占用 4 个字节。
  • 作用: 这个字段记录了 Ziplist 的总大小。有了它,程序无需遍历整个列表就能知道其边界,这在进行内存重分配(realloc)时非常有用,可以直接告诉内存管理器需要多大的空间。

2. zltail (ziplist tail)

  • 含义: 指向列表中最后一个元素(entry)的偏移量(offset)。
  • 类型: 32位无符号整数(uint32_t),固定占用 4 个字节。
  • 作用: 这个字段允许程序在 O(1) 的时间复杂度内定位到 Ziplist 的最后一个节点,而无需从头遍历。这使得从列表尾部进行 pop(弹出)等操作非常高效。

3. zllen (ziplist length)

  • 含义: 压缩列表中的节点(entry)数量。
  • 类型: 16位无符号整数(uint16_t),固定占用 2 个字节。
  • 作用: 提供了在 O(1) 时间复杂度内获取列表长度的能力。
  • 特殊情况: 由于它只有16位,最大只能表示 65535。如果 Ziplist 中的节点数超过或等于 65535,这个字段会被设置为特殊值 65535 (FFFF)。在这种情况下,要获取真实长度,就必须遍历整个列表来统计,时间复杂度会退化为 O(N)。不过,Ziplist 的设计初衷就是用于存储少量数据,所以这种情况很少见。

4. entry (列表节点)

  • 含义: 这部分是 Ziplist 的核心,用来存储实际的数据元素。图中的 entry1, entry2, entry3 代表连续存放的多个节点。
  • 结构: 每个 entry 自身的结构也非常精巧,它由三个部分组成:
    1. previous_entry_length (前一节点的长度): 这个字段记录了前一个节点所占用的总字节数。它的存在是实现从后向前遍历 Ziplist 的关键。通过当前节点的地址减去这个长度,就可以得到前一个节点的起始地址。这个字段本身的长度是可变的(1字节或5字节),以节省空间。
    2. encoding (编码): 这个字段指明了 content 部分的数据类型(是字符串还是整数)以及它的长度。编码字段本身也是变长的,通过不同的二进制位模式来表示不同的编码方式,实现了极致的空间优化。
    3. content (内容): 实际存储的数据,可以是整数或一个字节数组(字符串)。其长度由 encoding 字段决定。

5. zlend (ziplist end)

  • 含义: 压缩列表的结束标记。
  • 类型: 8位无符号整数(uint8_t),固定占用 1 个字节。
  • 值: 它的值永远是 255 (二进制 11111111,十六进制 0xFF)。
  • 作用: 作为一个明确的终止符,当程序遍历列表时,一旦遇到这个值,就知道已经到达了列表的末尾。

总结

Ziplist 的设计精髓在于 “紧凑”。它不像常规链表那样为每个节点都使用前后指针(在64位系统上,一个指针就占8字节),而是通过存储前一节点的长度 (previous_entry_length) 和利用连续内存布局,实现了双向遍历,从而极大地节省了内存。图中 zlbytes, zltail, zllen 这三个头部字段,共同为这个紧凑的结构提供了高效的宏观操作能力。

下一篇:

(ZipList入门笔记二)为何ZipList可以实现内存压缩,可以详细介绍一下吗

http://www.xdnf.cn/news/17233.html

相关文章:

  • Windows 电脑远程访问,ZeroTier 实现内网穿透完整指南(含原理讲解)
  • Spring Boot 整合 Web 开发全攻略
  • 深度拆解Dify:开源LLM开发平台的架构密码与技术突围
  • 消息队列疑难问题(RocketMQ)
  • 09-堆
  • GaussDB 常见问题-集中式
  • 8.5 CSS3多列布局
  • lumerical——Y分支功分器
  • Redis Stream:高性能消息队列核心原理揭秘
  • PDF转图片工具技术文档(命令行版本)
  • CRT调试堆检测:从原理到实战的资源泄漏排查指南
  • 北京JAVA基础面试30天打卡02
  • RocketMq如何保证消息的顺序性
  • 面向对象的七大设计原则
  • Kotlin属性委托
  • 探秘MOBILITY China 2026,新能源汽车与智慧出行的未来盛宴
  • React18 严格模式下的双重渲染之谜
  • 嵌入式硬件中运放的基本控制原理
  • 2025金九银十Java后端面试攻略
  • 天津大学2024-2025 预推免 机试题目(第二批)
  • 400V降24V,200mA,应用领域:从生活到工业的 “全能电源管家”
  • C++面向对象编程基础:从类定义到封装机制详解
  • 深度学习-卷积神经网络CNN-填充与步幅
  • 最新基于Python科研数据可视化实践技术
  • 【人工智能99问】什么是Post-Training,包含哪些内容?(19/99)
  • Next Terminal 实战:内网无密码安全登录
  • MCP进阶:工业协议与AI智能体的融合革命
  • Redis之Hash和List类型常用命令
  • VGMP(VRRP Group Management Protocol)VRRP组管理协议
  • Druid学习笔记 02、快速使用Druid的SqlParser解析