当前位置: 首页 > article >正文

Redis的设计与实现(6)-压缩列表

压缩列表 (ziplist) 是列表键和哈希键的底层实现之一.当一个列表键只包含少量列表项, 并且每个列表项要么就是小整数值, 要么就是长度比较短的字符串, 那么 Redis 就会使用压缩列表来做列表键的底层实现.当一个哈希键只包含少量键值对, 并且每个键值对的键和值要么就是小整数值, 要么就是长度比较短的字符串, 那么 Redis 就会使用压缩列表来做哈希键的底层实现.1. 压缩列表的构成压缩列表是 Redis 为了节约内存而开发的, 由一系列特殊编码的连续内存块组成的顺序型 (sequential) 数据结构.一个压缩列表可以包含任意多个节点 (entry) , 每个节点可以保存一个字节数组或者一个整数值.压缩列表的整体布局:| zlbytes | zltail | zllen | entry | entry | entry... | zlend |字段名称类型占用空间备注zlbytesuint32_t4 字节记录整个压缩列表占用的内存字节数: 在对压缩列表进行内存重分配, 或者计算 zlend 的位置时使用.zltailuint32_t4 字节记录压缩列表表尾节点距离压缩列表的起始地址有多少字节: 通过这个偏移量程序无须遍历整个压缩列表就可以确定表尾节点的地址.zllenuint16_t2 字节记录了压缩列表包含的节点数量: 当这个属性的值小于 UINT16_MAX (65535)时, 这个属性的值就是压缩列表包含节点的数量; 当这个值等于 UINT16_MAX 时, 节点的真实数量需要遍历整个压 缩列表才能计算得出.entryX列表节点不定压缩列表包含的各个节点节点的长度由节点保存的内容决定.zlenduint8_t1 字节特殊值 0xFF (十进制 255 )用于标记压缩列表的末端.2 压缩列表节点的构成每个压缩列表节点可以保存一个字节数组或者一个整数值, 其中, 字节数组可以是以下三种长度的其中一种:长度小于等于 63 (2^{6}-1)字节的字节数组;长度小于等于 16383 (2^{14}-1) 字节的字节数组;长度小于等于 4294967295 (2^{32}-1)字节的字节数组;而整数值则可以是以下六种长度的其中一种:4 位长介于 0 至 12 之间的无符号整数;1 字节长的有符号整数;3 字节长的有符号整数;int16_t 类型整数;int32_t 类型整数;int64_t 类型整数.压缩列表节点的构成:| previous_entry_length | encoding | content |2.1 previous_entry_length节点的 previous_entry_length 属性以字节为单位, 记录了压缩列表中前一个节点的长度.previous_entry_length 属性的长度可以是 1 字节或者 5 字节:如果前一节点的长度小于 254 字节, 那么 previous_entry_length 属性的长度为 1 字节: 前一节点的长度就保存在这一个字节里面.如果前一节点的长度大于等于 254 字节, 那么 previous_entry_length 属性的长度为 5 字节: 其中属性的第一字节会被设置为 0xFE (十进制值 254), 而之后的四个字节则用于保存前一节点的长度.因为节点的 previous_entry_length 属性记录了前一个节点的长度, 所以程序可以通过指针运算, 根据当前节点的起始地址来计算出前一个节点的起始地址.压缩列表的从表尾向表头遍历操作就是使用这一原理实现的: 只要我们拥有了一个指向某个节点起始地址的指针, 那么通过这个指针以及这个节点的 previous_entry_length 属性, 程序就可以一直向前一个节点回溯, 最终到达压缩列表的表头节点.2.2 encoding节点的 encoding 属性记录了节点的 content 属性所保存数据的类型以及长度:一字节, 两字节或者五字节长, 值的最高位为 00 , 01 或者 10 的是字节数组编码: 这种编码表示节点的 content 属性保存着字节数组, 数组的长度由编码除去最高两位之后的其他位记录;一字节长, 值的最高位以 11 开头的是整数编码: 这种编码表示节点的 content 属性保存着整数值, 整数值的类型和长度由编码除去最高两位之后的其他位记录;编码编码长度content 属性保存的值00bbbbbb1 字节长度小于等于 63 字节的字节数组.01bbbbbb xxxxxxxx2 字节长度小于等于 16383 字节的字节数组.10__ aaaaaaaa bbbbbbbb cccccccc dddddddd5 字节长度小于等于 4294967295 的字节数组.编码编码长度content 属性保存的值110000001 字节int16_t 类型的整数.110100001 字节int32_t 类型的整数.111000001 字节int64_t 类型的整数.111100001 字节24 位有符号整数.111111101 字节8 位有符号整数.1111xxxx1 字节使用这一编码的节点没有相应的 content 属性, 因为编码本身的 xxxx 四个位已经保存了一个介于 0 和 12 之间的值, 所以它无须 content 属性.2.3 content节点的 content 属性负责保存节点的值, 节点值可以是一个字节数组或者整数, 值的类型和长度由节点的 encoding 属性决定.3. 连锁更新前面说过, 每个节点的 previous_entry_length 属性都记录了前一个节点的长度:如果前一节点的长度小于 254 字节, 那么 previous_entry_length 属性需要用 1 字节长的空间来保存这个长度值.如果前一节点的长度大于等于 254 字节, 那么 previous_entry_length 属性需要用 5 字节长的空间来保存这个长度值.如果 原有的节点都小于 254 字节, 突然间插入一个大于等于 254 字节, 压缩列表将会发生空间重分配(连锁更新);删除节点, 也会发生导致连锁更新.因为连锁更新在最坏情况下需要对压缩列表执行 N 次空间重分配操作, 而每次空间重分配的最坏复杂度为 O(N) , 所以连锁更新的最坏复杂度为 O(N^2).要注意的是, 尽管连锁更新的复杂度较高, 但它真正造成性能问题的几率是很低的:首先, 压缩列表里要恰好有多个连续的, 长度介于 250 字节至 253 字节之间的节点, 连锁更新才有可能被引发, 在实际中, 这种情况并不多见;其次, 即使出现连锁更新, 但只要被更新的节点数量不多, 就不会对性能造成任何影响: 比如说, 对三五个节点进行连锁更新是绝对不会影响性能的;因为以上原因, ziplistPush 等命令的平均复杂度仅为 O(N) , 在实际中, 我们可以放心地使用这些函数, 而不必担心连锁更新会影响压缩列表的性能.4. 压缩列表 API函数作用算法复杂度ziplistNew创建一个新的压缩列表。O(1)ziplistPush创建一个包含给定值的新节点 并将这个新节点添加到压缩列表的表头或者表尾。平均 O(N) 最坏 O(N^2) 。ziplistInsert将包含给定值的新节点插入到给定节点之后。平均 O(N) 最坏 O(N^2) 。ziplistIndex返回压缩列表给定索引上的节点。O(N)ziplistFind在压缩列表中查找并返回包含了给定值的节点。因为节点的值可能是一个字节数组 所以检查节点值和给定值是否相同的复杂度为 O(N) 而查找整个列表的复杂度则为 O(N^2) 。ziplistNext返回给定节点的下一个节点。O(1)ziplistPrev返回给定节点的前一个节点。O(1)ziplistGet获取给定节点所保存的值。O(1)ziplistDelete从压缩列表中删除给定的节点。平均 O(N) 最坏 O(N^2) 。ziplistDeleteRange删除压缩列表在给定索引上的连续多个节点。平均 O(N) 最坏 O(N^2) 。ziplistBlobLen返回压缩列表目前占用的内存字节数。O(1)ziplistLen返回压缩列表目前包含的节点数量。节点数量小于 65535 时 O(1) 大于 65535 时 O(N) 。因为 ziplistPush, ziplistInsert, ziplistDelete 和 ziplistDeleteRange 四个函数都有可能会引发连锁更新, 所以它们的最坏复杂度都是 O(N^2).5. 总结压缩列表是一种为节约内存而开发的顺序型数据结构.压缩列表被用作列表键和哈希键的底层实现之一.压缩列表可以包含多个节点每个节点可以保存一个字节数组或者整数值.添加新节点到压缩列表, 或者从压缩列表中删除节点, 可能会引发连锁更新操作, 但这种操作出现的几率并不高

