redis线程模型
文章目录
- 一、redis单线程模型
- 1.1 为什么redis命令处理是单线程,而不采用多线程
- 1.2 单线程的局限及redis的优化方式
- 二、redis单线程为什么这么快
- 2.1 采用的机制
- 2.2 优化的措施
- 三、redis的IO多线程模型
- 3.1 redis 为什么引入IO多线程模型
- 3.2 配置io-threads-do-reads
- 3.3 流程
一、redis单线程模型
首先需要注意的是,redis整体而言并不是单线程。
redis-server是主线程,所说的redis是单线程主要指redis-server这个线程,用于处理命令。
所谓的redis单线程,指的是命令处理、逻辑处理在一个单线程中。即【接收客户端请求–>解析请求 -->进行数据读写等操作–>发送数据给客户端】这个过程是由一个线程(主线程)来完成的。
redis 6.0 版本之前的单线模式
图中的蓝色部分是一个事件循环,是由主线程负责的,可以看到网络 I/O 和命令处理都是单线程。
1.1 为什么redis命令处理是单线程,而不采用多线程
- redis支持多种数据结构(如string、list、hash、set、zset等),每个对象类型都是由多个数据结构实现的。因此多线程环境下,加锁复杂、锁粒度不好控制。
- 频繁的上下文切换,会带来更多的时间和性能上的开销,从而抵消多线程的优势。redis作为数据库,并不是每时每刻都有密集访问。在多线程环境下,访问少时需要将一些线程休眠,访问多时又需要唤醒,这就存在频繁的线程调度问题。
1.2 单线程的局限及redis的优化方式
单线程最大的局限,在于不能有耗时操作,即阻塞IO、CPU运算时间比较长的任务等。这会影响redis的响应性能。
redis的耗时操作以及其解决优化方式:
1)IO密集型 —— 磁盘IO : redis提供了类似于日志备份的 aof(Append-Only File)方式以支持持久化,也就是对数据的更改操作需要刷新落到磁盘里。针对这个耗时操作,redis有两种优化方法:1、rdb(Redis Database)文件:redis会fork一个子进程,在子进程中进行持久化,不占用主线程的资源。2、aof持久化策略:redis会创建bio_aof_fsync线程进程异步刷盘。
2)IO密集型 —— 网络IO :当redis服务多个客户端时,如果数据请求或返回数据量比较大时,造成了IO密集型的情况,也是比较耗时的操作。对比,redis通过开启IO多线程(io_thd_*线程)来处理网络IO。
3)CPU密集型:redis支持丰富的数据结构,而有些数据结构操作的事件复杂度比较高,就可能会导致CPU花费大量的时间去计算。对比,redis采用分治的方式。
二、redis单线程为什么这么快
2.1 采用的机制
redis采用了以下机制
- redis是内存数据库,数据存储在内存中,可以高效地访问。
- redis使用hash table的数据组织方式,查询数据的时间复杂度为 O ( 1 ) O(1) O(1),能快速查找数据。
- redis采用了高效的数据结构,可以根据性能进行数据结构切换,使得执行效率与空间占用保持平衡。
- redis使用高效的reactor网络模型。
2.2 优化的措施
- redis采用分治的思想,把rehash分摊到之后的每步增删查改的操作当中。同时,在定时器中最大执行1毫秒的rehash,每次步长100个数组槽位。
- redis将耗时阻塞的操作,放在其他线程处理。
- redis针对不同的对象类型采用不同的数据结构实现。比如string对象针对不同的数据长度,有int、raw、embstr三种编码方式。
127.0.0.1:6379> set name jack
OK
127.0.0.1:6379> OBJECT encoding name
"embstr"
127.0.0.1:6379> set name "1001"
OK
127.0.0.1:6379> OBJECT encoding name
"int"
127.0.0.1:6379> set name 123456789012345678901234567890123456789012345678901234567890
OK
127.0.0.1:6379> OBJECT encoding name
"raw"
三、redis的IO多线程模型
3.1 redis 为什么引入IO多线程模型
在 redis 6.0 版本之后,也采用了多个 I/O 线程来处理网络请求,这是因为随着网络硬件的性能提升,redis 的性能瓶颈有时会出现在网络 I/O 的处理上。所以为了提高网络 I/O 的并行度,Redis 6.0 对于网络 I/O 采用多线程来处理。但是对于命令的执行,Redis 仍然使用单线程来处理。
即多线程处理网络IO(read、decode和encode、send阶段)。主线程使用单线程,执行命令处理业务逻辑(因为 redis 采用高效的数据结构,其业务逻辑处理较快,所以用单线程即可)。
3.2 配置io-threads-do-reads
io-threads-do-reads是 redis.conf 文件中的一个配置选项,用于控制 I/O 线程是否执行读取操作。
默认情况下 I/O 多线程只针对发送响应数据( encode, send),并不会以多线程的方式处理读请求( read, decode)。要想开启多线程处理客户端读请求,就需要把 Redis.conf 配置文件中的 io-threads-do-reads 配置项设为 yes。
//读请求也使用io多线程
io-threads-do-reads yes // io-threads N,表示启用 N-1 个 I/O 多线程(主线程也算一个 I/O 线程)
io-threads 4
当将 io-threads-do-reads 设置为 “yes” 时,I/O 线程将负责处理客户端请求的读取操作。这意味着 I/O 线程可以直接从套接字中读取数据,并进行相应的处理,而无需等待主线程来分发任务。
使用 io-threads-do-reads 的好处是能够减轻主线程的负担,提高系统的并发性能和响应速度。通过将读取操作分配给专门的 I/O 线程,可以使主线程更专注于处理其他的任务,如写入操作、协议解析和业务逻辑等。
3.3 流程
对于 redis 来说,它采用的是 I/O 多路复用技术而不是真正的多线程模型。其基本流程:
- redis-server主线程作为生产者:
∙ \bullet ∙ 当有新的客户端连接请求到达时,主线程会将对应的客户端套接字加入到clients_pending_read 队列中。这表示该连接上有数据可读,需要被处理。
∙ \bullet ∙ 当有客户端数据写入请求到达时,主线程会将对应的客户端套接字加入到 clients_pending_write 队列中。这表示该连接上可以进行写操作。 - redis-server主线程作为消费者:
∙ \bullet ∙ 主线程通过循环遍历 clients_pending_read 队列中的客户端套接字,并将其分配给合适的 I/O 线程处理。主线程会根据负载均衡策略(如轮询或哈希)来决定将客户端套接字分发给哪个 I/O 线程的专属队列。
∙ \bullet ∙ 类似地,主线程也会从 clients_pending_write 队列中获取客户端套接字,并将其分配给适当的 I/O 线程处理。 - I/O 线程执行任务:
∙ \bullet ∙ 每个 I/O 线程拥有一个专属队列(如 io_threads_list[id]),主线程将客户端套接字分配给指定的 I/O 线程,并将其加入到对应的队列中。
∙ \bullet ∙ I/O 线程通过从自己的队列中获取客户端套接字,进行实际的读写操作和请求处理。一旦完成操作,也可以将结果返回给主线程。
通过这种队列模型和任务调度方式,主线程在兼顾生产者和消费者角色的同时,能够高效地将任务分发给对应的 I/O 线程进行处理,以提高并发性能和系统的吞吐量。同时,这种设计还能避免多线程并发带来的同步问题和竞争条件,保证了系统的稳定性和可靠性。
相关文章:

