`

整数集合与压缩列表

阅读更多
    在 Redis 中,当一个普通集合类型只包含整数值元素,并且元素数量不多时,就会使用整数集合(intset)作为集合键的底层实现,它可以保存类型为 int16_t、int32_t 或者 int64_t 的整数值,并且不会重复。这可通过类似下面的命令来看出。
redis> SADD nums 1 3 5 7 9 3 7
(integer)5
redis> OBJECT ENCODING nums
"intset"

    整数集合在 Redis 中的结构定义如下。
typedef struct intset{
    uint32_t encoding;        // 编码方式
    uint32_t length;          // 集合中包含的元素数量
    int8_t contents[];        // 按从小到大的顺序保存元素的底层数组
}intset;

    其中要注意的是,尽管 contents 字段申明为 int8_t 类型,但实际上它并不保存任何 int8_t 类型的值,保存的值的真正类型完全取决于 encoding 属性的值:
    1、如果 encoding 的值为 INTSET_ENC_INT16,则 contents 是一个 int16_t 类型的数组。
    2、如果 encoding 的值为 INTSET_ENC_INT32,则 contents 是一个 int32_t 类型的数组。
    3、如果 encoding 的值为 INTSET_ENC_INT64,则 contents 是一个 int64_t 类型的数组。
    因此,当某个时候新添加的元素的数值范围超出了当前集合的 encoding 属性对应的类型所能表示的范围时,就需要对该整数集合进行升级操作后再添加新元素,这个过程涉及的步骤如下:
    1、根据新元素的类型扩展整数集合底层数组的空间大小。
    2、将原来的元素的类型都转换成新元素的类型,并将它们按原来的大小顺序放到扩展后的空间对应的位上。
    3、将新元素添加到底层数组中合适的位置(要么放在最开头,要么放在最末尾)。
    4、修改 encoding 属性的值,并将 length 属性的值自增 1。
    整数集合一经升级,之后就不能再降级了。

    压缩列表(ziplist)是 Redis 为节约内存而开发,它是由一系列特殊编码的连续内存块组成的顺序型数据结构。
    列表键和哈希键的底层实现都用到了压缩列表。当一个列表键只包含少量列表项,并且每项要么是小整数值,要么是较短的字符串,或者当一个哈希键只包含少量键值对,并且每一个键值对要么是小整数值,要么是较短的字符串时,Redis 就会使用压缩列表来做列表键或者哈希键的底层实现。这两种情况都可分别用“OBJECT ENCODING”命令来验证。
    一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值。下图展示了压缩列表的各个组成部分和说明。

    为理解这些部分,假设有下图这样一个压缩列表示例。

    其中,
    * 属性 zlbytes 的值为 0x50,表示压缩列表的总长为 80 字节。
    * 属性 zltail 的值为 0x3c,表示若指针 p 指向压缩列表的起始地址,则使用 p + 60 即可计算出表尾节点 entry3 的地址。
    * 属性 zllen 的值为 0x3,表示压缩列表包含 3 个节点。
    接下来再来说说压缩列表节点的构成。
    每个压缩列表节点可以保存一个字节数组或者一个整数值,其中,字节数组的长度可以是以下三种长度的其中之一:
    1、小于等于 63(2^6 - 1)字节。
    2、小于等于 16 383(2^14 - 1)字节。
    3、小于等于 4 294 967 295(2^32 - 1)字节。
    而整数值则可以是以下六种长度的其中一种:
    1、4 位长、介于 0 至 12 之间的无符号整数。
    2、1 字节长的有符号整数。
    3、3 字节长的有符号整数。
    4、int16_t 类型整数。
    5、int32_t 类型整数。
    6、int64_t 类型整数。
    每个节点都由 previous_entry_length、encoding 和 content 三个部分组成,其中:
    * previous_entry_length 属性的长度可以是 1 字节或者 5 字节,它记录了压缩列表中前一个节点的长度。如果前一节点的长度小于 254 个字节,则该属性的长度为 1 字节,否则为 5 字节(其中第一字节会被设置成 0xFE(十进制 254),之后的 4 个字节则用于保存前一节点的长度)。根据该性质,程序可以根据当前节点的起始地址来计算出前一个节点的起始地址,压缩列表的从表尾向表头遍历操作就是使用这一原理实现的。
    * encoding 属性记录了节点的 content 属性所保存数据的类型以及长度。它有以下两种情况:
    1、1 字节、2 字节或者 5 字节长,值的最高位为 00、01 或者 10 的是字节数组编码,表示该节点的 content 属性保存着字节数组,数组的长度由除去最高两位之后的其他位记录。
    2、1 字节长,值的最高位以 11 开头的是整数编码,表示 content 属性保存着整数值,整数值的类型和长度由编码除去最高两位之后的其他位记录。
    下面两张表分别记录了可用的字节数组和整数编码。

    * content 属性负责保存节点的值,节点值可以是字节数组或者整数,其类型和长度由 encoding 属性决定。
    下图展示了一个保存字节数组的节点示例:

    其中,属性 previous_entry_length 的值为 0xFE00002766,最高位字节 0xFE 表示它占用五个字节,之后的四个字节 0x00002766(十进制 10086)才是前一节点的实际长度。属性 encoding 的最高两位 00 表示节点保存的是一个字节数组,后六位 001011 表示该数组的长度是 11。属性 content 保存着节点的值“hello world”。
    此外,由于 previous_entry_length 属性的长度与前一个节点的长度是否小于 254 字节有关,因此当一个压缩列表中存在多个连续的、长度介于 250 字节到 253 字节之间的节点 e1 至 eN 时,如果在 e1 之前插入了一个长度大于 254 字节的新节点,将迫使程序对压缩列表执行空间重分配操作,以将 e1 节点的 previous_entry_length 属性从原来的 1 字节长扩展为 5 字节长,而新增的四个字节又造成 e1 节点的长度变成了介于 254 字节到 257 字节之间,这进而又需要扩展 e2 节点的 previous_entry_length 属性长度,如此下去直到 eN。
    这种在特殊情况下产生的连续多次空间扩展操作在 Redis 中就被称为“连锁更新”(cascade update)。除添加新节点外,删除节点也可能会引发连锁更新。由于连锁更新在最坏情况下需要对压缩列表执行 N 次空间重分配操作,而每次空间重分配的最坏复杂度为 O(N),因此连锁更新的最坏复杂度为 O(N^2)。幸运的是,尽管连锁更新的复杂度较高,但由于其条件特殊,实际中它真正造成性能问题的几率其实是很低的。

参考书籍:
1、《Redis 的设计与实现》第 6 章——整数集合。
2、《Redis 的设计与实现》第 7 章——压缩列表。
  • 大小: 153.6 KB
  • 大小: 21.2 KB
  • 大小: 157.1 KB
  • 大小: 19 KB
分享到:
评论

相关推荐

    基于java网上球鞋竞拍系统设计与实现.docx

    基于java网上球鞋竞拍系统设计与实现.docx

    基于bert实现关系三元组抽取python源码+数据集+项目说明.zip

    基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip 个人大四的毕业设计、课程设计、作业、经导师指导并认可通过的高分设计项目,评审平均分达96.5分。主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 [资源说明] 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设或者课设、作业,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96.5分,放心下载使用! 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),供学习参考。

    基于java的足球赛会管理系统设计与实现.docx

    基于java的足球赛会管理系统设计与实现.docx

    基于java的婚纱摄影网的设计与实现.docx

    基于java的婚纱摄影网的设计与实现.docx

    基于安卓的美颜相机,可以通过opencv加滤镜,并调整亮度和对比度,可以磨皮,但并不能瘦脸,磨皮时非常卡顿,暂无解决方法.zip

    项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    基于java的农产品仓库管理系统系统设计与实现.docx

    基于java的农产品仓库管理系统系统设计与实现.docx

    基于Java swing +mysql(Oracle)实现的飞机订票系统项目(含毕业论文+答辩 ppt+双数据库版本源码+图)

    【作品名称】:基于Java swing +mysql(Oracle)实现的飞机订票系统项目(含毕业论文+答辩 ppt+双数据库版本源码) 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】: 系统功能需求 本系统用于远程机票预订,包括远程航班信息查询、机票预订与确认等;主要分为四大功能:查询、订票、退票和管理。 管理员登录、注销 到系统并进行插入、删除、更新以及查看机票后台数据库操作 插入:机票的插入可以按照航班号、班期、公司、座位号、起飞地以及抵达地等等插入数据库。 删除:机票可以按照航班号、起止城市、星期进行删除 3.1.1客户端系统功能 1.普通用户: 查询:根据航班号、航空公司以及目的地查询出票类信息 订票: 根据出发日期和第一航班号预订机票,机票类型分为单 【资源声明】:本资源作为“参考资料”而不是“定制需求”,代码只能作为参考,不能完全复制照搬。不一定能够满足所有人的需求,需要有一定的基础能够看懂代码,能够自行调试代码并解决报错,能够自行添加功能修改代码。

    2018信基广场“红动佛山”春节新媒体营销方案.pptx

    2018信基广场“红动佛山”春节新媒体营销方案.pptx

    #_ssm_100_mysql_基于智慧医疗预约挂号管理系统_.zip

    均包含代码,文章,部分项目包含ppt

    基于java的蜀都天香酒楼的网站设计与实现.docx

    基于java的蜀都天香酒楼的网站设计与实现.docx

    java基于ssm+vue 医院疫情防控管理系统源码 带毕业论文+ppt+sql

    1、开发环境:SSM框架;内含Mysql数据库;VUE技术;内含说明文档 2、项目代码都经过严格调试,代码没有任何bug! 3、该资源包括项目的全部源码,下载可以直接使用! 4、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 5、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。

    基于java的英语单词学习网站设计与实现.docx

    基于java的英语单词学习网站设计与实现.docx

    基于java企业销售人员培训系统设计与实现.docx

    基于java企业销售人员培训系统设计与实现.docx

    2019优益C x 易烊千玺微博营销案结案报告.pptx

    2019优益C x 易烊千玺微博营销案结案报告.pptx

    基于java的单位人事管理系统设计与实现.docx

    基于java的单位人事管理系统设计与实现.docx

    java-ssm+vue图书管理系统实现源码(项目源码-说明文档)

    该网站采用SSM框架和Eclipse编辑器、MySQL数据库设计并实现的。网站功能包含系统用户管理、图书管理、用户管理、借书管理、续借管理、违章缴款管理等模块。 首页是网站的入口,主要包含了:新闻信息、图书信息等导航功能。 用户有独立的注册界面,用户填写好注册信息后,会有个一审核的过程,经过管理员审核注册成功,并将注册的信息加入用户表中。 项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7+ 后端技术:ssm 前端技术:Vue 关键技术:springboot、SSM、vue、MYSQL、MAVEN 数据库工具:Navicat、SQLyog

    我的网页设计部署.zip(毕设&课设&实训&大作业&竞赛&项目)

    项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    信息系统项目管理师考试集锦.zip

    项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    【单变量输入多步预测】基于TCN-GRU-Attention的风电功率预测研究附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    docker安装部署gorse

    docker安装部署gorse

Global site tag (gtag.js) - Google Analytics