redis 从0到1完整学习 (七):ZipList 数据结构

文章目录

  • 1. 引言
  • 2. redis 源码下载
  • 3. zipList 数据结构
    • 3.1 整体
    • 3.2 entry 数据结构分析
    • 3.3 连锁更新
  • 4. 参考


1. 引言

前情提要:
《redis 从0到1完整学习 (一):安装&初识 redis》
《redis 从0到1完整学习 (二):redis 常用命令》
《redis 从0到1完整学习 (三):redis 数据结构》
《redis 从0到1完整学习 (四):字符串 SDS 数据结构》
《redis 从0到1完整学习 (五):集合 IntSet 数据结构》
《redis 从0到1完整学习 (六):Hash 表数据结构》
本文主要结合源码来介绍 ZipList 的数据结构

2. redis 源码下载

Redis 源码可以点击这里下载,方便查看其中定义的一些数据结构。
在这里插入图片描述

3. zipList 数据结构

3.1 整体

zipList 是为了提高存储效率而设计的一种特殊编码的双向链表,由一系列特殊编码的连续内存块组成。可以在任意一端进行 push 和 pop 操作,并且该操作的时间复杂度为 O(1)。它可以存储字符串或者整数,存储整数时是采用整数的二进制而不是字符串形式存储。

zipList 数据结构示意图:
在这里插入图片描述

名称类型size用途
zlbytesuint32_t4 字节记录整个 zipList 占用的字节总数,即图中 zlbytes 的起始 到 zlend 的末尾
zltailuint32_t4 字节记录 zipList 尾节点距离起始地址有多少字节,即图中 zlbytes 起始 到 tail 起始的偏移量,通过这个偏移量,可以确定尾节点的地址
zllenuint16_t2 字节记录了压缩列表包含的节点数量。 最大值为 UINT16_MAX (65534)。如果超过这个值,会记录为65535。
entry不定压缩列表包含的各个节点,节点的长度由节点保存的内容决定。
zlenduint8_t1 字节特殊值 0xFF (十进制 255 ),用于标记压缩列表的末端。

3.2 entry 数据结构分析

ziplist 中的每个 entry 都以包含两条信息的元数据作为前缀。首先,存储上一个 entry 的长度,以便能够从后向前遍历列表。其次,提供 entry encoding,表示 entry 类型,整数或字符串,如果是字符串,它还表示字符串有效负载的长度。因此,完整的 entry 存储如下:
在这里插入图片描述

  • prevlen:前一个 entry 的长度,占1个或5个字节。
    • 如果前一个 entry 的长度 < 254字节,则采用1个字节来保存这个长度值
    • 如果前一个 entry 的长度 > 254字节,则采用5个字节来保存这个长度值,第一个字节为 0xfe,后四个字节才是真实长度数据
  • encoding:编码属性,记录数据类型(字符串还是整数)以及长度,占用1个、2个或5个字节
  • entry-data:负责保存 entry 数据,可以是字符串或整数

根据 redis 源码的注解来看,encoding 的编码如下:
(1)字符串编码

encoding 格式编码长度字符串大小
|00pppppp|1 bytes<= 63 bytes
|01pppppp|qqqqqqqq|2 bytes<= 16383 bytes
|10000000|qqqqqqqq|rrrrrrrr|ssssssss|tttttttt|5 bytes<= 4294967295 bytes

例如,下面保存 abbc 字符串示例:

 *  [13 00 00 00] [0e 00 00 00] [02 00] [00 02 61 62] [04 02 62 63] [ff]
 *        |             |          |       	  |       	    |     	 |
 *     zlbytes        zltail     zllen       "ab"         "bc"     end
 * 

a 的 ASCII 码是97,对应的16进制是61
b 的 ASCII 码是98,对应的16进制是62
c 的 ASCII 码是99,对应的16进制是63
ab 的编码是 6162,长度是2字节,所以 encoding 是 00000010 即 16进制02,而前一个 entry 不存在,因而 prevlen 为 0,所以 ab 编码为 00026162;同样的 bc 前一个 entry 为 ab,字节一共为4,所以 bc 编码为 04026263

(2)数字编码

encoding 格式编码长度整数类型
110000001int16_t(2 bytes)
110100001int32_t(4 bytes)
111000001int64_t(8 bytes)
11110000124位有符整数(3 bytes)
1111111018位有符整数(1 bytes)
1111xxxx1在xxxx位置保存数值,范围从0001~1101,减1后结果为实际值