redis线程模型
文章目录 一、redis单线程模型1.1 为什么redis命令处理是单线程,而不采用多线程1.2 单线程的局限及redis的优化方式 二、redis单线程为什么这么快2.1 采用的机制2.2 优化的措施 三、redis的IO多线程模型3.1 redis 为什么引入IO多线程模型3.2 配置io-threads-do-read…...

【idea工具】idea工具,build的时候提示:程序包 com.xxx.xx不存在的错误
idea工具,build的时候提示:程序包 com.xxx.xx不存在的错误,如下图,折腾了好一会, 做了如下操作还是不行,idea工具编译的时候,还是提示 程序包不存在。 a. idea中,重新导入项目,也还…...

线性代数——特征值和特征向量
系列文章目录 线性代数——行列式线性代数——矩阵线性代数——向量线性代数——线性方程组线性代数——特征值和特征向量线性代数——二次型 文章目录 系列文章目录版权声明补充知识求和公式的性质常用希腊字符读音 特征值和特征向量相似矩阵相似对角化实对称矩阵 版权声明 …...

运筹系列83:使用分枝定界求解tsp问题
1. 辅助函数 Node算子用来存储搜索树的状态。其中level等于path的长度,path是当前节点已经访问过的vertex清单,bound则是当前的lb。 这里的bound函数是一种启发式方法,等于当前路径的总长度,再加上往后走两步的最小值。 struct …...

