Redis追本溯源(三)内核:线程模型、网络IO模型、过期策略与淘汰机制、持久化

news2025/1/9 2:06:51

文章目录

  • 一、Redis线程模型演化
    • 1.Redis4.0之前
    • 2.Redis4.0之后
    • 单线程、多线程对比
    • 3.redis 6.0之后
  • 二、Redis的网络IO模型
    • 1.基于事件驱动的Reactor模型
    • 2.什么是事件驱动,事件驱动的Reactor模型和Java中的AIO有什么区别
    • 3.异步非阻塞底层实现原理
  • 三、Redis过期策略
    • 1.常见的过期策略
    • 2.Redis的惰性删除
    • 3.Redis的定期过期删除
      • (1)每次检查一部分,这个一部分是多少
      • (2)事件循环是指什么
      • (3)惰性删除
    • 4.淘汰机制(缓存)
  • 四、持久化

一、Redis线程模型演化

1.Redis4.0之前

Redis在处理客户端请求时,通常使用单线程来进行读取、解析、执行和响应返回,因此被称为单线程应用。在4.0版本之前,这一描述是准确的。

  • 单线程: 读取、解析、执行和响应返回。

2.Redis4.0之后

从4.0版本开始,Redis开始使用后台线程来处理一些耗时的操作,如清理脏数据、释放超时连接、删除大key等,但网络读写和执行命令仍然是单线程处理的。

  • 单线程: 网络读写和执行命令
  • 多线程: 清理脏数据、释放超时连接、删除大key等耗时操作。

单线程、多线程对比

Redis 之所以使用单线程是因为 Redis 执行的是纯内存的操作,Redis 服务的瓶颈不在 CPU,而是在网络和内存。单线程避免了不必要的上下文切换和竞争条件,也无需考虑锁的问题,整个线程模型比较简单。

多线程模型虽然在某些方面表现优异,但是它却引入了程序执行顺序的不确定性,带来了并发读写的一系列问题,增加了系统复杂度、同时可能存在线程切换、甚至加锁解锁、死锁造成的性能损耗。Redis 通过事件模型以及 IO 多路复用等技术,处理性能非常高,因此没有必要使用多线程来执行命令。

3.redis 6.0之后

Redis 6.0使用多条IO线程从IO队列中读取请求并进行解析,然后将解析后的命令交给主线程执行。虽然Redis 6.0支持多线程,但执行命令的线程仍然只有主线程一个,因此仍然被认为是单线程执行的。但Redis 6.0通过使用多线程IO突破了单线程IO的瓶颈,发挥了多核的优势。

  • 单线程: 执行命令。
  • 多线程: 网络IO读写。
  • 多线程: 清理脏数据、释放超时连接、删除大key等耗时操作。

当 Redis Server 收到一个请求的时候,先会进入 IO 队列,多条 IO 线程会从 IO 队列里面读取请求并进行解析,解析之后的命令就会交给 Redis 主线程进行执行;执行后的结果会重新进入 IO 队列,等待 IO 线程将响应返回给客户端。

二、Redis的网络IO模型

上面已经说了,Redis是基于单个主线程 + IO 多线程的线程模型,

1.基于事件驱动的Reactor模型

关于Reactor模型的基本介绍之前写过了:博客

Reactor模型有三种——单Reactor单线程、单Reactor多线程、多Reactor多线程,Redis是基于第二种单Reactor多线程,是基于事件驱动的、多路复用的、异步非阻塞I/O的线程模型。

2.什么是事件驱动,事件驱动的Reactor模型和Java中的AIO有什么区别

  • 事件驱动:

事件驱动的I/O模型(Event-driven I/O Model)是一种高效的I/O处理模型,主要用于处理多个I/O事件。在事件驱动的I/O模型中,程序会监听多个I/O事件,并在事件发生时触发相应的处理程序进行处理,而不是等待I/O操作完成。 这种模型避免了阻塞式I/O操作可能带来的性能问题,同时也提高了系统的并发性能。

在这里插入图片描述

  • AIO:

而AIO虽然也是异步非阻塞的(基于发布订阅模式),但和事件驱动还是不一样的:博客

总的来说,AIO Server需要有一个线程来处理读写事件,在等待OS内核处理读写事件并异步通知此线程的时候可以继续做其他的事情。和Reactor相比其实现的机制还是很不一样的。

在这里插入图片描述

3.异步非阻塞底层实现原理

select、poll、epoll操作系统底层原理:博客

三、Redis过期策略

1.常见的过期策略

