redis数据结构、多路复用、持久化---java

数据结构

Redis 提供了丰富的数据类型,常见的有五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)、Zset(有序集合)
在这里插入图片描述
随着 Redis 版本的更新,后面又支持了四种数据类型:BitMap(2.2 版新增)、HyperLogLog(2.8 版新增)、GEO(3.2 版新增)、Stream(5.0 版新增)
在这里插入图片描述

zset底层实现-跳表

跳表(Skip List) 是一种数据结构,它的核心思想是通过“跳跃”来加速查找、插入和删除操作。
想象你有一排有序的数字,比如 [1, 3, 5, 7, 9, 11],你想快速找到某个数,比如 7。如果用普通链表,一个个找过去(线性查找),最坏情况要查 6 次。如果是二叉搜索树,可以跳着找,效率高很多。跳表就是想让链表也能“跳着找”,通过增加多层索引来实现。

比如,假设底层链表是:[1 -> 3 -> 5 -> 7 -> 9 -> 11]
第一层索引可能是(随机选一部分节点,比如 3 和 9):[3 -> 9]
第二层索引可能是(再从第一层随机选,比如只有 9):[9]
完整结构就像这样:

2: [9]↓
层 1: [3 -> 9]↓    ↓
层 0: [1 -> 3 -> 5 -> 7 -> 9 -> 11]
  1. 从最高层(层 2)开始,只有 [9],9 > 7,跳不动,往下到层 1。
  2. 层 1 是 [3 -> 9],从 3 开始,3 < 7,往右跳到 9,9 > 7,跳不动,往下到层 0。
  3. 层 0 是 [1 -> 3 -> 5 -> 7 -> 9 -> 11],从 3 开始,3 < 7,跳到 5,5 < 7,跳到 7,找到!

每一层的索引不是真的去创建新结点,而是利用一个 level 数组

typedef struct zskiplistNode {//Zset 对象的元素值sds ele;//元素权重值double score;//后向指针struct zskiplistNode *backward;//节点的level数组,保存每层上的前向指针和跨度struct zskiplistLevel {struct zskiplistNode *forward;unsigned long span;} level[];
} zskiplistNode;

在这里插入图片描述
Redis 跳表在创建节点的时候,随机生成每个节点的层数:跳表在创建节点时候,会生成范围为[0-1]的一个随机数,如果这个随机数小于 0.25(相当于概率 25%),那么层数就增加 1 层,然后继续生成下一个随机数,直到随机数的结果大于 0.25 结束,最终确定该节点的层数。

跳表 vs B+树

在这里插入图片描述

  • 代码简单:Redis 是内存数据库,跳表代码实现比 B+ 树简单得多,开发者希望尽量减少维护复杂数据结构的开销。
  • 容易调整:ZSET 经常需要插入和删除元素,跳表的动态调整(随机层数)比 B+ 树的节点分裂/合并更轻量。
  • Redis 数据在内存中,不需要优化磁盘I/O,因此 B+ 树的磁盘友好特性(叶子结点顺序排列,可一次读取)对 Redis 意义不大。

压缩列表和listpack

压缩列表

想象你有一堆小纸条,上面写着数字 [1, 2, 3]。传统链表会给每个数字单独包一个信封(节点),每个信封还有地址标签指向下一个,占空间多。压缩列表就像把这些数字直接顺序排列在一起节省空间。
在这里插入图片描述
压缩列表是一个字节数组,分为几个部分:
头部(元数据):

  • zlbytes(4 字节):整个压缩列表的总字节数。
  • zltail(4 字节):尾节点相对于起点的偏移量(方便从尾部访问)。
  • zllen(2 字节):节点数量(如果超过 65535,就需要遍历计算真实数量)。
  • entry1, entry2, …:实际存储的节点数据。
  • zlend(1 字节):结束标记,固定为 0xFF。

节点(entry): 每个节点由三部分组成:

  • previous_length:前一个节点的长度(变长编码,1 或 5 字节)。
  • encoding:当前节点的编码类型和长度(变长编码)。
  • content:实际数据内容。

压缩列表的缺点是会发生连锁更新的问题,因此连锁更新一旦发生,就会导致压缩列表占用的内存空间要多次重新分配,这就会直接影响到压缩列表的访问性能。

listpack

在这里插入图片描述
可以看到,listpack 没有压缩列表中记录前一个节点长度的字段了,listpack 只记录当前节点的长度,当我们向 listpack 加入一个新元素的时候,不会影响其他节点的长度字段的变化,从而避免了压缩列表的连锁更新问题

哈希表扩容