linux 指令 第3期
cat cat 指令: 首先我们知道一个文件内容属性 我们对文件操作就有两个方面:对文件内容和属性的操作 扩展:echo 指令 直接打印echo后面跟的字符串 看: 这其实是把它打印到了显示器上,我们也可以改变一下它的打印位置…...

测试用例实战
测试用例实战 三角形判断 三角形测试用例设计 测试用例编写 先做正向数据,再做反向数据。 只要有一条边长为0,那就是不符合要求,不需要再进行判断,重复。 四边形 四边形测试用例...

Unity XML1——XML基本语法
一、XML 概述 全称:可拓展标记语言(EXtensible Markup Language) XML 是国际通用的,它是被设计来用于传输和存储数据的一种文本特殊格式,文件后缀一般为 .xml 我们在游戏中可以把游戏数据按照 XML 的格式标…...

了解Unity编辑器之组件篇Playables和Rendering(十)
Playables 一、Playable Director:是一种用于控制和管理剧情、动画和音频的工具。它作为一个中央控制器,可以管理播放动画剧情、视频剧情和音频剧情,以及它们之间的时间、顺序和交互。 Playable Director组件具有以下作用: 剧情控…...

python的包管理器pip安装经常失败的解决办法:修改pip镜像源
pip 常用的国内镜像源: https://pypi.tuna.tsinghua.edu.cn/simple/ // 清华 http://mirrors.aliyun.com/pypi/simple/ // 阿里云 https://pypi.mirrors.ustc.edu.cn/simple/ // 中国科技大学 http://pypi.hustunique.com/ // 华中理…...

忘记安卓图案/密码锁如何解锁?
如何解锁Android手机图案锁?如何删除忘记的密码?Android 手机锁定后如何重置?这是许多智能手机用户在网上提出的几个问题。为了回答这些问题,我们想出了一些简单有效的方法来解锁任何设备而不丢失数据。 忘记手机密码可能会令人恐…...

Bash编程
目录: bash编程语法bash脚本编写 1.bash编程语法 Bash 编程基础 变量引号数组控制语句函数 Bash 变量 语法: Variable_namevalue Bash 变量定义的规则 变量名区分大小写,a和A为两个不同的变量。变量名可以使用大小写字母混编的形式进行…...

vue指令-v-model修饰符
vue指令-v-model修饰符 1、目标2、语法 1、目标 让v-modelv-mode拥有更强大的功能 2、语法 v-model.修饰符“Vue数据变量” .number 以parseFloat转成数字类型 .trime 去除首位空白字符 .lazy 在change时触发而非input时示例1 <template><div id"app"&g…...

【论文精读CVPR_2023】3D-Aware Face Swapping
【论文精读CVPR_2023】3D-Aware Face Swapping 前言Abstract1. Introduction2. Related WorkFace Swapping.3D-Aware Generative Models.GAN Inversion.3. Method3.1. Overview3.2. Inferring 3D Prior from 2D Images3.3. Face Swapping via Latent Code Manipulation3.4. Joi…...

flutter开发实战-自定义相机camera功能
flutter开发实战-自定义相机camera功能。 Flutter 本质上只是一个 UI 框架,运行在宿主平台之上,Flutter 本身是无法提供一些系统能力,比如使用蓝牙、相机、GPS等,因此要在 Flutter 中调用这些能力就必须和原生平台进行通信。 实现…...