在缓存系统中,常见的过期策略有以下几种:

  1. 定时过期策略(TTL):为每个缓存条目设置一个过期时间(Time To Live),当缓存超过这个时间时,缓存条目就会被自动删除。这种策略适用于缓存对象的过期时间比较固定的场景。

  2. 惰性过期策略(LRU):当缓存空间不足时,删除最近最少使用(Least Recently Used)的缓存条目。这种策略适用于缓存对象的访问模式是热点访问的场景。

  3. 定期过期策略:周期性地清理缓存中的过期条目,以保证缓存空间的有效利用。这种策略适用于缓存对象的过期时间比较长的场景。

  4. 基于容量的过期策略(LFU):根据缓存条目的使用频率(Least Frequently Used)来删除缓存条目,以保证缓存空间的有效利用。这种策略适用于缓存空间有限的场景。

  5. 基于热度的过期策略(Hot Key):根据缓存条目的热度(Hot Key)来删除缓存条目,以保证缓存空间的有效利用。这种策略适用于缓存对象的访问模式是热点访问的场景。

在 Redis 中并没有采用定时过期策略,而是选择了惰性过期策略(第二种)和定期过期策略(第三种)的组合。

2.Redis的惰性删除

Redis不会主动删除过期的key,而是在客户端访问这个key时,Redis会检查这个key是否过期,如果过期了就会删除这个key。

惰性删除的实现原理是基于Redis的请求响应模型。当客户端请求一个key时,Redis会首先检查这个key是否过期,如果过期了就将其删除,并返回一个不存在的响应。如果这个key没有过期,就返回对应的value。

需要注意的是,惰性删除不是实时的,过期key可能会长时间存在于内存中,直到有客户端请求时才被删除。这可能会导致内存浪费,需要根据实际情况选择合适的过期策略。

3.Redis的定期过期删除

Redis的过期字典是一种特殊的字典结构,它用于存储带有过期时间的key和对应的value。过期字典的实现基于哈希表和跳跃表,可以以时间复杂度O(1)的速度进行新增、删除和查找操作。

具体来说,当我们向Redis存储一个带有过期时间的key时,Redis会将其添加到过期字典中。过期字典的键是带有过期时间的key,值是一个指向存储这个key的数据结构的指针。过期字典中的每个键都对应一个过期时间,用来记录这个key何时过期。

Redis在每个 事件循环 中都会检查 一部分 过期字典中的key,并将过期的key删除。为了避免一次检查过多的key,Redis会将所有的过期key分散到不同的时间点上,并使用定时器来监控这些时间点。当Redis在某个时间点上检查到一个过期key时,就会将其删除。

过期字典的实现基于哈希表和跳跃表。哈希表用于快速查找key,而跳跃表则用于按照过期时间排序key。当Redis需要检查过期key时,它会遍历跳跃表,找到已经过期的key,并将其从哈希表和跳跃表中删除。

(1)每次检查一部分,这个一部分是多少

Redis的过期字典每次检查的过期key数量是由服务器配置的一个参数决定的,这个参数叫做hz。hz是Redis服务器每秒运行的事件循环数量,它决定了每秒钟服务器会检查多少个过期key。默认的hz值是10,也就是每秒钟会检查10个过期key。

(2)事件循环是指什么

Redis的事件循环是一个基于事件驱动的异步非阻塞的网络通信模型,它通过监听和处理事件来实现网络通信和其他任务的处理。在Redis中,事件是指网络通信中发生的各种事件,例如客户端连接、读写事件、定时器事件等。

为了处理这些事件,Redis使用了一个事件处理器,它会监听事件,并根据事件的类型和状态来执行相应的操作。事件处理器包含多个事件状态,每个状态都对应一类事件。例如,REDIS_READ_EVENT状态表示读事件,REDIS_WRITE_EVENT状态表示写事件,REDIS_TIME_EVENT状态表示定时器事件等。

当一个事件到达时,Redis会将其添加到事件队列中,并在下一个事件循环中处理它。在事件循环中,Redis会遍历事件队列,并根据事件的类型和状态来执行相应的操作。例如,对于一个客户端连接事件,Redis会建立一个新的客户端连接,并将其添加到客户端列表中;对于一个读事件,Redis会从客户端连接中读取数据并进行处理;对于一个定时器事件,Redis会执行相应的定时任务等等。

需要注意的是,Redis的事件循环是单线程的,因此在任何时候只会有一个事件循环正在执行。这意味着在事件循环中处理事件时,应尽量避免执行耗时较长的操作,以免影响其他事件的处理效率。

  • 事件队列

Redis的一个事件循环会处理多个事件,具体处理的事件数量取决于事件队列中的事件数量以及服务器配置的参数。在事件循环中,Redis会遍历事件队列,并根据事件的类型和状态来执行相应的操作。

事件队列是Redis存储事件的数据结构,它是一个先进先出(FIFO)的队列。当一个事件到达时,Redis会将其添加到事件队列中,并在下一个事件循环中处理它。如果事件队列中有多个事件,Redis会按照它们的顺序依次处理。

  • 划分依据