两张哈希表,表1放数据;
表1满了给表2分空间(2倍),数据复制到表2,原表1释放,表2变表1;
新建空表2;

如果「哈希表 1 」的数据量非常大,那么在迁移至「哈希表 2 」的时候,因为会涉及大量的数据拷贝,此时可能会对 Redis 造成阻塞,无法服务其他请求。

渐进式更新:在 rehash 进行期间,每次哈希表元素进行新增、删除、查找或者更新操作时,Redis 除了会执行对应的操作之外,还会顺序将「哈希表 1 」中索引位置上的所有 key-value 迁移到「哈希表 2」 上,最终「哈希表 1 」变空表。
查找一个 key 的值的话,先会在「哈希表 1」 里面进行查找,如果没找到,就会继续到哈希表 2 里面进行找到。

String

在这里插入图片描述

  1. 多增加 len 表示当前字符串的长度:这样就可以直接获取长度了,复杂度 O(1);
  2. 自动扩展空间:当 SDS 需要对字符串进行修改时,首先借助于 len 和 alloc 检查空间是否满足修改所需的要求,如果空间不够的话,SDS 会自动扩展空间,避免了像 C 字符串操作中的溢出情况;
  3. 有效降低内存分配次数:C 字符串在涉及增加或者清除操作时会改变底层数组的大小造成重新分配,SDS 使用了 空间预分配 和 惰性空间释放 机制,简单理解就是每次在扩展时是成倍的多分配的,在缩容是也是先留着并不正式归还给 OS;
  4. 二进制安全:C 语言字符串只能保存 ascii 码,对于图片、音频等信息无法保存,SDS 是二进制安全的,写入什么读取就是什么,不做任何过滤和限制;

redis线程和IO多路复用

redis为什么选择单线程

  • Redis 的大部分操作 都在内存中完成,并且采用了高效的数据结构,因此 Redis 瓶颈可能是机器的内存或者网络带宽,而并非 CPU,既然 CPU 不是瓶颈,那么自然就采用单线程的解决方案了;
  • Redis 采用单线程模型可以 避免了多线程之间的竞争,省去了多线程切换带来的时间和性能上的开销,而且也不会导致死锁问题。
  • Redis 采用了 I/O 多路复用机制 处理大量的客户端 Socket 请求,一旦有请求到达,就会交给 Redis 线程处理,这就实现了一个 Redis 线程处理多个 IO 流的效果。

IO 多路复用并不是开启一个新线程监听socket然后把任务给主线程。I/O 多路复用(I/O Multiplexing)是一种技术,让一个线程(通常是主线程)可以同时监听多个 I/O 通道(如 socket),并在某个通道有事件(如数据可读或可写)时得到通知,然后处理这些事件。它并不是依赖“新线程”来监听,而是利用操作系统提供的机制(如 select、poll、epoll)在单线程内高效管理多个连接。

传统 I/O 多路复用(Redis 6.0 之前)

  • 流程:
    • 主线程用 epoll(或其他多路复用工具)监听所有客户端 socket。
    • 当某个 socket 有数据可读时,epoll 通知主线程。
    • 主线程读取数据、执行命令、返回结果,全程单线程完成。
  • 特点:没有新线程,完全由主线程负责监听和处理。

Redis 6.0+ 的 I/O 多线程优化

  • 流程:
    • 主线程仍然用 I/O 多路复用(epoll)监听 socket,接受新连接。
    • 主线程将 socket 分配给 I/O 线程。
    • I/O 线程负责读取客户端数据,放入队列。
    • 主线程从队列中取出命令,执行计算逻辑。
    • 执行结果放回队列,I/O 线程发送给客户端。
  • 特点:多了 I/O 线程来分担网络读写,但核心计算仍是主线程完成。

Redis 6.0 对于网络 I/O 采用多线程来处理。但是对于命令的执行,Redis 仍然使用单线程来处理,所以大家不要误解 Redis 有多线程同时执行命令。

redis事务

如果要保证 2 条命令的原子性的话,可以考虑用 lua 脚本
redis 事务(使用 MULTI 和 EXEC )出错的情况不保证原子性;

redis持久化

redis 虽然是内存数据库,但也要能够处理重启、宕机或系统故障后恢复数据。
redis 有两种持久化方式:RDB 快照和 AOF 日志

RDB快照

RDB 快照就是将 某一时刻的键值对数据存储到磁盘 ,生成一个二进制文件(默认名为 dump.rdb)。
触发时机:

  • SAVE命令手动触发:主线程直接生成 RDB 文件,会阻塞其他操作(不常用)
  • BGSAVE 命令手动触发:fork 一个子进程生成 RDB 文件,主线程继续处理请求(常用)
  • 自动触发:配置文件中设置条件,底层其实是 BGSAVE