相关文章:

Redis的设计与实现(6)-压缩列表

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

OpenClaw配置备份方案:GLM-4.7-Flash环境迁移与快速恢复

OpenClaw配置备份方案:GLM-4.7-Flash环境迁移与快速恢复 1. 为什么需要配置备份? 上周我的主力开发机突然硬盘故障,不得不紧急更换设备。当我准备在新电脑上重新部署OpenClaw时,突然意识到一个严重问题——过去三个月精心调试的…...

小白专属!Qwen2.5-7B离线推理,一步步教你搭建环境

小白专属!Qwen2.5-7B离线推理,一步步教你搭建环境 1. 前言:为什么选择Qwen2.5-7B? Qwen2.5-7B是阿里最新开源的大语言模型,相比前代版本有了显著提升。它特别适合中文场景,能帮你完成各种文本生成任务&am…...

DRAM命令真值表实战指南:如何正确理解L/H/V/X信号(DDR4为例)

DRAM命令真值表实战指南:如何正确理解L/H/V/X信号(DDR4为例) 在嵌入式系统开发中,DRAM的正确配置和操作是确保系统稳定性的关键。本文将深入解析DDR4 DRAM命令真值表中L(低电平)、H(高电平&…...

translategemma-4b-it实战落地:与Notion API联动实现笔记截图自动翻译归档

translategemma-4b-it实战落地:与Notion API联动实现笔记截图自动翻译归档 1. 项目背景与价值 你有没有遇到过这样的情况:阅读英文资料时截取了大量有价值的截图,但时间一长就忘记了内容,或者需要分享给团队时还要手动翻译&…...

BepInEx新手故障诊断与解决方案完全指南

BepInEx新手故障诊断与解决方案完全指南 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx 一、环境配置故障诊断:游戏启动无响应或闪退问题 影响范围说明 影响程度&…...

嵌入式机器人3-DOF运动学计算库:轻量级前向/逆向解算

1. 项目概述 Kinematics 是一个面向嵌入式机器人系统的轻量级运动学计算工具包,专为资源受限的微控制器平台(如基于 AVR 或 ARM Cortex-M0 的 Arduino 兼容开发板)设计。其核心目标并非替代工业级机器人控制库,而是提供一套 可直…...

告别依赖烦恼:在Kylin V10桌面版一键部署Qt 5.12.3开发环境(附离线包制作方法)

告别依赖烦恼:在Kylin V10桌面版一键部署Qt 5.12.3开发环境(附离线包制作方法) 在团队协作开发中,开发环境的标准化部署一直是个令人头疼的问题。特别是当项目需要迁移到国产化平台时,如何快速、高效地为整个团队搭建统…...

基于范德华外延氮化物剥离转印的研究

基于范德华外延氮化物剥离转印的研究 摘要 第三代半导体氮化物材料(GaN、AlN、InN及其合金)因其优异的物理性能在光电器件和功率电子领域具有重要应用。然而,氮化物异质外延面临的晶格失配与热失配问题,以及难以从生长衬底上剥离转移的困境,严重制约了其在柔性电子和异质…...

热键冲突排查完全指南:从症状到解决方案的系统方法论

热键冲突排查完全指南:从症状到解决方案的系统方法论 【免费下载链接】hotkey-detective A small program for investigating stolen hotkeys under Windows 8 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detective 问题诊断:识别热键冲…...

Ostrakon-VL-8B入门指南:5类典型失败提问模式纠正(模糊/歧义/超范围/多跳/隐含)

Ostrakon-VL-8B入门指南:5类典型失败提问模式纠正(模糊/歧义/超范围/多跳/隐含) 你是不是也遇到过这种情况:给一个看起来很聪明的AI模型上传了一张图片,问了一个自己觉得很简单的问题,结果它要么答非所问&…...

DTIIA 9.1.1、角形传动滚筒头架(槽钢)

图示 【主视图】 【侧视图】 【俯视图】 【Tip】滚筒与支架连接的紧固件(螺栓)已包括在本部件内。 组成 见下面 标准图 “120JA1072Q” 参数 (结合下面3张表) 【Y】传动滚筒中心 到 中间架焊接角钢 (带面角度&#…...

黑丝空姐-造相Z-Turbo风格迁移实验:从写实到动漫的多种可能

黑丝空姐-造相Z-Turbo风格迁移实验:从写实到动漫的多种可能 最近在玩一个挺有意思的AI图像模型,叫黑丝空姐-造相Z-Turbo。听名字你可能觉得它就是个生成特定风格图片的工具,但我发现它有个被低估的隐藏技能:风格迁移。简单说&…...

Phi-3-mini-128k-instruct企业应用:制造业BOM表语义解析与零部件替代建议生成

Phi-3-mini-128k-instruct企业应用:制造业BOM表语义解析与零部件替代建议生成 1. 引言:当BOM表遇上AI,制造业的智能升级新思路 如果你是制造业的从业者,一定对BOM表(物料清单)不陌生。这份看似简单的表格…...

DTII(A) 9.6、垂直拉紧装置架

描述垂直拉紧装置架,由改向滚筒X3、支座、导杆组成;示意图主视图侧视图K向:装置支座俯视图地脚螺栓【说明】参数表【表9-25】垂直拉紧装置架相关参数含:180改向滚筒、90改向滚筒、装置支座、导杆;详细数据:…...

OFA-33M蒸馏模型轻量化效果展示:边缘设备部署实测

OFA-33M蒸馏模型轻量化效果展示:边缘设备部署实测 最近在折腾边缘设备上的AI应用,发现一个挺有意思的问题:那些效果好的大模型,动不动就几百上千亿参数,在服务器上跑起来都费劲,更别说塞进一个小盒子里了。…...

Deep Research避坑指南:RAGFlow多Agent协作中的5个常见错误与优化技巧

RAGFlow多Agent深度研究实战:5个关键优化点与避坑策略 当技术团队首次接触RAGFlow的Deep Research功能时,往往会被其多Agent协作的潜力所吸引,但在实际部署中却容易陷入几个典型陷阱。本文将基于三个真实项目复盘数据,揭示那些文档…...

工业控制开发者必看:Xenomai 4实时性能调优与libevl实战解析

工业控制开发者必看:Xenomai 4实时性能调优与libevl实战解析 在工业自动化领域,毫秒级的响应延迟可能导致生产线停机,而微秒级的抖动则直接影响精密加工质量。传统Linux系统虽然功能强大,但其非确定性的调度机制难以满足硬实时需求…...

基于LSDYNA模拟的SPH方法:双水射流与单水射流冲击混凝土视频录制对比分析

视频录制 基于lsdyna的双水射流和单水射流冲击混凝土对比(sph方法)(开篇先甩个实际现象)混凝土被高压水射流冲得稀碎这事儿,本质上就是个暴力美学现场。最近在LS-DYNA里用SPH方法折腾双水射流和单水射流的对比,发现这玩意儿比单纯…...

SSD1357驱动RGB OLED 64×64显示库技术解析

1. SparkFun RGB OLED 6464 显示库技术解析1.1 硬件平台与驱动芯片架构SparkFun RGB OLED 6464 显示模块(SKU: SPX-14860)采用 WiseChip UG-6464TDDBG01 型 0.6 英寸全彩 OLED 面板,其核心驱动 IC 为 Solomon Systech SSD1357 —— 一款专为高…...

Lychee Rerank多语言支持实践:跨语言文档重排序案例

Lychee Rerank多语言支持实践:跨语言文档重排序案例 1. 多语言重排序的技术挑战 在全球化信息时代,跨语言文档检索已成为许多企业和组织的核心需求。想象一下,一家跨国公司需要从海量的中英文混合文档中快速找到相关信息,或者一…...

AnimatedDrawings技术故障排除指南:从安装到动画导出的系统解决方案

AnimatedDrawings技术故障排除指南:从安装到动画导出的系统解决方案 【免费下载链接】AnimatedDrawings Code to accompany "A Method for Animating Childrens Drawings of the Human Figure" 项目地址: https://gitcode.com/GitHub_Trending/an/Anima…...

从零开始在银河麒麟上配置Qt Creator:一步步教你搭建高效开发环境

从零开始在银河麒麟上配置Qt Creator:一步步教你搭建高效开发环境 在国产操作系统逐渐崛起的今天,银河麒麟作为一款安全可靠的操作系统,正受到越来越多开发者的关注。而Qt作为跨平台的C图形用户界面应用程序开发框架,其强大的功能…...

Oracle闪回功能实战:从误删数据到快速恢复的完整指南(附常见问题排查)

Oracle闪回技术深度实战:从原理到高阶恢复策略 在数据库运维的日常工作中,数据误操作如同悬在每位DBA头顶的达摩克利斯之剑。我曾亲眼见证一位资深工程师因误执行TRUNCATE命令导致核心业务表数据丢失时的手足无措,也经历过凌晨三点被紧急呼叫…...

文件上传漏洞全解析:从GIF89a到.phtml的攻防实战

文件上传漏洞攻防艺术:从GIF89a到.phtml的实战进阶指南 当你在社交媒体上传自拍时,系统会检查图片格式;当企业HR上传员工档案时,平台会验证文档类型。这些看似平常的文件校验机制背后,隐藏着网络安全领域最经典的攻防战…...

3步实现AI驱动3D建模:Wonder3D单图重建技术全解析

3步实现AI驱动3D建模:Wonder3D单图重建技术全解析 【免费下载链接】Wonder3D Single Image to 3D using Cross-Domain Diffusion 项目地址: https://gitcode.com/gh_mirrors/wo/Wonder3D 在数字内容创作领域,3D建模一直是技术门槛较高的环节&…...

Z-Image-Turbo-辉夜巫女惊艳生成:手持退魔弓、脚踏灵狐、周身结界光效的动态构图

Z-Image-Turbo-辉夜巫女惊艳生成:手持退魔弓、脚踏灵狐、周身结界光效的动态构图 1. 引言:当二次元幻想照进现实 你是否曾幻想过,那些存在于动漫、游戏或自己脑海中的奇幻角色,能够以高清、精美的图片形式跃然纸上?比…...

如何构建ESP32智能环境监测系统:5大核心特性深度解析

如何构建ESP32智能环境监测系统:5大核心特性深度解析 【免费下载链接】arduino-esp32 Arduino core for the ESP32 项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32 当我们在物联网时代谈论环境感知,是否曾思考过如何在资源受限…...

从0到1掌握GroundingDINO:突破性开放词汇目标检测实战指南

从0到1掌握GroundingDINO:突破性开放词汇目标检测实战指南 【免费下载链接】GroundingDINO 论文 Grounding DINO: 将DINO与基于地面的预训练结合用于开放式目标检测 的官方实现。 项目地址: https://gitcode.com/GitHub_Trending/gr/GroundingDINO Grounding…...

NSudo 终极指南:解锁Windows系统权限的完整教程

NSudo 终极指南:解锁Windows系统权限的完整教程 【免费下载链接】NSudo [Deprecated, work in progress alternative: https://github.com/M2Team/NanaRun] Series of System Administration Tools 项目地址: https://gitcode.com/gh_mirrors/nsu/NSudo 你是…...