当前位置: 首页 > news >正文

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命令处理是单线程,而不采用多线程

  1. redis支持多种数据结构(如string、list、hash、set、zset等),每个对象类型都是由多个数据结构实现的。因此多线程环境下,加锁复杂、锁粒度不好控制。
  2. 频繁的上下文切换,会带来更多的时间和性能上的开销,从而抵消多线程的优势。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采用了以下机制

  1. redis是内存数据库,数据存储在内存中,可以高效地访问。
  2. redis使用hash table的数据组织方式,查询数据的时间复杂度为 O ( 1 ) O(1) O(1),能快速查找数据。
  3. redis采用了高效的数据结构,可以根据性能进行数据结构切换,使得执行效率与空间占用保持平衡。
  4. redis使用高效的reactor网络模型。

2.2 优化的措施

  1. redis采用分治的思想,把rehash分摊到之后的每步增删查改的操作当中。同时,在定时器中最大执行1毫秒的rehash,每次步长100个数组槽位。
  2. redis将耗时阻塞的操作,放在其他线程处理。
  3. 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 多路复用技术而不是真正的多线程模型。其基本流程:

  1. redis-server主线程作为生产者:
    ∙ \bullet 当有新的客户端连接请求到达时,主线程会将对应的客户端套接字加入到clients_pending_read 队列中。这表示该连接上有数据可读,需要被处理。
    ∙ \bullet 当有客户端数据写入请求到达时,主线程会将对应的客户端套接字加入到 clients_pending_write 队列中。这表示该连接上可以进行写操作。
  2. redis-server主线程作为消费者:
    ∙ \bullet 主线程通过循环遍历 clients_pending_read 队列中的客户端套接字,并将其分配给合适的 I/O 线程处理。主线程会根据负载均衡策略(如轮询或哈希)来决定将客户端套接字分发给哪个 I/O 线程的专属队列。
    ∙ \bullet 类似地,主线程也会从 clients_pending_write 队列中获取客户端套接字,并将其分配给适当的 I/O 线程处理。
  3. 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 框架&#xff0c;运行在宿主平台之上&#xff0c;Flutter 本身是无法提供一些系统能力&#xff0c;比如使用蓝牙、相机、GPS等&#xff0c;因此要在 Flutter 中调用这些能力就必须和原生平台进行通信。 实现…...

重排链表——力扣143

文章目录 题目描述法一&#xff1a;寻找链表中点、链表逆序、链表合并 题目描述 法一&#xff1a;寻找链表中点、链表逆序、链表合并 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&#xff08;不符合实情&#xff0c;很多时候是查库获取的变量值&#xff09;使用原子类存储变量&#xff0c;保证一致性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对代理模式的理解 场景&#xff1a;拍电影的时候&#xff0c;替身演员去代理演员完成表演。这就是一个代理模式。 演员为什…...

桥梁安全生命周期监测解决方案

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

图技术在 LLM 下的应用:知识图谱驱动的大语言模型 Llama Index

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

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...