Redis的事件循环是以时间为依据划分的。具体来说,Redis会定时执行事件循环,每个事件循环的时间长度由服务器配置的参数决定。在每个事件循环中,Redis会处理所有已经到达的网络请求和定时任务,并等待下一个事件循环的到来。

Redis的事件循环的时间长度由服务器配置的参数hz决定。hz表示Redis服务器每秒运行的周期性任务数量,它决定了每秒钟服务器会执行多少个事件循环。默认的hz值是10,也就是每秒钟执行10个事件循环。

(3)惰性删除

采用懒惰删除机制可以简化Redis的实现。如果Redis需要立即删除过期key,那么它需要在每个事件循环中执行删除操作,这会增加代码的复杂度和维护成本。采用懒惰删除机制可以将删除操作集中在一起,简化代码实现和维护。

采用懒惰删除机制可以简化Redis的实现。如果Redis需要立即删除过期key,那么它需要在每个事件循环中执行删除操作,这会增加代码的复杂度和维护成本。采用懒惰删除机制可以将删除操作集中在一起,简化代码实现和维护。

4.淘汰机制(缓存)

Redis的缓存内存淘汰机制是指在内存不足时,Redis会根据一定的规则和算法自动删除一些缓存数据,以释放一部分内存空间,以保证Redis服务的正常运行。Redis的缓存内存淘汰机制主要有以下几种(用户可选择):

  1. LRU算法:LRU全称是Least Recently Used,即最近最少使用。LRU算法的原理是根据数据的访问时间来淘汰缓存数据,即淘汰最近最少被访问的数据。当内存不足时,Redis会自动删除最近最少使用的缓存数据,以释放一部分内存空间。

  2. LFU算法:LFU全称是Least Frequently Used,即最不经常使用。LFU算法的原理是根据数据的访问频率来淘汰缓存数据,即淘汰访问频率最低的数据。当内存不足时,Redis会自动删除访问频率最低的缓存数据,以释放一部分内存空间。

  3. TTL算法:TTL全称是Time To Live,即生存时间。TTL算法的原理是根据缓存数据的过期时间来淘汰数据。当缓存数据的过期时间到期时,Redis会自动删除这些数据,以释放一部分内存空间。

  4. Random算法:Random算法的原理是随机选择一些缓存数据进行删除,以释放一部分内存空间。当内存不足时,Redis会随机选择一些缓存数据进行删除,以释放一部分内存空间。

需要注意的是,Redis的缓存内存淘汰机制并不是完全准确的,它只是在一定程度上保证了Redis服务的可用性和稳定性。在实际使用Redis时,应根据实际情况选择合适的内存淘汰机制,以保证缓存数据的有效性和完整性。

四、持久化

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

印刷和数字设计的页面布局软件 QuarkXPress 2023 Crack

QuarkXPress 2023 用于印刷 和数字设计的页面布局软件,使用 QuarkXPress 释放您的创造力并最大限度地提高生产力 图形设计和桌面出版流程早就应该进行创新和颠覆,所以 QuarkXPress 就来了。自 1987 年首次亮相市场以来,成千上万的创意专业人士…

RocketMQ教程-(5)-功能特性-事务消息

事务消息为 Apache RocketMQ 中的高级特性消息,本文为您介绍事务消息的应用场景、功能原理、使用限制、使用方法和使用建议。 事务消息为 Apache RocketMQ 中的高级特性消息,本文为您介绍事务消息的应用场景、功能原理、使用限制、使用方法和使用建议。…

FFmpeg AVFilter的原理(三)- filter是如何被驱动的

1、下面是一个avfilter的graph 上图是ffmpeg中doc/examples中filtering_video.c案例的示意图。 本章节主要查看avfilter中的数据是怎么进入的,然后又是怎么出来的。 主要考察两个函数: av_buffersrc_add_frame_flags()av_buffers…

gcc编译的时候出现错误,可以用core查看错误信息

比如说我们有文件main.c,threadpool.c,threadpool.h main.c和threadpool.c都用了threadpool.h,也就是#include "threadpool.h" (1)如果我们直接使用gcc main.c -o a.out -lpthread会报如下的错 我们需要进行动态库链接 gcc -c threadpool.c -…

驱动开发 day3 (模块化驱动启动led,蜂鸣器,风扇,震动马达)

模块化驱动启动led,蜂鸣器,风扇,震动马达并加上Makefile 封装模块化驱动,可自由安装卸载驱动,便于驱动更新(附图) 1.安装模块驱动同时初始化各个设备并使能 2.该驱动会自动创建驱动节点. 3.通过c函数程序输入控制各个设备 4.卸载模块驱动 //编译驱动…

裂缝二维检测:裂缝类型判断

