Redis数据结构——QuickList、SkipList、RedisObjective

2023-11-13

承接上文,本文主要介绍QuickList、SkipList、RedisObjective

四、 Redis数据结构-QuickList

问题1:ZipList虽然节省内存,但申请内存必须是连续空间,如果内存占用较多,申请内存效率很低。怎么办?

​ 答:为了缓解这个问题,我们必须限制ZipList的长度和entry大小。

问题2:但是我们要存储大量数据,超出了ZipList最佳的上限该怎么办?

​ 答:我们可以创建多个ZipList来分片存储数据。

问题3:数据拆分后比较分散,不方便管理和查找,这多个ZipList如何建立联系?

​ 答:Redis在3.2版本引入了新的数据结构QuickList,它是一个双端链表,只不过链表中的每个节点都是一个ZipList。
在这里插入图片描述

为了避免QuickList中的每个ZipList中entry过多,Redis提供了一个配置项:list-max-ziplist-size来限制。
如果值为正,则代表ZipList的允许的entry个数的最大值
如果值为负,则代表ZipList的最大内存大小,分5种情况:

  • -1:每个ZipList的内存占用不能超过4kb。
  • -2:每个ZipList的内存占用不能超过8kb。
  • -3:每个ZipList的内存占用不能超过16kb。
  • -4:每个ZipList的内存占用不能超过32kb。
  • -5:每个ZipList的内存占用不能超过64kb。

其默认值为 -2:
在这里插入图片描述

以下是QuickList的和QuickListNode的结构源码:

typedef struct quicklist {
    //头节点指针
	quicklistNode *head;
    //尾节点指针
	quicklistNode *tail;
	//所有ziplist的entry的数量
    unsigned long count;l
    //ziplists总数量
	unsigned long len;
	//ziplist的entry上限,默认值-2
    int fill : QL_FILL_BITS;
	//首尾不压缩的节点数量
	unsigned int compress : QL_COMP_BITS;
    //内存重分配时的书签数量及数组,一般用不到
    unsigned int bookmark_count: QL_BM_BITS;
    quicklistBookmark bookmarks[;
} quicklist;

typedef struct quicklistNode {
    //前一个节点指针
	struct quicklistNode *prev;
    //下一个节点指针
	struct quicklistNode *next;
    //当前节点的ZipList指针
    unsigned char *zl;
	//当前节点的ZipList的字节大小
    unsigned int sz;
	//当前节点的ZipList的entry个数
    unsigned int count : 16;
	//编码方式:1,ZipList; 2,Izf压缩模式
    unsigned int encoding : 2;
	//数据容器类型(预留): 1,其它;2,ZipListunsigned 
    int container : 2;
	//是否被解压缩。1︰则说明被解压了,将来要重新压缩
    unsigned int recompress : 1;
	unsigned int attempted_compress : 1;//测试用
    unsigned int extra : 10;/*预留字段*/
} quicklistNode;
                            

我们接下来用一段流程图来描述当前的这个结构

在这里插入图片描述

总结:

QuickList的特点:

  • 是一个节点为ZipList的双端链表。
  • 节点采用ZipList,解决了传统链表的内存占用问题。
  • 控制了ZipList大小,解决连续内存空间申请效率问题。
  • 中间节点可以压缩,进一步节省了内存。

五、 Redis数据结构-SkipList

SkipList(跳表)首先是链表,但与传统链表相比有几点差异:

  • 元素按照升序排列存储。
  • 节点可能包含多个指针,指针跨度不同。

在这里插入图片描述

//t_zset.c
typedef struct zskiplist {
    //头尾节点指针
	struct zskiplistNode *header, *tail;
    //节点数量
	unsigned long length;
	//最大的索引层级,默认是1
    int level;
}zskiplist;

typedef struct zskiplistNode {
    sds ele; //节点存储的值
	double score;//节点分数,排序、查找用
	struct zskiplistNode *backward;//前一个节点指针
    struct zskiplistLevel {
		struct zskiplistNode *forward;//下—个节点指针
        unsigned long span;//索引跨度
	} leveli;//多级索引数组
} zskiplistNode;

在这里插入图片描述

小总结:

SkipList的特点:

  • 跳跃表是一个双向链表,每个节点都包含score和ele值。
  • 节点按照score值排序,score值一样则按照ele字典排序。
  • 每个节点都可以包含多层指针,层数是1到32之间的随机数。
  • 不同层指针到下一个节点的跨度不同,层级越高,跨度越大。
  • 增删改查效率与红黑树基本一致,实现却更简单。

六、Redis数据结构-RedisObject

Redis中的任意数据类型的键和值都会被封装为一个RedisObject,也叫做Redis对象,源码如下:

1、什么是redisObject:
从Redis的使用者的角度来看,⼀个Redis节点包含多个database(非cluster模式下默认是16个,cluster模式下只能是1个),而一个database维护了从key space到object space的映射关系。这个映射关系的key是string类型,⽽value可以是多种数据类型,比如:string, list, hash、set、sorted set等。我们可以看到,key的类型固定是string,而value可能的类型是多个。
⽽从Redis内部实现的⾓度来看,database内的这个映射关系是用⼀个dict来维护的。dict的key固定用⼀种数据结构来表达就够了,这就是动态字符串sds。而value则比较复杂,为了在同⼀个dict内能够存储不同类型的value,这就需要⼀个通⽤的数据结构,这个通用的数据结构就是robj,全名是redisObject。

在这里插入图片描述

Redis的编码方式

Redis中会根据存储的数据类型不同,选择不同的编码方式,共包含11种不同类型:

编号 编码方式 说明
0 OBJ_ENCODING_RAW raw编码动态字符串
1 OBJ_ENCODING_INT long类型的整数的字符串
2 OBJ_ENCODING_HT hash表(字典dict)
3 OBJ_ENCODING_ZIPMAP 已废弃
4 OBJ_ENCODING_LINKEDLIST 双端链表
5 OBJ_ENCODING_ZIPLIST 压缩列表
6 OBJ_ENCODING_INTSET 整数集合
7 OBJ_ENCODING_SKIPLIST 跳表
8 OBJ_ENCODING_EMBSTR embstr的动态字符串
9 OBJ_ENCODING_QUICKLIST 快速列表
10 OBJ_ENCODING_STREAM Stream流

五种数据结构

Redis中会根据存储的数据类型不同,选择不同的编码方式。每种数据类型的使用的编码方式如下:

数据类型 编码方式
OBJ_STRING int、embstr、raw
OBJ_LIST LinkedList和ZipList(3.2以前)、QuickList(3.2以后)
OBJ_SET intset、HT
OBJ_ZSET ZipList、HT、SkipList
OBJ_HASH ZipList、HT

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Redis数据结构——QuickList、SkipList、RedisObjective 的相关文章

  • 如何使用Spring Cache处理redis异常?

    我目前正在开发一个包含 Spring Data Redis 和 Spring Cache 的项目 在spring data redis中 我使用redis模板调用redis 我在 try catch 块中处理 redis 模板抛出的所有异常
  • 库存管理系统的 SQL 与 NoSQL

    我正在开发一个基于 JAVA 的网络应用程序 主要目的是拥有在多个称为渠道的网站上销售的产品的库存 我们将担任所有这些渠道的管理者 我们需要的是 用于管理每个渠道的库存更新的队列 库存表 其中包含每个通道上分配的正确快照 将会话 ID 和其
  • Redis 排序集和解决关系

    我正在使用 Redis 排序集来存储我正在处理的项目的排名 我们没有预料到 我们想要如何处理关系 Redis 按字典顺序对具有相同分数的条目进行排序 但我们想要做的是对具有相同分数的所有条目给予相同的排名 例如在以下情况 redis 127
  • Redis INCRBY 有限制

    我想知道是否有一种方法可以通过我的应用程序的单次往返在 Redis 中执行此操作 对于给定的键K 其可能值V是范围内的任意整数 A B 基本上 它有上限和下限 When an INCRBY or DECRBY发出命令 例如INCRBY ke
  • Spring Data Redis JedisConnectionException:流意外结束

    雷迪斯3 0 5Spring数据Redis 1 3 6绝地武士2 6 3 我们的 Web 应用程序通过 pub sub 从 Redis 接收数据 还以键 值对的形式在 Redis 上执行数据读 写 读 写发生在监听线程 独立监控线程和htt
  • 如何将 ActionController::Live 与 Resque + Redis 一起使用(用于聊天应用程序)

    我正在尝试为我的 Rails 应用程序构建聊天功能 我在用ActionController Live Puma Resque Redis为了这 所以基本上在这种情况下 redissubscribe方法正在后台运行 使用resque 到目前为
  • SignalR 无法连接到 SSL 上的 Azure Redis

    我目前在 Azure 上托管我的 redis 缓存服务器 并让 signalR 依赖它作为骨干 使用以下内容 GlobalHost DependencyResolver UseRedis 服务器 端口 密码 eventKey 这可以在端口
  • Node Js:Redis 作业在完成其任务后未完成

    希望你们做得很好 我在我的 Nodejs 项目中实现了 BullMQ Bull 的下一个主要版本 来安排发送电子邮件的作业 例如 发送忘记密码请求的电子邮件 所以 我编写了如下所示的代码 用户服务 await resetPasswordJo
  • 如何使 Redis 缓存中数据层次结构(树)的部分内容无效

    我有一些产品数据 需要在 Redis 缓存中存储多个版本 数据由 JSON 序列化对象组成 获取普通 基本 数据的过程很昂贵 将其定制为不同版本的过程也很昂贵 因此我想缓存所有版本以尽可能进行优化 数据结构看起来像这样 BaseProduc
  • 为什么Redis中没有有序的hashmap?

    Redis 数据类型 http redis io topics data types包括排序集 http redis io topics data types intro sorted sets以及其他用于键值存储的必要数据结构 但我想知道
  • Scala 使用的 Redis 客户端库建议

    我正在计划使用 Scala 中的 Redis 实例进行一些工作 并正在寻找有关使用哪些客户端库的建议 理想情况下 如果存在一个好的库 我希望有一个为 Scala 而不是 Java 设计的库 但如果现在这是更好的方法 那么仅使用 Java 客
  • Redis 队列工作程序在 utcparse 中崩溃

    我正在尝试按照以下教程获得基本的 rq 工作 https blog miguelgrinberg com post the flask mega tutorial part xxii background jobs https blog m
  • 在 Spring 4 中干掉通用的 RedisTemplate

    我读到你可以拥有 Autowired从 Spring 4 开始泛型 这太棒了 我有一个摘要RedisService我想参加的课程 Autowired一个通用的 RestTemplate 如下所示 public abstract class
  • 当 Jedis 与 Spring Data 一起使用时,为什么数据会以奇怪的键存储在 Redis 中?

    我将 Spring Data Redis 与 Jedis 一起使用 我正在尝试存储带有密钥的哈希值vc list id 我能够成功插入到redis 但是 当我使用 redis cli 检查密钥时 我没有看到密钥vc 501381 相反我看到
  • docker-compose:容器之间的 Redis 连接被拒绝

    我正在尝试设置一个 docker compose 文件 该文件旨在替换运行多个进程 RQ 工作线程 RQ 仪表板和 Flask 应用程序 的单个 Docker 容器解决方案导师 http supervisord org 主机系统是 Debi
  • 如何延长 django-redis 中的缓存 ttl(生存时间)?

    我正在使用 django 1 5 4 和 django redis 3 7 1 我想延长缓存的 ttl 生存时间 当我取回它时 这是示例代码 from django core cache import cache foo cache get
  • 如何配置Lettuce Redis集群异步连接池

    我正在配置我的生菜重新分配池 当我按照官方文档配置时 连接池无法正常初始化 无法获取连接 官方文档指出 RedisClusterClient clusterClient RedisClusterClient create RedisURI
  • 超出 Redis 连接/缓冲区大小限制

    在对我们的应用程序服务器进行压力测试时 我们从 Redis 中得到以下异常 ServiceStack Redis RedisException 无法连接到 redis host 6379 处的 redis 实例 gt System Net
  • 由于配置文件错误,无法启动 Redis 服务器

    我刚刚按照此处的说明安装了 Redis http redis io download http redis io download 当我运行 redis server redis conf 时出现以下错误 FATAL CONFIG FILE
  • 没有适用于机器人的 Laravel 会话

    我在大型 Laravel 项目和 Redis 存储方面遇到问题 我们将会话存储在 Redis 中 我们已经有 28GB 的 RAM 然而 它的运行速度仍然相对较快 达到了极限 因为我们有来自搜索引擎机器人的大量点击 每天超过 250 000

随机推荐

  • 大电容滤低频,小电容滤高频?——滤波电容的选择

    大电容滤低频 小电容滤高频 滤波电容的选择 2013 07 29 20 19 06 分类 默认分类 标签 举报 字号大中小 订阅 用微信 扫一扫 将文章分享到朋友圈 用易信 扫一扫 将文章分享到朋友圈 下载LOFTER客户端 文章一 一直有
  • vue weixin-js-sdk进行微信分享

    第一步 安装weixin js sdk npm install weixin js sdk 第二步 在assets文件下新建个common文件夹 然后再新建个utils js文件 import wx from weixin js sdk 微
  • 存储过程中SELECT INTO的使用

    在MySQL存储过程中使用SELECT INTO语句为变量赋值 用来将查询返回的一行的各个列值保存到局部变量中 要求 查询的结果集中只能有1行 SELECT col name INTO var name table expr 使用SELEC
  • jqGrid 各种参数 详解

    JQGrid JQGrid是一个在jquery基础上做的一个表格控件 以ajax的方式和服务器端通信 JQGrid Demo 是一个在线的演示项目 在这里 可以知道jqgrid可以做什么事情 下面是转自其他人blog的一个学习资料 与其说是
  • SpringCloud-服务配置

    服务配置 Spring Cloud Config分布式配置中心 概述 分布式系统面临的配置问题 微服务意味着要将单体应用中的业务拆分成一个个子服务 每个服务的粒度相对较小 因此系统中会出现大量的服务 由于每个服务都需要必要的配置信息才能运行
  • NAT--静态、动态、NAPT、Easy-ip、NAT server

    静态NAT 静态 NAT Static NAT 一对一 将内部网络的私有IP地址转换为公有IP地址 IP地址对是一对一的 是一直不变的 实验拓扑 PC配置 AR1
  • 5 .A-B 数对-二分查找/模拟(普及-)

    文章目录 问题描述 问题分析 代码实现 运行结果 总结 问题描述 出题是一件痛苦的事情 相同的题目看多了也会有审美疲劳 于是我舍弃了大家所熟悉的 A B Problem 改用 A B 了哈哈 好吧 题目是这样的 给出一串数以及一个数字 C
  • 深度测评

    2021 跨平台开发框架到底哪家强 目前市场上有多个专业做跨平台开发的框架 那么对开发者来说究竟哪一个框架更符合自己的需求呢 笔者特地总结对比了一下不同框架的特性 国内外笔者选择了一共 5 个主流的测评对象 分别是 RN Flutter I
  • Kafka 数据存储形式以及数据清理

    文章目录 Kafka 的存储日志 日志的观察模式 日志写入模式 日志读写模式 删除消息 数据挤压问题 数据清理 日志删除 日志压缩 在Kafka当中数据是以日志的形式存在的 Kafka 的存储日志 在Kafka当中 数据在磁盘当中的存储 K
  • 家用千兆路由器排行榜前十名_路由器哪个牌子好?千兆路由器2019排行

    现在网络宽带已经进入千兆时代 几乎很多的宽带已经免费升级到了100M以上 所以之前的百兆无线路由器已经有点落伍了 市面上也出现了很多的入门级的千兆无线路由器 区别就是如果你家的宽带在100M以内 比如80M 50M 20M 10M等 使用百
  • 取消GL.iNet路由器视频的密码

    每次路由器访问192 168 8 1 8083 action stream时总是无法访问 但是先进入192 168 8 1登录以后再去刷新视频就可以出来 即使取消外网登录验证也还是没效果 最后发现广大网友的意见是重新刷固件 先去GL iNe
  • 计算机专业毕业设计演示视频(论文+系统)_kaic

    https gongkailuxiangdu oss cn beijing aliyuncs com lx jsp 20 70912jspm E6 88 BF E5 B1 8B E9 94 80 E5 94 AE E7 AE A1 E7 9
  • 树莓派命令行显示乱码及异地组网问题

    写了一千多字没保存 很生气 这一条简写 命令行显示异常 首先检查树莓派设置里的地区 时区设置 一律改为中国 随后重要原因就是字库不全问题 命令行输入 sudo apt get install ttf way zenhei 一路确定安装字体
  • 程序的链接的三种方式

    程序的链接有以下三种方式 静态链接 在程序运行之前 先将各目标模块及它们所需的库函数链接成一个完整的可执行程序 以后不再拆开 装入时动态链接 将用户源程序编译后所得到的一组目标模块 在装入内存时 釆用边装入边链接的链接方式 运行时动态链接
  • 使用matlab进行灵敏性分析(附源代码)

    调用单纯形程序 function x z flg sgma simplexfun A A1 b c m n n1 cb xx A b are the matric in Ax b c is the matrix in max z cx A1
  • ChatGPT实现代码生成

    代码生成 就代码生成而言 ChatGPT 是一款卓越的工具 它为开发者提供强大的功能 ChatGPT 可以运用其出色的自然语言处理技术 深入理解和解释开发者的需求 快速生成适合的代码片段 对于那些繁琐的任务或者重复的代码 ChatGPT 能
  • 试题 C: 刷题统计

    题目链接 点击跳转 题目描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛 他计划周一至周五每天做 a 道题目 周六和周日每天做 b 道题目 请你帮小明计算 按照计划他将在第几天实现做题数大于等于 n 题 输入格式 输入一行包含三个整数 a
  • 系统资源占用高排查手段

    1 cpu高排查思路 1 top d 1每秒打印进程所占cpu资源 然后再按h显示线程占用 2 strace跟踪strace p 线程号 会打印该线程主要做什么操作 2 io高排查思路 lsof是一个展现的是当前系统所有进程 不是线程 打开
  • 端午过后公司面了一个字节来的要求月薪23K,明显感觉他背了很多面试题...

    最近有朋友去字节面试 面试前后进行了20天左右 包含4轮电话面试 1轮笔试 1轮主管视频面试 1轮hr视频面试 据他所说 80 的人都会栽在第一轮面试 要不是他面试前做足准备 估计都坚持不完后面几轮面试 其实 第一轮的电话面试除了一些常规的
  • Redis数据结构——QuickList、SkipList、RedisObjective

    承接上文 本文主要介绍QuickList SkipList RedisObjective 四 Redis数据结构 QuickList 问题1 ZipList虽然节省内存 但申请内存必须是连续空间 如果内存占用较多 申请内存效率很低 怎么办