Redis-压缩列表

压缩列表

介绍

  • 压缩列表(ziplist)是列表建和哈希键的底层实现之一,当一个列表键质保函少量列表项,并且每个列表项要么就是小整数值,要么是长度比较小的字符串,Redis就会使用压缩列表来存储他们 已达到节约内存的目的

构成

  • 压缩列表是由一系列特殊编码的连续内存块组成的顺序型数据结构

  • 其中包含多个节点,每个节点可以保存一个字节数组或者一个整数值

  • 列表的构成

属性类型长度用途
zlbytesuint32_t4字节记录整个压缩列表占用的内存字节数,对压缩列表进行内存重分配和计算zlend的位置时使用
zltailuint32_t4字节记录压缩列表表尾节点距离压缩列表的其实地址有多少字节;通过这个偏移量,程序无序遍历整个压缩列表就可以确定表尾几点的地址
zllenuint16_t2字节记录压缩列表中节点的数量当节点数量超过最大值(65535)时 真实的节点数量需要遍历整个压缩列表来获得
entryX列表节点不定压缩列表的各个节点,具体长度需要由节点保存的内容来决定
zlenduint8_t1字节特殊值(255) 用于标记压缩列表的末端

节点

  • 每个压缩列表的节点都可以保存一个较短的字符串或者整数类型

    • 其中 字节数组可以是以下的三种

      • 长度小于等于63 (2的六次方-1)字节的字节数组

      • 长度小于等于16383(2的14次方-1) 字节的字节数组

      • 长度小于等于4294967295(2的32次方-1) 字节的字节数组

    • 整数类型

      • 4bit 介于0-12之间的无符号整数

      • 1字节长的有符号整数

      • 3字节长的有符号整数

      • int16_t类型整数

      • int32_t类型整数

      • int64_t类型整数

  • 其次每个节点都有previous_entry_length、encoding、content 三个部分组成

  • 那么节点是怎么构成的能 向下看

  1. previous_entry_length
  • 这个属性为字节的单位,记录了压缩列表中前一个节点的长度,previous_entry_length可以是1字节或者5字节

  • 前一节的长度小于254字节 那么previous_entry_length的长度为1字节

  • 前一节的长度大于等于254字节, 那么previous_entry_length的长度为5字节

  • 当前一个字节长度发生变化时previous_entry_length就会变化 当前一个节点的长度由小于254变成大于等于254是 previous_entry_length也会改变 可能就会导致连锁更新具体什么是连锁更新后面会说

  1. encoding
  • encoding中保存了content中数据的类型以及长度

    • bbbbb xxx等为具体的二进制包含的就是content的长度
编码编码长度content属性保存的值
00bbbbbb1字节长度小于等于63字节的字节数组
01bbbbbb xxxxxxxx2字节长度小于等于16383(2的14次方-1) 字节的字节数组
10_______ aaaaaaaa bbbbbbbb cccccccc dddddddd5字节长度小于等于4294967295(2的32次方-1) 字节的字节数组
110000001字节int16_t类型的整数
110100001字节int32_t类型的整数
111000001字节int64_t类型的整数
111100001字节24位有符号整数
111111101字节8位有符号整数
1111xxxx1字节其中xxxx可以表示介于0-12的无符号整数,所以不需要给content分配空间
  1. content
  • 用来保存节点的值,类型和长度由encoding来决定

连锁更新

之前介绍previous_entry_length的时候说过 previous_entry_length记录的是前一个节点的长度 当节点长度小于254字节的时候 previous_entry_length站1字节 大于等于254字节站5字节

  • 当一个长度为n的压缩列表,节点的长度都在250-253之间时,在表头插入一个长度超过254字节的节点 就会使得第一个节点的previous_entry_length进行升级为5字节,从而导致第二个 以此类推直至第n个

  • 这种情况下 每次重新分配空间的时间复杂度为O(n) 整个列表进行重新分配就是O(n*n) 对于这种情况就属于连锁更新

  • 但是不用担心 几个节点进行连锁更新不会影响redis的正常使用 除非大规模的进行连锁更新 但是概率非常非常小

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值