裂缝类型选择 裂缝类型有很多种,这里我们判断类型的目的是要搞明白是否有必要检测裂缝的长度。在本文中,需要判断的裂缝类型共有四种:横向裂缝、纵向裂缝、斜裂缝、网状裂缝。 环境搭建 上一节骨架图提取部分,我们已经安装了sk…

Linux centos安装openoffice在线预览

前言:由于项目里需要用到word、excel等文件的在线预览,所有选择了openoffice 1、下载openoffice Apache OpenOffice - Official Download 大家自行选择需要安装的版本,楼主由于之前在其他服务器安装过,选择了之前用过的版本&am…

4.Docker数据管理和容器互联

文章目录 Docker数据管理数据卷(容器与宿主机之间数据共享)数据卷容器(容器与容器之间数据共享)容器互联 Docker数据管理 数据卷(容器与宿主机之间数据共享) 数据卷是一个供容器使用的特殊目录&#xff0…

【UE5 多人联机教程】03-创建游戏

效果 步骤 打开“UMG_MainMenu”,增加创建房间按钮的点击事件 添加如下节点 其中,“FUNL Fast Create Widget”是插件自带的函数节点,内容如下: “创建会话”节点指游戏成功创建一个会话后,游戏的其他实例即可发现&am…

mysql -速成

目录 1.概述 1.3SQL的优点 1.4 SQL 语言的分类 2. 软件的安装与启动 2.1 安装 2.2 MySQL服务的启动和停止 2.3 MySQL服务的登录和退出 ​编辑 2.4 mysql常用命令 2.5 图形化用户结构Sqlyong 3.DQL 语言 3.1 基础查询 3.1.1、语法 3.1.2 特点 3.2 条件查询 3.2.1 …

数据库的聚合函数和窗口函数

1. 聚合函数 数据库的聚合函数是用于对数据集执行聚合计算的函数。它们将一组值作为输入,并生成单个聚合值作为输出。聚合函数通常与GROUP BY子句结合使用,以便在数据分组的基础上执行聚合操作。 1.1. 常用的聚合函数 COUNT():计算指定列或…

(五)springboot实战——springboot自定义事件的发布和订阅

前言 本节内容我们主要介绍一下springboot自定义事件的发布与订阅功能,一些特定应用场景下使用自定义事件发布功能,能大大降低我们代码的耦合性,使得我们应用程序的扩展更加方便。就本身而言,springboot的事件机制是通过观察者设…

Python(三十九)for-in循环

❤️ 专栏简介:本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中,我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 :本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

JAVA设计模式——模板设计模式(heima)

JAVA设计模式——模板设计模式(heima) 文章目录 JAVA设计模式——模板设计模式(heima)一、模板类二、子类2.1 Tom类2.2 Tony类 三、测试类 一、模板类 package _01模板设计模式;public abstract class TextTemplate{public final…

利用FME实现批量提取图斑特征点、关键界址点提取、图斑拐点抽稀,解决出界址点成果表时点数过多问题的方法

目录 一、实现效果 二、实现过程 1.提取图斑界址点 2.计算各界址点的角度 3.筛选提取关键界址点 三、总结 对于范围较大的图斑,界址点数目较大,在出界址点成果表前,往往需要对界址点进行处理,提取出关键特征点作为出界址点成…

数据库集群方案详解

本期直播我们邀请 KaiwuDB 资深解决方案专家周幸骏,为大家分享数据库集群方案详解。周老师毕业于复旦大学数学系,从业 20 余年,曾在 IBM 公司任资深技术专家,并为多家国有大型商业银行提供技术咨询和数据库业务连续方案设计等服务…

IBM:2023 年数据泄露的平均成本将达到 445 万美元

IBM 发布年度《数据泄露成本报告》,显示 2023 年全球数据泄露平均成本达到 445 万美元,比过去 3 年增加了 15%。创下该报告的历史新高。 报告显示,企业在计划如何应对日益增长的数据泄露频率和成本方面存在分歧。研究发现,虽然 95…

Linux学成之路(基础篇)(二十三)MySQL服务(上)

目录 一、概述 一、什么是MySQL 二、数据库能干什么 三、为什么要用数据库,优势、特性? 二、数据库类型 一、关系型数据库 RDBMS 一、概述 二、特点 三、代表产品 二、非关系型数据库 一、概述 二、特点 三、代表产品 三、数据库模型 一、…

【GEE笔记】主成分分析(PCA)算法的实现和应用

前言 主成分分析(PCA)是一种常用的降维方法,它可以将多个相关的变量转换为少数几个不相关的变量,称为主成分(PC)。这些主成分可以反映原始变量的大部分信息,同时减少数据的复杂度和冗余性。在遥…

结构型设计模式之组合模式【设计模式系列】

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 设计模式系列 期待你的关注哦!!! 现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。 Now everythi…