AOF日志

AOF 是通过 记录每条写命令(增删改)到日志文件(默认名为 appendonly.aof),在重启时重放这些命令来恢复数据。它记录的是操作过程,而不是数据快照。
同步策略(写磁盘的频率):

  • appendfsync always:每条命令立即同步到磁盘,最安全但最慢。
  • appendfsync everysec:每秒同步一次,性能和安全性平衡(默认)。
  • appendfsync no:交给操作系统决定,性能最好但可能丢数据。

重写(rewrite):AOF 文件会不断变大,Redis 提供 BGREWRITEAOF 命令精简文件,只保留能重建当前状态的最小命令集。

对比

  • AOF 文件占用空间大,因为要重现每条命令,所以恢复慢,优点就是即使丢失数据,丢失的也比较少
  • RDB 占用空间小,恢复快,但可能丢失两次快照之间的修改

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3之写一个aichat ----vite.config.js

vite.config.js的CSS配置 postcss-pxtorem 开发响应式网页的时候需要用到postcss-pxtorem amfe-flexible amfe-flexible是由阿里团队开发的一个库&#xff0c;它可以根据设备的屏幕宽度去动态调整HTML根元素()的字体大小&#xff0c;这意味着无论用户使用什么尺寸的设备访问你…

强化学习(赵世钰版)-学习笔记(8.值函数方法)

本章是算法与方法的第四章&#xff0c;是TD算法的拓展&#xff0c;本质上是将状态值与行为值的表征方式&#xff0c;从离散的表格形式&#xff0c;拓展到了连续的函数形式。 表格形式的优点是直观&#xff0c;便于分析&#xff0c;缺点是数据量较大或者连续性状态或者行为空间时…

C++模版(进阶)

文章目录 一、非类型模版参数二、模版的特化2.1 概念2.2 函数模版特化2.2.1 函数模版特化为指针类型注意事项 2.3 类模版特化2.3.1 全特化2.3.2 偏特化(半特化)2.3.3 类模板特化应用示例 三、模版分离编译3.1 什么是分离编译&#xff1f;3.2 模版的分离编译3.3 解决方法! 四、模…

Linux配置yum仓库,服务控制,防火墙

一、yum仓库 1.在安装软件时&#xff0c;首先第一步就是要考虑软件的版本的问题&#xff01; 2.软件的安装&#xff1a;最安全可靠的方法就是去软件对应的官网上查看安装手册&#xff08;包括的软件的下载&#xff09; 红帽系软件安装的常见的3种方式 &#xff08;1&#x…

布谷直播系统源码开发实战:从架构设计到性能优化

作为山东布谷科技的一名技术研发人员&#xff0c;我参与了多个直播系统平台从0到1的开发和搭建&#xff0c;也见证了直播行业从萌芽到爆发的全过程。今天&#xff0c;我想从研发角度&#xff0c;分享一些直播系统软件开发的经验和心得&#xff0c;希望能对大家有所帮助。 一、 …

实战设计模式之解释器模式

概述 作为一种行为设计模式&#xff0c;解释器模式提供了一种方法来定义语言的文法规则&#xff0c;并通过这些规则解析和处理特定类型的语言句子。简单来说&#xff0c;解释器模式允许我们定义一个代表某种语言中语法规则的对象结构&#xff0c;从而能够根据这些规则理解并处理…

物联网边缘计算网关是什么?

在物联网的浩瀚架构中&#xff0c;边缘计算网关宛如一位坚毅的前沿哨兵&#xff0c;默默守护着数据处理与传输的关键防线&#xff0c;为整个物联网系统的高效运转发挥着不可或缺的作用。 一、边缘计算网关的定义与基本功能 边缘计算网关是一种智能设备&#xff0c;它被部署在…

