美文网首页
redis 内部数据结构(1.6)-压缩列表

redis 内部数据结构(1.6)-压缩列表

作者: 颜灏_2181 | 来源:发表于2017-04-09 15:49 被阅读0次

    压缩列表(ziplist)是列表键和哈希键的底层实现之一。

    当一个列表键只包含少量列表项, 并且每个列表项要么就是小整数值, 要么就是长度比较短的字符串, 那么 Redis 就会使用压缩列表来做列表键的底层实现。

    比如说, 执行以下命令将创建一个压缩列表实现的列表键:

    redis> RPUSH lst 1 3 5 10086 "hello" "world"
    (integer) 6
    
    redis> OBJECT ENCODING lst
    "ziplist"
    

    因为列表键里面包含的都是 1 、 3 、 5 、 10086 这样的小整数值, 以及 "hello" 、 "world" 这样的短字符串。

    另外, 当一个哈希键只包含少量键值对, 并且每个键值对的键和值要么就是小整数值, 要么就是长度比较短的字符串, 那么 Redis 就会使用压缩列表来做哈希键的底层实现。

    举个例子, 执行以下命令将创建一个压缩列表实现的哈希键:

    redis> HMSET profile "name" "Jack" "age" 28 "job" "Programmer"
    OK
    
    redis> OBJECT ENCODING profile
    "ziplist"
    

    压缩列表是 Redis 为了节约内存而开发的, 由一系列特殊编码的连续内存块组成的顺序型(sequential)数据结构。

    一个压缩列表可以包含任意多个节点(entry), 每个节点可以保存一个字节数组或者一个整数值。

    压缩表的构成

    图 7-1 展示了压缩列表的各个组成部分, 表 7-1 则记录了各个组成部分的类型、长度、以及用途。

    Paste_Image.png
    • 列表 zlbytes 属性的值为 0x50 (十进制 80), 表示压缩列表的总长为 80 字节。
    • 列表 zllen 属性的值为 0x3 (十进制 3), 表示压缩列表包含三个节点。
    • 列表 zltail 属性的值为 0x3c (十进制 60), 这表示如果我们有一个指向压缩列表起始地址的指针 p , 那么只要用指针 p 加上偏移量 60 , 就可以计算出表尾节点 entry3 的地址。
    Paste_Image.png

    图 7-3 展示了另一个压缩列表示例:

    • 列表 zlbytes 属性的值为 0xd2 (十进制 210), 表示压缩列表的总长为 210 字节。
    • 列表 zltail 属性的值为 0xb3 (十进制 179), 这表示如果我们有一个指向压缩列表起始地址的指针 p , 那么只要用指针 p 加上偏移量 179 , 就可以计算出表尾节点 entry5 的地址。
    • 列表 zllen 属性的值为 0x5 (十进制 5), 表示压缩列表包含五个节点。
    Paste_Image.png

    压缩表节点的构成

    每个压缩列表节点都由 previous_entry_length 、 encoding 、 content 三个部分组成

    Paste_Image.png

    previous_entry_length

    节点的 previous_entry_length 属性以字节为单位, 记录了压缩列表中前一个节点的长度。

    previous_entry_length 属性的长度可以是 1 字节或者 5 字节:

    • 如果前一节点的长度小于 254 字节, 那么 previous_entry_length 属性的长度为 1 字节: 前一节点的长度就保存在这一个字节里面。
    • 如果前一节点的长度大于等于 254 字节, 那么 previous_entry_length 属性的长度为 5 字节: 其中属性的第一字节会被设置为 0xFE(十进制值 254), 而之后的四个字节则用于保存前一节点的长度。
    Paste_Image.png

    因为节点的 previous_entry_length 属性记录了前一个节点的长度, 所以程序可以通过指针运算, 根据当前节点的起始地址来计算出前一个节点的起始地址。

    encoding

    节点的 encoding 属性记录了节点的 content 属性所保存数据的类型以及长度

    content

    节点的 content 属性负责保存节点的值, 节点值可以是一个字节数组或者整数, 值的类型和长度由节点的 encoding 属性决定。

    相关文章

      网友评论

          本文标题:redis 内部数据结构(1.6)-压缩列表

          本文链接:https://www.haomeiwen.com/subject/ybqhattx.html