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

文章目录

  • 一、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时,应根据实际情况选择合适的内存淘汰机制,以保证缓存数据的有效性和完整性。

四、持久化

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

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

相关文章

【数字信号处理】带通采样定理及其MATLAB仿真

目录 一、带通采样定理1.1 内容1.2 公式推导 二、MATLAB信号仿真2.1 信号仿真实验2.2 MATLAB代码 三、总结参考 一、带通采样定理 按照奈奎斯特采样定理(低通采样),采样频率 f s f_{s} fs​ 要大于等于信号中最高频率 f m a x f_{max} fmax​ 的2倍,才…

28.1 kibana

Kibana 是一个免费且开放的用户界面,能够对 Elasticsearch 数据进行可视化操作,从跟踪查询负载,到理解请求如何流经整个应用,都能轻松完成。 1.Kibana安装 注意要与ES版本保持一致 https://www.elastic.co/downloads/past-relea…

C# 目标平台为x64,自定义控件不可用,显示控件未能加载,错误解决方法

由于项目加载第三方的dll需要编译成x64,设置编译目标为x64 结果打开窗口设计器时,自定义的控件不能显示及加载 错误消息:未能找到类型“XXX”。请确保已引用包含此类型的程序集。如果此类型为开发项目的一部分,请确保已使用针对当…

Android 在程序运行时申请权限——以自动拨打电话为例

Android 6.0及以上系统在使用危险权限时必须进行运行时权限处理。 main_activity.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://sche…

HDFS的文件块大小(重点)

HDFS 中的文件在物理上是分块存储 &#xff08;Block &#xff09; &#xff0c; 块的大小可以通过配置参数( dfs.blocksize&#xff09;来规定&#xff0c;默认大小在Hadoop2.x/3.x版本中是128M&#xff0c;1.x版本中是64M。 如果一个文件文件小于128M&#xff0c;该文件会占…

【C#】并行编程实战:使用 Visual Studio 调试任务

并行编程可以提高应用程序的性能&#xff0c;但是调试起来会更困难&#xff0c;这一点在之前的章节中我们已经有了很直观的感受。对于程序而言&#xff0c;保证程序的正确性和保证性能同样重要。 本章将介绍可以在 Visual Studio 中的调试工具&#xff08;包括 Thread 窗口、Ta…

Qt Core学习日记——第三天QMetaEnum(上)

QMetaEnum用来代表枚举信息,内部也是访问moc文件。从moc文件中得到对应值 需要在头文件中声明 Q_ENUM,如下红框部分 moc中qt_meta_stringdata_XTest变为&#xff1a; qt_meta_data_XTest变为 static const uint qt_meta_data_XTest[] { // content: 8, // revision 0, // …

(二)RabbitMQ【安装Erlang、安装RabbitMQ 、账户管理、管控台、Docker安装 】

Lison <dreamlison163.com>, v1.0.0, 2023.06.22 RabbitMQ【安装Erlang、安装RabbitMQ 、账户管理、管控台、Docker安装 】 文章目录 RabbitMQ【安装Erlang、安装RabbitMQ 、账户管理、管控台、Docker安装 】**安装Erlang**安装RabbitMQ账户管理管控台Docker安装RabbitM…

打家劫舍系列

class Solution { public:int dp[105];//dp[i]表示偷取前i个房间获取的最大值int rob(vector<int>& nums) {// // dp[i][0];不偷取第i间房&#xff0c;偷取前i-1间房的最大值// //dp[i][1];偷取第i间房&#xff0c;偷取前i间房的最大值// memset(dp,0,siz…

案例研究|DataEase助力亚加达智能医学实验室场景BI展示

深圳市亚加达信息技术有限公司&#xff08;以下简称为亚加达&#xff09;成立于2018年&#xff0c;是一家专注于医疗信息系统研发的高科技公司&#xff0c;隶属于亚辉龙集团。 亚加达深入理解医疗实验室业务和日常工作流程&#xff0c;通过物联网和大数据技术&#xff0c;基于…

ubuntu环境安装centos7虚拟机网络主机不可达,ping不通

【NAT模式下解决】1.首先vi /etc/sysconfig/network-scripts/ifcfg-ens33检查ONBOOTyes&#xff0c;保存 2.输入systemctl restart network命令重启网关

GBASE南大通用出席CCF第38届中国计算机应用大会

在数据要素市场化分论坛上&#xff0c;GBASE南大通用高级副总裁赵伟发表“以自主可控的国产基础软件新兴技术保障数据要素安全高效流通”的主题演讲&#xff0c;向参会嘉宾分享基于GBASE数据库的自主可控国产软件&#xff0c;保障数据要素安全流通、高效流转的创新实践。 赵伟讲…

Maven学习笔记

Maven学习笔记 一、MAVEN基础1.1、Maven作用1.2、Maven基础概念1.2.1、仓库1.2.2、坐标1.2.2、仓库配置 1.3、 手动写一个maven程序1.4、依赖管理1.5、生命周期与插件1.5.1、构建生命周期1.5.2、插件 一、MAVEN基础 1.1、Maven作用 Maven的本质是一个项目管理工具&#xff0c…

王道考研数据结构--4.3链队列

目录 前言 1.链队列的定义 2.链队列的结构 3.链队列的操作 3.1定义链队列 3.2初始化 3.3入队 3.4出队 3.5遍历求表长 3.6清空&#xff0c;销毁 4.完整代码 前言 日期&#xff1a;2023.7.25 书籍&#xff1a;2024年数据结构考研复习指导&#xff08;王道考研系列&…

Cesium态势标绘专题-自由多边形(标绘)

标绘专题介绍:态势标绘专题介绍_总要学点什么的博客-CSDN博客 入口文件:Cesium态势标绘专题-入口_总要学点什么的博客-CSDN博客 辅助文件:Cesium态势标绘专题-辅助文件_总要学点什么的博客-CSDN博客 本专题没有废话,只有代码,代码中涉及到的引入文件方法,从上面三个链…

蓝桥杯专题-真题版含答案-【加法变乘法】【三羊献瑞】【交换瓶子】【卡片换位】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

力扣 56. 合并区间

题目来源&#xff1a;https://leetcode.cn/problems/merge-intervals/description/ C题解&#xff1a;根据左区间排序&#xff0c;更新每一段的右区间最大值&#xff0c;直到间断。 class Solution { public:static bool cmp(vector<int> & a, vector<int> &a…

PHP 药店管理系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP 药品管理系统 是一套完善的web设计系统,系统采用smarty框架进行开发设计&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 PHP 药店管理系统mysql数据库web结构apache计 下载地址…

Python实现九宫格数独小游戏

1 问题 有1-9个数字&#xff0c;将他们填入一个3*3的九宫格中&#xff0c;使得他们的每行&#xff0c;每列&#xff0c;以及对角线上的和相等&#xff0c;且要求每个格子的数字不可以重复。使用python列出所有可能的组合。示例如下: 2 方法 每行&#xff0c;列&#xff0c;对角…

Tomcat 的使用(图文教学)

Tomcat 的使用&#xff08;图文教学&#xff09; 前言一、什么是Tomcat&#xff1f;二、Tomcat 服务器和 Servlet 版本的对应关系三、Tomcat 的使用1、安装2、目录介绍3、如何启动4、Tomcat 的停止5、如何修改 Tomcat 的端口号6、如何部暑 web 工程到 Tomcat 中6.1 方式一6.2 …