Redis 跳跃列表与紧凑列表
Redis 跳跃列表(Skip List)
跳跃列表是一种高效的数据结构,它结合了有序数组和链表的优点,能够在 O(log n) 时间内进行插入、删除和查找操作。Redis 使用跳跃列表来实现有序集合(sorted set)的底层数据结构之一。
1. 跳跃列表的结构
跳跃列表由多个层级的链表组成,每一层都是一个有序链表。最低层包含所有元素,每一层都按一定概率跳过一些元素,从而减少查询路径的长度。
节点结构
每个节点包含以下几个部分:
- 值:节点存储的实际数据。
- 分数:用于排序的关键值。
- 前向指针数组:指向不同层级的下一个节点。
示意图:
Level 3: 1 ------> 6
Level 2: 1 --> 3 ------> 6 --> 9
Level 1: 1 --> 2 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8 --> 9
2. 跳跃列表的操作
插入操作
插入一个新元素时,首先需要找到插入位置。查找路径通过各层链表找到最接近的节点,然后插入新节点并更新前向指针数组。
示意图:
原始列表:
Level 3: 1 ------> 6
Level 2: 1 --> 3 ------> 6 --> 9
Level 1: 1 --> 2 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8 --> 9插入 4.5:
Level 3: 1 ------> 6
Level 2: 1 --> 3 ------> 6 --> 9
Level 1: 1 --> 2 --> 3 --> 4 --> 4.5 --> 5 --> 6 --> 7 --> 8 --> 9
删除操作
删除元素时,类似于插入操作,先找到要删除的节点,然后调整前向指针数组,移除该节点。
查找操作
查找操作利用各层链表加速定位目标元素,通过前向指针数组快速跳过无关节点,找到目标节点。
3. 跳跃列表的实现
Redis 中跳跃列表的实现主要包括以下几个结构体:
- zskiplistNode:跳跃列表节点结构,包含值、分数、前向指针数组等。
- zskiplist:跳跃列表结构,包含头节点、尾节点、节点数、最大层级等。
zskiplistNode 结构
typedef struct zskiplistNode {double score;robj *obj;struct zskiplistLevel {struct zskiplistNode *forward;unsigned long span;} level[];struct zskiplistNode *backward;
} zskiplistNode;
zskiplist 结构
typedef struct zskiplist {struct zskiplistNode *header, *tail;unsigned long length;int level;
} zskiplist;
4. Redis 中跳跃列表的应用
Redis 使用跳跃列表作为有序集合(sorted set)的一种实现方式(另一种实现是压缩列表,用于存储小数据量的有序集合)。跳跃列表提供了高效的插入、删除、查找和范围查询等操作,非常适合需要频繁更新和查询的有序集合。
5. 优点与缺点
优点
- 高效性:跳跃列表在插入、删除、查找等操作上都有 O(log n) 的时间复杂度,性能优越。
- 简单性:相比平衡树等复杂数据结构,跳跃列表实现相对简单,易于理解和维护。
缺点
- 空间消耗:由于需要维护多个层级的前向指针数组,跳跃列表的空间消耗相对较高。
- 概率性:跳跃列表的层级高度由随机算法决定,虽然平均性能优越,但在极端情况下可能出现性能不稳定的问题。
总结
跳跃列表是 Redis 中实现有序集合的一种高效数据结构。通过多层链表的设计,跳跃列表能够在保证高效查询的同时,提供较高的插入和删除性能。Redis 的跳跃列表实现结合了简单性和高效性,适用于各种需要有序存储和快速访问的数据场景。
Redis 紧凑列表(Ziplist)
Redis 5.0 又引入了一个新的数据结构 listpack,它是对 ziplist 结构的改进,在存储空间上会更加节省,而且结构上也比 ziplist 要精简。主要用于存储小规模的列表(list)和哈希表(hash)。紧凑列表通过一段连续的内存区域来存储多个元素,每个元素包含其值及其前一个元素的长度信息。
1. 紧凑列表的结构
紧凑列表由以下几个部分组成:
- zlbytes:紧凑列表所占用的总字节数。
- zltail:到最后一个元素的偏移量。
- zllen:紧凑列表包含的元素数量。
- entryX:列表中的元素(entry),每个元素包含其前一个元素的长度信息及其值。
- zlend:紧凑列表的结尾标记,固定为 0xFF。
示意图:
+--------+--------+--------+--------+--------+--------+--------+
| zlbytes| zltail | zllen | entry1 | entry2 | ... | zlend |
+--------+--------+--------+--------+--------+--------+--------+
2. 紧凑列表的元素结构
每个元素(entry)包含以下部分:
- prevlen:前一个元素的长度。
- encoding:当前元素的编码方式,决定了元素值的存储形式。
- value:当前元素的实际值,根据编码方式的不同,可以是整数或字符串。
元素示意图:
+--------+--------+--------+
| prevlen| encoding| value |
+--------+--------+--------+
3. 紧凑列表的操作
插入操作
插入一个新元素时,需要找到合适的位置,然后调整相应位置的偏移量和长度信息,将新元素插入到列表中。
示意图:
原始列表:
+--------+--------+--------+--------+--------+
| zlbytes| zltail | zllen | entry1 | zlend |
+--------+--------+--------+--------+--------+插入 entry2 后:
+--------+--------+--------+--------+--------+--------+
| zlbytes| zltail | zllen | entry1 | entry2 | zlend |
+--------+--------+--------+--------+--------+--------+
删除操作
删除一个元素时,需要找到该元素的位置,然后调整其前后元素的偏移量和长度信息,移除该元素。
示意图:
原始列表:
+--------+--------+--------+--------+--------+--------+
| zlbytes| zltail | zllen | entry1 | entry2 | zlend |
+--------+--------+--------+--------+--------+--------+删除 entry2 后:
+--------+--------+--------+--------+--------+
| zlbytes| zltail | zllen | entry1 | zlend |
+--------+--------+--------+--------+--------+
查找操作
查找元素时,需要遍历紧凑列表,依次比较每个元素的值,找到匹配的元素。
4. Redis 中紧凑列表的应用
紧凑列表在 Redis 中主要用于以下两种数据类型的底层实现:
- 列表(list):当列表元素数量较少或每个元素的长度较短时,Redis 使用紧凑列表来实现。
- 哈希表(hash):当哈希表中的键值对数量较少或每个键值对的长度较短时,Redis 使用紧凑列表来实现。
5. 优点与缺点
优点
- 节省内存:紧凑列表通过紧密排列的内存结构,显著减少了内存消耗。
- 较高的缓存命中率:由于紧凑列表在内存中是连续存储的,可以更好地利用 CPU 缓存,提高访问速度。
缺点
- 操作复杂:由于每次插入、删除操作需要调整多个元素的偏移量和长度信息,操作复杂度较高。
- 性能下降:当元素数量较多或元素长度较长时,紧凑列表的操作性能会显著下降。
总结
紧凑列表是一种高效的内存优化数据结构,适用于存储小规模列表和哈希表。通过紧密排列的内存结构,紧凑列表能够显著减少内存消耗,并提高缓存命中率。然而,由于操作复杂度较高,当数据规模增大时,紧凑列表的性能会受到一定影响。因此,在 Redis 中,紧凑列表主要用于存储小规模的数据,当数据规模增大时,Redis 会自动切换到其他更适合的数据结构,如双向链表或哈希表。
相关文章:
Redis 跳跃列表与紧凑列表
Redis 跳跃列表(Skip List) 跳跃列表是一种高效的数据结构,它结合了有序数组和链表的优点,能够在 O(log n) 时间内进行插入、删除和查找操作。Redis 使用跳跃列表来实现有序集合(sorted set)的底层数据结构…...
达梦数据库的系统视图v$arch_status
达梦数据库的系统视图v$arch_status 在达梦数据库(DM Database)中,V$ARCH_STATUS 是一个动态性能视图(Dynamic Performance View),用于显示归档日志的状态信息。这个视图可以帮助数据库管理员监控和管理数…...
【Rust光年纪】Rust 中常用的数据库客户端库:核心功能与使用场景
探秘 Rust 语言下的多种数据库客户端库:从安装到实际应用 前言 在现代的软件开发中,数据库是不可或缺的一部分。为了与数据库进行交互,开发人员需要使用各种数据库客户端来执行操作、构建查询等。本文将介绍一些用于 Rust 语言的常见数据库…...
网络安全防御【防火墙双机热备带宽管理综合实验】
目录 一、实验拓扑图 二、实验要求 三、实验思路: 四、实验步骤: 1、FW3的网络相关配置: 2、FW1的新增配置: 3、交换机LSW6(总公司)的新增配置: 4、双机热备技术配置(双机热…...
19.x86游戏实战-创建MFC动态链接库
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 工具下载: 链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…...
图论建模技巧搜集
一些经典题目 找可达路径 UVa - 11604 General Sultan 平面图最小割对偶图最短路 UVa - 1376 Animal Run 最小割建模 UVa - 1515 Pool construction 费用流建模 洛谷P3159 [CQOI2012] 交换棋子 一些可以转化为二分图最大权匹配的建模题 UVa1006/LA2238 Fixed Partition Me…...
pytorch学习(九)激活函数
1.pytorch常用激活函数如下: #ReLU激活函数 #Leaky ReLU激活函数 #Sigmoid激活函数 #Tanh激活函数 #Softmax激活函数 #Softplus2.代码 import torch.nn as nn import torch import numpy from torch.utils.tensorboard import SummaryWriterwriter SummaryWriter…...
conda 环境打包与使用
conda 环境导出 使用 Conda 打包环境,可以创建一个可重复使用的环境文件,便于在不同的机器上重新创建相同的环境。以下是具体的步骤: 1. 创建 Conda 环境 如果你还没有创建一个 Conda 环境,可以使用以下命令创建一个新环境&…...
jenkins 插件版本冲突
一、Jenkins安装git parameter 插件重启后报错与临时解决方案 cd /root/.jenkins cp config.xml config.xml.bak vim config.xml <authorizationStrategy class"hudson.security.FullControlOnceLoggedInAuthorizationStrategy"><denyAnonymousReadAcces…...
Python print() 格式化输出
Python print{} 格式化输出 1. print()2. 浮点数 (float)References 1. print() 传递给函数的值称为参数。 引号没有打印在屏幕上,它们只是表示字符串的起止,不是字符串的一部分。可以用这个函数在屏幕上打印出空行,只要调用 print() 就可以…...
【Qt+opencv】计时函数与图像变换
文章目录 前言计算时间函数图像变换旋转镜像缩放 总结 前言 在图像处理和计算机视觉的应用中,我们经常需要对图像进行各种变换,如旋转、缩放、剪切等。同时,为了评估算法的性能,我们也需要对代码的执行时间进行精确的测量。OpenC…...
nodejs下载+react安装
一、nodejs安装 1、nodejs下载 具体安装可参考连接:2023最新版Node.js下载安装及环境配置教程(非常详细)从零基础入门到精通,看完这一篇就够了_nodejs安装及环境配置-CSDN博客 下载地址:Node.js — 下载 Node.js 测…...
linux service小例
linux service 测试 1.创建一个app // myapp.c // 间隔10s写入时间到文件 #include <stdio.h> #include <time.h> #include <unistd.h> // 引入unix标准函数定义,如sleep()int main() {FILE *fp;time_t now;char buffer[80];// 打开文件以追加模…...
iOS 开发包管理之 Swift Package Manager
这是由官方推出,用于管理分发 swift 代码的工具。这个在 Xcode 是天然的存在,就是说我们不用安装就能够直接使用。 File > Add Package Dependencies… 在弹出来窗口选择一些库来导入 又或者点左下角的“” > Add Package Collection… 添加完成…...
【C语言初阶】C语言数组基础:从定义到遍历的全面指南
📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C语言 “ 登神长阶 ” 🤡往期回顾🤡:C语言函数 🌹🌹期待您的关注 🌹🌹 ❀数组 📒1. 什么是数组…...
AI开源战争的真相
引言 在AI技术迅猛发展的今天,开源与闭源之争成为了AI圈内最热的话题之一。大模型免费开放的背后到底隐藏着什么样的真相?这是一个令人困惑的问题。本文将深入探讨开源与闭源之争的历史背景、技术演进以及商业利益的博弈。 开源概念的起源 开源软件的…...
使用Java填充Word模板的技术详解
目录 概述常见的Java Word处理库 Apache POIAspose.Words for JavaDocx4j 使用Apache POI填充Word模板 创建和读取Word文档填充文本填充表格 使用Aspose.Words for Java填充Word模板 创建和读取Word文档填充文本填充表格 使用Docx4j填充Word模板 创建和读取Word文档填充文本填…...
vmware配置centos+配置静态ip联网+更换镜像
centos7配置参考【实战】VMware17虚拟机以及Centos7详细安装教程-CSDN博客 ip配置步骤: 先更改编辑虚拟网络编辑器中的内容 就按照还原默认设置来,设定后就是以上内容,然后一定要记住子网ip和子网掩码 接下来就是NAT设置: 网关…...
广州数据中心服务器搬迁方案
设备搬迁的准备工作涵盖资料准备、环境准备、计划细化等工作。资料准备主要是对旧机房的整理工作,对所搬运的设备进行资料整理,首先对每台设备建立基本情况、位置说明、系统关联性、搬迁批次及工作步骤等的设备档案,然后在档案资料收集完的基…...
uniapp开发钉钉小程序流程
下载开发工具 1、小程序开发工具 登录钉钉开发平台,根据自己的需求下载合适的版本,我这里下载的是Windows (64位)版本 小程序开发工具 - 钉钉开放平台 2、HBuilder X HBuilderX-高效极客技巧 新建项目及相关配置 新建项目 …...
流处理优化:提高实时数据处理性能
流处理优化:提高实时数据处理性能 一、流处理优化概述 1.1 流处理优化的定义 流处理优化是指通过优化流处理系统的性能、吞吐量和延迟,提高实时数据处理能力的过程。它涉及优化数据处理管道、资源配置和算法实现。 1.2 流处理优化的价值 低延迟ÿ…...
Avogadro 2:3分钟掌握跨平台分子建模的5大核心价值
Avogadro 2:3分钟掌握跨平台分子建模的5大核心价值 【免费下载链接】avogadroapp Avogadro is an advanced molecular editor designed for cross-platform use in computational chemistry, molecular modeling, bioinformatics, materials science, and related a…...
SeetaFace6实战:5分钟搞定实时视频流人脸检测(支持戴口罩识别,附完整C++/OpenCV代码)
SeetaFace6实战:5分钟构建高精度实时视频人脸检测系统(含口罩识别) 在智能安防、无接触门禁和远程医疗等场景中,实时人脸检测技术正发挥着越来越重要的作用。SeetaFace6作为中科视拓开源的最新版本人脸识别引擎,不仅将…...
靠谱的工程防火门公司推荐工程防火门
在工程行业摸爬滚打十几年,我见过太多因防火门翻车的项目:验收反复返工、产品用了两三年就变形卡死、超大门洞找不到厂家定制…… 这些看似鸡毛蒜皮的小事,一旦卡到消防验收节点上,轻则赔钱延期,重则被责令停工整改。今…...
航拍UAV电力电缆巡检检测数据集_数据集第10027期
航拍UAV电力电缆巡检检测数据集_数据集第10027期 项目简介 面向无人机电力巡检场景的开源目标检测数据集,聚焦电力电缆识别任务,可用于电力线检测、植被与电力线安全距离监测等场景,助力电力巡检智能化。 数据集核心信息 数据规模:…...
基于GAN的端到端ISP:用AI学习从RAW到RGB的图像处理革命
1. 项目概述:从“拍”到“算”的ISP革命在计算机视觉和图像处理领域,图像信号处理器(ISP)一直扮演着“幕后英雄”的角色。它负责将相机传感器捕捉到的原始、未经处理的RAW Bayer数据,转换为我们手机相册里那些色彩鲜艳…...
混元图像3.0对话P图技术解析:本地化可控生成新范式
1. 项目概述:这不是又一个“AI修图”功能,而是本地化P图工作流的临界点“腾讯混元图像3.0图生图模型上线,元宝也支持对话P图啦!”——这句话在科技圈刷屏那天,我正用本地部署的Stable Diffusion给客户改第十版电商主图…...
STC8H8K64U单片机IAP升级实战:从官方例程到自定义协议的完整移植指南
STC8H8K64U单片机IAP升级实战:从官方例程到自定义协议的完整移植指南 在嵌入式系统开发中,固件升级是一个永恒的话题。想象一下这样的场景:你的设备已经部署在客户现场,突然发现了一个需要紧急修复的Bug,或者需要增加新…...
CodeBuddy ai对话框上面的git docs terminal Rulds 干嘛用的,以thinkphp fastadmin 为例,插件市场
CodeBuddy(或同类 AI 编程助手)里的**「上下文注入(Context Injection)」功能模块**,作用是把项目/环境信息喂给 AI,让它“看得懂你的项目”,而不是凭空瞎编代码。 插件市场###ai对对话框 逐个拆…...
基于OpenClaw构建开源项目与Docker镜像自动化监控方案
1. 项目概述 作为一个常年泡在开源社区和容器生态里的开发者,我深知“追新”的痛。今天这个项目发布了v2.0,明天那个镜像更新了安全补丁,手动去GitHub和Docker Hub一个个检查,效率低不说,还容易遗漏关键更新。为了解决…...
