论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com
»
论坛
›
数据库
›
SQL-Server
›
【Redis】Redis线程与IO模子—(三)
【Redis】Redis线程与IO模子—(三)
万有斥力
论坛元老
|
2024-8-21 10:11:36
|
显示全部楼层
|
阅读模式
楼主
主题
1010
|
帖子
1010
|
积分
3030
一、Redis 单线程
通常说 Redis 是单线程,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,其他功能,好比持久化、异步删除、集群数据同步等,是由额外的线程执行的,所以严格来说,Redis 并不是单线程。
多线程开辟会不可避免的带来并发控制和资源开销的问题,如果没有良好的体系设计往往会适得其反,为了避免这些问题,Redis 直接采取了单线程模式。
Redis 单线程模子能到达每秒数十万级别的处理能力,一方面是大部门操作在内存上完成 + 高效的数据布局,例如哈希表和跳表。另一方面,就是采取了多路复用机制,使其在网络 IO 操作中能并发处理大量的客户端哀求,实现高吞吐率。
在了解多路复用之前,要先明白网络操作的基本 IO 模子和潜伏的阻塞点。如果单线程被阻塞了,就无法举行多路复用了。以 Get 哀求为例如下图,bind/listen、accept、recv、parse 和 send 属于网络 IO 处理,get 属于键值数据操作。
这里的网络 IO 操作中,潜伏的阻塞点分别是 accept() 和 recv()。当 Redis 监听到一个客户端有连接哀求,但一直未能成功建立起连接时,会阻塞在 accept() 函数这里,导致其他客户端无法和 Redis 建立连接。雷同的,当 Redis 通过 recv() 从一个客户端读取数据时,如果数据一直没有到达,Redis 也会一直阻塞在 recv(),这就导致 Redis 整个线程阻塞,无法处理其他客户端哀求,效率很低。不外,Socket 网络模子可以设置非阻塞模式,基于此 Linux 中的 IO 多路复用机制就要登场了。
二、多路复用机制
Linux 中的 IO 多路复用机制是指一个线程处理多个 IO 流,就是我们经常听到的 select/epoll 机制。简单来说,在 Redis 只运行单线程的情况下,该机制允许内核中,同时存在多个监听套接字和已连接套接字。内核会一直监听这些套接字上的连接哀求或数据哀求。一旦有哀求到达,就会交给 Redis 线程处理,这就实现了一个 Redis 线程处理多个 IO 流的结果。
图中的多个 FD 就是指多个套接字,Redis 网络框架调用 epoll 机制,让内核监听这些套接字。此时,Redis 线程不会阻塞在某一个特定的监听或已连接套接字上,所以,Redis 可以同时和多个客户端连接并处理哀求,从而提升并发性。
为了在哀求到达时能关照到 Redis 线程,select/epoll 提供了基于事件的回调机制,即针对不同事件的发生,调用相应的处理函数,select/epoll 一旦监测到 FD 上有哀求到达时,就会触发相应的事件。这些事件会被放进一个事件队列,Redis 单线程对该事件队列不断举行处理。这样一来,Redis 无需一直轮询是否有哀求实际发生,这就可以避免造成 CPU 资源浪费。同时,Redis 在对事件队列中的事件举行处理时,会调用相应的处理函数,这就实现了基于事件的回调。由于 Redis 一直在对事件队列举行处理,所以能及时响应客户端哀求,提升 Redis 的响应性能。
三、Redis 6.0 多线程特性
Redis 6.0 之前,固然有些命令操作可以用后台线程或子进程执行(好比数据删除、快照天生、AOF 重写),但是,从网络 IO 处理到实际的读写命令处理,都是由单个线程完成的,有时会成为 Redis 的性能瓶颈。Redis 6.0 之后采取多个 IO 线程来处理网络哀求,进步网络哀求处理的并行度,对于读写命令,仍旧利用单线程来处理。
详细流程:
(1)
主线程吸收到客户端连接哀求后创建连接,将 Socket 放入全局等待队列中,通过轮询分配给 IO 线程。
(2)
分配后主线程就会进入阻塞状态,等待 IO 线程完成客户端哀求读取和解析,多个 IO 线程在并行处理,嗖嗖嗖
。
(3)
IO 线程解析完哀求,主线程还是会以单线程的方式执行这些命令操作。
(4)主线程执行完哀求操作后,把返回结果写入缓冲区,主线程阻塞等待 IO 线程把这些结果回写到 Socket 中,并返回给客户端。
和 IO 线程读取和解析哀求一样,IO 线程回写 Socket 时,也是有多个线程在并发执行,所以回写 Socket 的速度也很快。等到 IO 线程回写 Socket 完毕,主线程会清空全局队列,等待客户端的后续哀求。
四、IO 多线程设置
在实际应用中,如果 Redis 实例的 CPU 开销不大,吞吐量却没有提升,可以考虑利用多线程机制提升吞吐量,redis.conf 中设置:
设置 io-thread-do-reads 设置项为 yes,表现启用多线程
io-threads-do-reads yes
复制代码
设置线程个数要小于 Redis 实例所在机器的 CPU 核个数,例如,对于一个 8 核的机器来说,Redis 官方发起设置 6 个 IO线程
io-threads 6
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
正序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
发新帖
回复
万有斥力
论坛元老
这个人很懒什么都没写!
楼主热帖
MyBatis-Plus入门教程及基本API使用案 ...
深度理解 C# 中的 for 和 foreach ...
OpenJDK和OracleJDK的区别说明
几个函数的使用例子:更新VBRK-XBLNR, ...
EFCore 动态拼接查询条件(表达式树方式 ...
阿里巴巴Java开发手册(全册四版) ...
.net 发邮件的小工具,包含json,环境 ...
2022年混过的那些SAP项目
Excel 制作可视化看板的思路及操作 ...
MySQL分区表对NULL值的处理
标签云
AI
运维
CIO
存储
服务器
浏览过的版块
Oracle
Java
快速回复
返回顶部
返回列表