重排链表——力扣143
文章目录 题目描述法一:寻找链表中点、链表逆序、链表合并 题目描述 法一:寻找链表中点、链表逆序、链表合并 void reorderList(ListNode* head){if(headnullptr){return;}// 找到中点 ListNode* mid FindMiddle(head);ListNode *h1head, *h2mid->ne…...

Lambda表达式常见的Local variable must be final or effectively final原因及解决办法
目录 Local variable must be final or effectively final错误原因 解决办法按照要求定义为final(不符合实情,很多时候是查库获取的变量值)使用原子类存储变量,保证一致性AtomicReference常用原子类 其它 Local variable must be …...

YOLOv5改进系列(16)——添加EMA注意力机制(ICASSP2023|实测涨点)
【YOLOv5改进系列】前期回顾: YOLOv5改进系列(0)——重要性能指标与训练结果评价及分析 YOLOv5改进系列(1)——添加SE注意力机制 YOLOv5改进系列(2)——添加...

[SSM]GoF之代理模式
目录 十四、GoF之代理模式 14.1对代理模式的理解 14.2静态代理 14.3动态代理 14.3.1JDK动态代理 14.3.2CGLIB动态代理 十四、GoF之代理模式 14.1对代理模式的理解 场景:拍电影的时候,替身演员去代理演员完成表演。这就是一个代理模式。 演员为什…...

桥梁安全生命周期监测解决方案
一、方案背景 建筑安全是人们生产、经营、居住等经济生活和人身安全的基本保证,目前我国越来越多的建筑物逐 步接近或者已经达到了使用年限,使得建筑物不断出现各种安全隐患,对居民的人身安全和财产安全产 生不利影响,因此房…...

图技术在 LLM 下的应用:知识图谱驱动的大语言模型 Llama Index
LLM 如火如荼地发展了大半年,各类大模型和相关框架也逐步成型,可被大家应用到业务实际中。在这个过程中,我们可能会遇到一类问题是:现有的哪些数据,如何更好地与 LLM 对接上。像是大家都在用的知识图谱,现在…...

SpringBoot自动配置、启动器原理爆肝解析(干货满满)
文章目录 前言一、SpringBoot优势概要二、SpringBoot自动配置1. ☠注意☠2.自动配置详解 三、Starter(场景启动器)原理总结 前言 本文详细解析面试重点—SpringBoot自动配置原理、场景启动器原理,深入源码,直接上干货、绝不拖泥带…...

chrome扩展控制popup页面动态切换
文章目录 1、通过控制元素的显示隐藏达到popup页面切换的效果2、通过监听页面重新加载完成不同popup的切换3、直接修改popup页面location.href,无需刷新页面 1、通过控制元素的显示隐藏达到popup页面切换的效果 下面在mv2版本的API下完成 实际上通过控制页面元素实…...

【AI】《动手学-深度学习-PyTorch版》笔记(三):PyTorch常用函数
AI学习目录汇总 1、torch.arange 返回一维张量(一维数组),官网说明,常见的三种用法如下 输入:torch.arange(5) 输出:tensor([0, 1, 2, 3, 4]) 输入:torch.arange(5, 16) 输出:tensor([ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) 输入:torch.arange(1, 25, 2) …...

某文化馆三维建模模型-glb格式-三维漫游-室内导航测试
资源描述 某文化馆某个楼层的三维建模模型,glb格式,适用于three.js开发,可用来做一些三维室内漫游测试和室内导航测试 资源下载地址...

网络安全 Day19-计算机网络基础知识04(网络协议)
计算机网络基础知识04(网络协议) 1. ARP1.1 ARP通讯原理1.2 arp欺骗1.3 ARP欺骗与预防1.4 排查ARP病毒 2. DHCP工作原理(自动分配内网IP)3. TCP协议三次握手、四次挥手原理4. DNS协议工作原理 1. ARP Linux查看arp:ar…...

Verilog语法学习——LV5_位拆分与运算
LV5_位拆分与运算 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 题目描述: 现在输入了一个压缩的16位数据,其实际上包含了四个数据…...

❤️创意网页:创意动态画布~缤纷移动涂鸦~图片彩色打码
✨博主:命运之光 🌸专栏:Python星辰秘典 🐳专栏:web开发(简单好用又好看) ❤️专栏:Java经典程序设计 ☀️博主的其他文章:点击进入博主的主页 前言:欢迎踏入…...

数值分析第六章节 用Python实现解线性方程组的迭代法
参考书籍:数值分析 第五版 李庆杨 王能超 易大义编 第5章 解线性方程组的迭代法 文章声明:如有发现错误,欢迎批评指正 文章目录 迭代法的基本概念雅可比迭代法与高斯-塞格尔迭代法雅可比迭代法高斯-塞格尔迭代法 迭代法的基本概念 6.1.1引言…...

【低代码专题方案】使用iPaaS平台下发数据,快捷集成MDM类型系统
01 场景背景 伴随着企业信息化建设日趋完善化、体系化,使用的应用系统越来越多,业务发展中沉淀了大量数据。主数据作为数据治理中枢,保存大量标准数据库,如何把庞大的数据下发到各个业务系统成了很棘手的问题。 传统的数据下发方…...

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