• Redis源码学习:ziplist的数据结构和连锁更新问题


    ziplist

    ziplist 是 Redis 中一种紧凑型的列表结构,专门用来存储元素数量少且每个元素较小的数据。它是一个双端链表, 可以在任意一端进行压入/弹出操作,并且该操作的时间复杂度为O(1)。

    ziplist数据结构

    ...

    字段字节数描述
    zlbytes4 字节记录整个 ziplist 所占用的字节数
    zltail4 字节记录 ziplist 最后一个元素的偏移量
    zllen2 字节记录 ziplist 中包含的元素个数(最大为 65535)
    entryX不定长每个元素的数据,包括 prevlen、encoding 和 content
    zlend1 字节特殊值 0xFF,标志 ziplist 的结束

    每个元素的结构

    字段字节数描述
    prevlen1 或 5 字节记录前一个元素的长度,为了方便反向遍历ziplist
    encoding1-5 字节记录当前元素的类型和长度信息
    content不定长具体的数据内容,长度由 encoding 部分决定

    ziplist的不足

    1、查找复杂度高

    虽然ziplist对头尾的操作可以很快,但是,当要查找列表中间的元素时,ziplist 就得从列表头或列表尾遍历才行。而当 ziplist 保存的元素过多时,查找中间数据的复杂度就会增加。因此,ziplist的最大存储元素数量和每个元素的大小直接影响其性能。

    • hash-max-ziplist-entries:hash 类型元素数量超过指定数据后时候。使用 hash 存储, 否则使用压缩表。
    • hash-max-ziplist-value: hash 类型元素长度超过指定数据后时候。 使用 hash 存储,否则使用压缩链表。
    • zset-max-ziplist-entries:zset 类型 压缩列表 ziplist 最大限制元素数。超过指定值将会使用跳表 skiplist + dict 来存储。
    • zset-max-ziplist-value:set 类型 压缩列表 ziplist 最大限制大小。超过指定将会使用跳表 skiplist+dict 来存储。

    Redis.conf文件中有默认配置:

    # 最大元素个数
    hash-max-ziplist-entries 512
    # 元素最大字节数
    hash-max-ziplist-value 64
    
    zset-max-ziplist-entries 128
    zset-max-ziplist-value 64
    

    2、连锁更新问题

    由于ziplist 必须使用一块连续的内存空间来保存数据,所以当新插入一个元素时,ziplist 就需要计算其所需的空间大小,并申请相应的内存空间,假设有N个小于255字节的Entry,每一个Entry的pre_entry_len都可以用1个字节存储,现在要在中间插入新的Entry,长度大于254,此时pre_entry_len就需要5字节来存,后续的元素的prevlen字段也需要扩展,就会引起连锁更新的问题。这一系列操作,可以从 ziplist 的元素插入函数__ziplistInsert中看到。
    Snipaste_2024-06-22_18-41-04.png

    到这里结束,希望本文对你有帮助。

  • 相关阅读:
    Java入门------数组
    【imessage苹果群发苹果推】软件安装Apple证书,服务或其他方式建立任何涵盖的产品或其他代码或程序
    STM32CubeMX驱动INA226芯片
    MySQL系统表information_schema.INNODB_TRX详解及查看当前运行事务
    磁盘存储链式的B树与B+树
    vue+springboot,easyexcel的excel文件下载
    手写HashMap 手撕哈希表
    2-10.基金管理人的内部控制
    SQL练习题
    Windows下同一电脑配置多个Git公钥访问不同的账号
  • 原文地址:https://blog.csdn.net/github_37151951/article/details/139886732