例如,下面是 redis 源码给出的保存 25 整数示例:

 *  [0f 00 00 00] [0c 00 00 00] [02 00] [00 f3] [02 f6] [ff]
 *        |             |          |       |       |     |
 *     zlbytes        zltail     zllen    "2"     "5"   end
 * 

2 的长度在 0001~1101,对应上面表格的最后一种,所以 encoding 为 11110011,即16进制的 f3 (这里的3,实际为2+1);同样 5 encoding 为 11110110,即 f6

3.3 连锁更新

zipList 的每个 entry 都包含 prevlen 来记录上一个节点的大小,长度是1个或5个字节:

  • 如果前一节点的长度 < 254字节,则采用1个字节来保存这个长度值
  • 如果前一节点的长度 >= 254字节,则采用5个字节来保存这个长度值,第一个字节为0xfe,后四个字节才是真实长度数据

当一种边界场景下,插入了一个 entry,entry 的大小超过了 254 字节,导致后续大范围的 entry 的 prevlen 由1字节转为用5个字节来保存,触发了连锁更新,同时删除也可能触发连锁更新。

4. 参考

《redis 从0到1完整学习 (一):安装&初识 redis》
《redis 从0到1完整学习 (二):redis 常用命令》
《redis 从0到1完整学习 (三):redis 数据结构》
《redis 从0到1完整学习 (四):字符串 SDS 数据结构》
《redis 从0到1完整学习 (五):集合 IntSet 数据结构》
《redis 从0到1完整学习 (六):Hash 表数据结构》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/272323.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

让马达转动起来(motor)

代码&#xff1a; #include "reg51.h"sbit P2_0 P2^0; sbit P2_7 P2^7;void main(){while(1){P2_0 1;P2_7 0;} } 仿真&#xff1a; 介绍&#xff1a; 当2.0和2.7端口均为低电平或高电平时&#xff0c;马达保持不转动&#xff1b; 当2.0和2.7端口分别为高电平和…

数据库开发之内连接和外连接的详细解析

1.2 内连接 内连接查询&#xff1a;查询两表或多表中交集部分数据。 内连接从语法上可以分为&#xff1a; 隐式内连接 显式内连接 隐式内连接语法&#xff1a; select 字段列表 from 表1 , 表2 where 条件 ... ; 显式内连接语法&#xff1a; select 字段列表 …

ElasticSearch之RestClient笔记

1. ElasticSearch 1.1 倒排索引 1.2 ElasticSearch和Mysql对比 1.3 RestClient操作 导入依赖 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.15.…

带大家做一个,易上手的家常辣椒炒香肠

搞两根香肠 我这里选择的哈尔滨红肠 切成片 打开下图这么大块姜 三瓣蒜 姜蒜切小片 三分之一个大葱 切段 一个螺丝椒 螺丝椒切片 起锅烧油 下葱姜蒜翻炒 翻炒一会儿 然后下入螺丝椒 翻炒出辣椒的辣味后 倒入一勺生抽调味 翻炒均匀后下入香肠 翻炒个几分钟 就可以放入…

Github项目推荐:快写鸭

项目地址 GitHub - oncework/kuaixieya: 「快写鸭」是一款专为开发者开发的一站式写作、管理、发布的更简单且下载即用的效率工具&#xff0c;去除繁琐配置但又极具丰富且自定义性质等功能。 项目简介 这是一个多平台的内容分发工具。可以用来加快博文的多平台发布。 项目截…

jar 运行清单文件MANIFEST.MF生成定义Main-Class Premain-Class IDEA maven-assembly-plugin

可运行jar文件中的启动清单文件 META-INF/MANIFEST.MF 内容自定义生成 清单文件中的 Main-Class: Premain-Class: Can-Retransform-Classes: 在maven-assembly-plugin插件中的生成配置如下, 注意命名 <archive> <manifest> <mainClass>c…

记一次接口交互is开头的属性序列化后“is”丢失问题

问题背景&#xff1a; 今天在做项目联调时调用别人的第三方接口时&#xff0c;发现字段传递不对导致参数传递异常的问题&#xff0c;当时还很奇怪&#xff0c;明白传好着呢&#xff0c;怎么就好端端的出现字段不对的情况呢&#xff1f; 查看发现该字段为boolean类型的isIsRef…

龙蜥开源操作系统能解决CentOS 停服造成的空缺吗?

龙蜥开源操作系统能解决CentOS 停服造成的空缺吗&#xff1f; 本文图片来源于龙蜥&#xff0c;仅做介绍时引用用途&#xff0c;版权归属龙蜥和相关设计人员。 一、《国产服务器操作系统发展报告&#xff08;2023&#xff09;》称操作系统已步入 2.0 时代&#xff0c;服务器操作…