计算机视觉算法实战——障碍物识别(主页有源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​ ​​​​​​ ​ ​ 1. 引言 计算机视觉是人工智能领域的一个重要分支&#xff0c;旨在通过计算机模拟人类的视觉系统&#xff0c;从…

Win11锁屏后显示“天气、市场、广告”如何取消显示

关闭方法&#xff1a;设置>个性化>锁屏界面>锁屏界面状态>"无"。 方法一&#xff1a;通过“个性化”设置 打开“设置”应用&#xff1a; 点击屏幕左下角的“开始”按钮&#xff08;Windows 图标&#xff09;。点击齿轮状的“设置”图标。或者按下 Win I…

10天速通强化学习-008

TRPO 思考-TRPO-在线策略-给定信任区域防止更新不稳定 Actor-Critic网络随着网络深度的增加&#xff0c;步长太长&#xff0c;梯度更新会变差。改变方法-增加信任区域。(trust region policy optimization)-TRPO算法&#xff1a; 核心思想&#xff1a; 是在每次迭代中&…

整合百款经典街机游戏的模拟器介绍

对于80、90后而言&#xff0c;街机游戏承载着童年的欢乐记忆。今天要给大家介绍一款超棒的软件——「MXui街机厅经典游戏101款」&#xff0c;它能带你重回那段热血沸腾的街机时光。 「MXui街机厅经典游戏101款」是一款绿色免安装的街机模拟器&#xff0c;体积约1.39G。无需繁琐…

springboot第三站(1) web开发引入

目录 1.简介 2.SpringBoot对静态资源的映射规则 3.模版引擎 1.简介 使用SpringBoot&#xff1b; 1&#xff09;、创建SpringBoot应用&#xff0c;选中我们需要的模块&#xff1b; 2&#xff09;、SpringBoot已经默认将这些场景配置好了&#xff0c;只需要在配置文件中指定…

12-二叉树-二叉树高度(给定前序和中序确定二叉树)

题目 来源 23. 二叉树的高度 思路 其实跟09那篇很像&#xff0c;反正核心就是要通过前序和中序来建树&#xff0c;只不过现在多了一个返回值&#xff1b;因为建树的时候&#xff0c;其实左子树和右子树的深度就可以知道。其余详见代码。 代码 /* 前序遍历根左右,中序&…

PSI5接口

文章目录 前言PSI5接口简介操作模式命名规则异步操作模式&#xff08;PSI5-A&#xff09;同步操作模式&#xff08;PSI5-P&#xff09; 传感器->ECU物理层&#xff08;位编码&#xff09;数据链路层数据帧帧格式串行消息帧10bits 传感器帧定义超10bits传感器帧定义 ECU->…

垃圾处理全流程监管平台

在当前城市化进程中&#xff0c;垃圾处理已成为城市管理的重要课题。随着技术的发展&#xff0c;垃圾处理全流程监管平台的建设显得尤为重要。该平台能够实现垃圾从产生、收集、运输到最终处理的全流程监管&#xff0c;提高垃圾处理效率&#xff0c;促进资源回收利用&#xff0…

【Linux编程】IPC之消息队列从踩坑到实战:核心原理、实战案例与C++封装详解(含完整代码)

一、消息队列基础概念 消息队列是Linux系统提供的一种进程间通信&#xff08;IPC&#xff09;机制&#xff0c;具有以下特点&#xff1a; 消息以链表形式存放在内核中每个消息包含类型标识&#xff08;mtype&#xff09;支持多生产者/多消费者模式消息总长度受限于系统配置&a…

Unity 项目工程结构目录

1. Unity.VisualScripting.Core 作用: Visual Scripting 的核心模块&#xff0c;提供了可视化编程的基础功能&#xff08;前身为 Bolt&#xff09;。它允许开发者通过节点图创建游戏逻辑&#xff0c;而无需编写代码。 典型用途: 非程序员快速构建原型&#xff0c;或简化…

从pdf提取文本数据的c/cpp库(非OCR)

Aspose.PDF for C 商业付费版&#xff0c;无源码。 功能强大&#xff0c;支持多种PDF操作。 对应的官方示例代码&#xff1a;Aspose.PDF-for-C Spire.PDF for C 商业付费版 对应的官方示例代码&#xff1a;Spire.PDF-for-C- PDFTron SDK 商业付费版 PoDoFo 开源 当前版本…

【Linux操作系统——学习笔记二】Linux简单导航命令操作

一、前言 学习Linux&#xff0c;本质上是学习在命令行下熟练使用Linux的各类命令。 命令行&#xff1a;是一种通过输入命令和参数与计算机系统进行交互的方式&#xff0c;可以使用各种字符化命令对系统发出操作指令&#xff0c;打开Linux终端&#xff0c;进入命令行界面。 …

赛逸展2025创新模式,以科技创新奖赋能展位战略价值

CES Asia2025第七届亚洲消费电子技术贸易展&#xff08;赛逸展&#xff09;主办方负责人提出的创新理念&#xff0c;为展会的战略价值注入了新活力&#xff1a;“我们不是在卖展位&#xff0c;而是在分发政策红利入场券——企业每平方米的展位投入&#xff0c;都可能通过科技创…