redis数据结构之压缩列表

 更新时间:2022年03月21日 09:25:37   作者:周杰伦本人  
这篇文章主要介绍了redis数据结构之压缩列表,压缩列表是列表list和hash数据结构的底层实现之一,是redis为了节约内存而开发的,由一系列特殊编码的连续内存块组成的顺序型数据结构,下面详细内容需要的小伙伴可以参考一下

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

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

压缩列表是Redis为了节约内存而开发的是由一系列特殊编码的连续内存块组成的顺序型数据结构,一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值

ziplist 数据结构:压缩列表各个组成部分

压缩列表各个组成部分详细说明:

压缩列表节点的构成:

每个压缩列表节点可以保存一个字节数组或者一个整数值,其中字节数组可以是以下三种长度的其中一种

长度小于等于63字节的字节数组

长度小于等于16383字节的字节数组

长度小于等于4294967295字节的字节数组

数值则可以是以下六种长度的其中一种:

  • 1:  4位长介于0至12之间的无符号整数
  • 2:1字节长的有符号整数
  • 3: 3字节长的有符号整数
  • 4:int16类型整数
  • 5:int32类型整数
  • 6 : int64类型整数

压缩列表的数据结构:

压缩列表是redis为了节约内存而开发的,由一系列特殊编码的连续内存块组成的顺序型数据结构。一个压缩列表可以包含任意多个节点,每个节点保存一个字节数组或者一个整数值。

创建一个空的ziplist:

/*
 * 新创建一个空 ziplist
 * 
 * 复杂度:O(1)
 *
 * 返回值:新创建的 ziplist
 */
unsigned char *ziplistNew(void) {
    // 分配 2 个 32 bit,一个 16 bit,以及一个 8 bit
    // 分别用于 <zlbytes><zltail><zllen> 和 <zlend>
    unsigned int bytes = ZIPLIST_HEADER_SIZE+1;
    unsigned char *zl = zmalloc(bytes);

    // 设置长度
    ZIPLIST_BYTES(zl) = intrev32ifbe(bytes);

    // 设置表尾偏移量
    ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(ZIPLIST_HEADER_SIZE);

    // 设置列表项数量
    ZIPLIST_LENGTH(zl) = 0;

    // 设置表尾标识
    zl[bytes-1] = ZIP_END;

    return zl;
}

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

压缩列表组成部分:

  • zlbytes:记录整个压缩列表占用的内存字节数
  • zltail:记录压缩列表表尾节点距离压缩列表的起始地址的字节数
  • entryX:列表节点
  • zlend:用于标记压缩列表的末端

压缩列表节点的构成:

  • preivous_entry_length:记录压缩列表中前一个节点的长度
  • encoding:记录节点content属性保存数据的类型以及长度
  • content:负责保存节点的值,值的类型和长度由节点的encoding属性决定。

当我们知道一个指向某个节点起始地址的指针,那么通过这个指针以及这个节点的preivous_entry_length属性,我们可以一直向前一个节点回溯,最终到达压缩列表的表头节点。

连锁更新:

每个节点的preivous_entry_length属性记录前一个节点的长度

如果前一个节点长度小于254字节,preivous_entry_length属性需要用1字节长的空间来保存这个长度值

如果前一个节点长度大于等于254字节,preivous_entry_length属性需要用5字节长的空间来保存这个长度值

如果前一个节点长度变大,这个节点的preivous_entry_length就要扩展,这个节点的扩展引起下一个节点的扩展,这就是连锁更新

redis将这种在特殊情况下产生的连续多次空间扩展操作称之为连锁更新

在添加新节点和删除节点都可能引发连锁更新。

连锁更新最坏情况下需要对压缩列表进行N次空间重分配操作,每次空间重分配的最坏复杂度为O(N),所以连锁更新的最坏复杂度为O(N的平方),平均复杂度为O(N)

总结:

压缩列表是为了节约内存而开发的顺序型数据结构,它是列表键和哈希键的底层实现之一,压缩列表可以包含多个节点,每个节点可以保存一个字节数组或整数值,添加新节点或删除节点可能引发连锁更新操作,这种操作出现几率不高。

到此这篇关于redis数据结构之压缩列表 的文章就介绍到这了,更多相关redis压缩列表 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • K8s部署Redis主从集群教程

    K8s部署Redis主从集群教程

    本文介绍了在Kubernetes环境下搭建Redis集群的详细步骤,包括环境准备、安装NFS、创建PV卷、搭建Redis集群、集群初始化、主从切换测试以及开放外网端口等内容
    2025-01-01
  • redis快速部署为docker容器的方法实现

    redis快速部署为docker容器的方法实现

    部署 Redis 作为 Docker 容器是一种快速、灵活且可重复使用的方式,特别适合开发、测试和部署环境,本文主要介绍了redis快速部署为docker容器的方法实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-05-05
  • Redis实现短信验证码登录的示例代码

    Redis实现短信验证码登录的示例代码

    本文主要介绍了基于Redis如何实现短信验证码登录功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Redis Cluster集群数据分片机制原理

    Redis Cluster集群数据分片机制原理

    这篇文章主要介绍了Redis Cluster集群数据分片机制原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • 基于Redis实现分布式锁以及任务队列

    基于Redis实现分布式锁以及任务队列

    这篇文章主要介绍了基于Redis实现分布式锁以及任务队列,需要的朋友可以参考下
    2015-11-11
  • Redis IP地址的绑定的实现

    Redis IP地址的绑定的实现

    这篇文章主要介绍了Redis IP地址的绑定的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • Redis妙用之存储用户token问题

    Redis妙用之存储用户token问题

    这篇文章主要介绍了Redis妙用之存储用户token问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Redis中有序集合的内部实现方式的详细介绍

    Redis中有序集合的内部实现方式的详细介绍

    本文主要介绍了Redis中有序集合的内部实现方式的详细介绍,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Redis 整数集合的具体使用(intset)

    Redis 整数集合的具体使用(intset)

    对于集合,STL 的 set 相信大家都不陌生,本文主要介绍了整数集合,又称为 intset,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Redis命令使用技巧之Keys的相关操作

    Redis命令使用技巧之Keys的相关操作

    Redis KEYS命令用于搜索具有匹配模式的键。下面这篇文章主要给大家介绍了关于Redis命令使用技巧之Keys的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
    2018-10-10

最新评论