【C语言刷题每日一题】一维数组的交换

目录 问题描述 思路分析 代码实现 结果测试 问题描述 将两个整型一维数组的元素进行交换 如果两个数组长度相同就全部交换&#xff1b; 如果两个数组长度不同&#xff0c;则交换长度相同部分的元素 思路分析 为了代码的复用&#xff0c;这里通过函数来实现&#xff0c;…

【QML-对话框】

QML编程指南 VX&#xff1a;hao541022348 弹出类DialogDrawerFileDialog文件对话框 &#x1f3b3;FontDialog字体对话框 &#x1f6b4;ColorDialog 颜色对话框 &#x1f3ca;MessageDialog 消息提示框 &#x1f429; 弹出类 Dialog 对话框是一种弹出式对话框&#xff0c;主要…

4.13 构建onnx结构模型-Conv

前言 构建onnx方式通常有两种&#xff1a; 1、通过代码转换成onnx结构&#xff0c;比如pytorch —> onnx 2、通过onnx 自定义结点&#xff0c;图&#xff0c;生成onnx结构 本文主要是简单学习和使用两种不同onnx结构&#xff0c; 下面以 Conv 结点进行分析 方式 方法一…

蓝桥杯的学习规划

c语言基础&#xff1a; Python语言基础 学习路径&#xff1a;画框的要着重学习

补题与总结:leetcode第 377 场周赛

文章目录 写在最前面的复盘2977. 转换字符串的最小成本 II&#xff08;Flody 爆搜优化->dp&#xff09; 写在最前面的复盘 感谢leetcode&#xff0c;丰富了我为数不多的卡常经验 2是简单思维题&#xff0c;但卡常 4是爆搜优化&#xff0c;也卡常&#xff0c;补题时给卡麻了…

腾讯NCNN环境部署及pt到ncnn模型转换推理

该内容还未完整&#xff0c;笔记内容&#xff0c;后期补充。 一、模型转换 yolov5s v6.2训练的pt模型&#xff0c;直接导tourchscript&#xff0c;然后时候ncnn里面的pnnx工具直接转换为ncnn 二、部署环境 1.安装vunlkan 1.2.198.1版本&#xff0c;记得配置环境变量 2.安装…

SSH远程登陆服务器

截取自文章&#xff1a;SSH简介及两种远程登录的方法_ssh -CSDN博客 SSH的安装 SSH分为客户端 openssh-client 和服务器 openssh-server&#xff0c;可以利用以下命令确认电脑上是否安装了客户端和服务器。 dpkg -l | grep ssh 如果只是想远程登陆别的机器只需要安装客户端&…

【Web API系列】使用getDisplayMedia来实现录屏功能

文章目录 前言一、认识getD该处使用的url网络请求的数据。二、使用步骤1.使用方法一实现录屏2.使用方法二实现录屏3. 运行效果 延伸 前言 Web API经过长期的发展&#xff0c;尤其是最近&#xff0c;发展相当迅猛&#xff0c;现在已经支持很多功能了&#xff0c;一些原生就支持…

IDEA相关操作

目录 连接MySQL IDEA配置Maven 配置全局Maven 导入Maven项目 方法一 方法二 安装Mybatisx插件 连接MySQL 填写user和Password之后测试连接 如果是第一次连接需要联网下载数据库连接驱动&#xff0c;安装提示下载即可 如果显示如下错误需要更改时区 Server returns …

虚拟机安装windows2012和虚拟机安装国产系统deepin

虚拟机安装windows2012和虚拟机安装国产系统deepin 一.安装windows20121.安装VMWare虚拟机2.1.注意点一&#xff1a;VMWare虚拟网卡2.2.注意点二&#xff1a;配置虚拟网络编辑器3.安装配置Windows Server 2012 R23.1激活windows121.利用下面两个文件进行windows激活2.运行exe文…

5G NR无线蜂窝系统的信道估计器设计

文章目录 DMRS简介DMRS类型DMRS频域密度 信道估计实验仿真实验参数实验实验结论 DMRS简介 DMRS类型 类型A&#xff1a;DMRS位于时隙的第二个或第三个OFDM符号&#xff0c;由14个OFDM符号组成&#xff0c;当数据占据大部分时隙时使用A型映射。 类型B&#xff1a;用在URLLC中&a…

Linux 学习

复制/etc 文件夹到/mnt 目录 cp -r(-a) /etc /mnt回到上一次文件夹 cd -切换到当前用户的家目录_cd ~________________________如何查找ls 命令的位置_______which ls_________________________________请写出ll 命令中查看到的7大文件类型缩写 - s l p c b …