[编程技术] 一文看懂Redis 6.0多线程IO
作者:CC下载站 日期:2021-12-09 00:00:51 浏览:5 分类:编程开发
Redis基础
Redis是什么
Redis是一个基于BSD开源的项目,是一个把结构化的数据放在内存中的一个存储系统。
你可以把它作为数据库,缓存和消息中间件来使用。同时支持strings
,lists
,hashes
,sets
,sorted sets
,bitmaps
,hyperloglogs
和geospatial indexes
等数据类型。
它还通过redis sentinel实现高可用,通过redis cluster实现了自动分片。以及事务,发布/订阅,自动故障转移等等。
为什么用Redis
而在后端开发的技术选型中,Redis已经成为了一个不可绕过的解决方案工具。因此Redis成为了后端开发的基本技能之一。当然,也是后端面试中必考的技术栈之一。
Redis的优点,如果只用一个字来解释,那就是:快!
Redis 有多快?官方给出的答案是读写速度 10万/秒,如果说这是在单线程情况下跑出来的成绩,你会不会惊讶?为什么单线程的 Redis 速度这么快?
Redis为什么快
主要有以下几点:
- Redis 是基于内存的。 内存的读写速度非常快。当然Redis也存在持久化操作,但是是fork子进程和利用 Linux 系统的页缓存技术来完成,并不会影响Redis的读写性能。
- Redis 是单线程的。 避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。
- Redis 使用多路复用技术。 可以处理并发的连接。非阻塞 IO 部实现采用 epoll,采用了 epoll+自己实现的简单的事件框架。epoll 中的读、写、关闭、连接都转化成了事件,然后利用 epoll 的多路复用特性,绝不在 IO 上浪费一点时间。
- Redis 中的数据结构是专门进行设计的。 数据结构简单。对数据操作也简单。
Redis是单线程的吗
我们经常听到,Redis是单线程的,这句话对吗?
基本上是对的,但是不准确。
而对于为什么使用单线程,官方有一句解释:
It’s not very frequent that CPU becomes your bottleneck with Redis, as usually Redis is either memory or network bound.
意思就是:
因为 Redis 是基于内存的操作,CPU 不是 Redis 的瓶颈。Redis 的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且 CPU 不会成为瓶颈,那就顺理成章地采用单线程的方案了。
为什么说不准确呢?
我们需要回顾Redis的两个最重要的版本更新:
-
Redis 4.0
为了防止耗时的命令阻塞线程,导致无法处理后续事件。引入了多线程来处理一些非阻塞命令。有:UNLINK
、FLUSHALL ASYNC
、FLUSHDB ASYNC
等。
但是整个网络模型依然是单线程的,所以我们称之为单线程。 -
Redis 6.0
就真正的在网络模型上加入多线程IO
来解决网络IO的性能瓶颈。 此时IO读写是多线程的,执行命令依旧是单线程的。
Redis网络模型
一张图看懂Redis的单线程模型:
redis的网络事件处理器是基于Reactor模式,又叫做文件事件处理器。
文件事件处理器
使用I/O多路复用
来同时监听多个套接字,并根据套接字执行的任务关联到不同的事件处理器。
文件事件以单线程方式运行,但通过使用I/O多路复用
程序来监听多个套接字,文件事件处理器
实现了高性能的网络通信模型。
Redis 在处理客户端的请求时,包括接收
(socket读)、解析
、执行
、发送
(socket 写) 等都由一个顺序串行的主线程处理,这就是所谓的单线程
。
Reactor模型
Redis的单线程网络模型,这就是一个经典的Reactor的模型,其本质上是 I/O 多路复用(I/O multiplexing) + 非阻塞 I/O(non-blocking I/O)
的模式。
是一种基于事件驱动模型的设计模式。
我们来看一下Reactor里面两种经典的模型。
单线程Reactor模型
Redis的单线程模型就是使用的经典的单线程Reactor模型。
我们先看看单线程的Reactor模型
消息处理流程:
- Reactor对象通过
select/poll/epoll
等IO多路复用监控连接事件,收到事件后通过dispatcher
事件分发器进行转发。 - 如果是连接建立的事件,则由
acceptor
接受连接,并创建Handler
处理后续事件。 - 如果不是建立连接事件,则Reactor会分发调用
Handler
来响应。 - Handler会完成
read->解析->执行->send
的完整业务流程。
优点:
- 单线程运行,串行操作,不需要加锁,逻辑简单。
缺点:
- 仅用一个线程处理请求,对于多核资源机器来说是有点浪费的。
- 当处理读写任务的线程负载比较重,将会阻塞后续的事件处理,导致整体延迟变大。
应用:
- Redis网络模型。(6.0版本以前)
Master-Worker Reactor模型
比起单线程模型,它是将Reactor分成两部分:
mainReactor
负责监听server socket,用来处理网络IO连接建立操作,将建立的socketChannel指定注册给subReactor。 (只负责监听)subReactor
主要做和建立起来的socket做数据交互和事件业务处理操作。通常,subReactor个数上可与CPU个数等同。一般是多个,这样的话,就可以充分利用多核的优势。 (负责IO读写和命令的执行)
区别于单线程Reactor模式
,这种模式不再是单线程的事件循环,而是有多个线程subReactors
各自维护一个独立的事件循环,由 mainReactor
负责接收新连接并分发给 subReactors
去独立处理,最后 subReactors
回写响应给客户端。
优点:
- 响应快,不必为单个同步时间所阻塞,虽然Reactor本身依然是同步的;
- 可扩展性,可以方便地通过增加Reactor实例个数来充分利用CPU资源;
缺点:
- 如果多个线程可能操作同一份数据,就涉及到底层数据同步的问题,则必然会引入某些同步机制,比如锁。增加了代码复杂度,同时增加了同步机制的开销。
应用:
- Nginx, Netty, Swoole, Memcached就是使用的这个模型
Redis 6.0的多线程网络模型
Redis 6.0版本之后,Redis 正式在核心网络模型中引入了多线程,也就是所谓的 I/O threading
,至此 Redis 真正拥有了多线程模型。
但是Redis的多线程模型却并非标准的Master-Worker Reactor
模型。他的多线程 只负责IO读写,不负责具体的执行。
为什么Redis 6.0 要使用多线程
之前说了,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存大小和网络带宽。
从Redis自身角度来说,因为读写网络的read/write
系统调用占用了Redis执行期间大部分CPU时间,瓶颈主要在于网络的 IO 消耗, 所以选择多线程IO来实现读写。主线程来执行Redis命令。
总结就是:
将主线程 IO 读写任务拆分出来给一组独立的线程处理,使得多个 socket 读写可以并行化,但是 Redis 命令还是主线程串行执行。
Redis 6.0 网络模型
为什么这么设计呢?
- 前面提到 Redis 最初选择单线程网络模型的理由是:CPU 通常不会成为性能瓶颈,瓶颈往往是内存和网络,因此单线程足够了。那么为什么现在 Redis 又要引入多线程呢?很简单,就是 Redis 的
网络 I/O 瓶颈
已经越来越明显了。所以这个多线程是为了解决IO的瓶颈
的。 - 如果多线程包括了
IO读写,解析和执行
的整个过程,那么多线程需要面临线程安全的问题,Redis 6.0版本之前是没有考虑线程安全的,如果使用多线程来处理命令的执行,需要大量的改动来保证多线程的安全机制,实现更复杂。为了避免了不必要的上下文切换和竞争条件,多线程导致的切换而消耗 CPU,也不用考虑各种锁的问题,就让执行这一步只使用主线程。
Redis 6.0和Memcached多线程模型对比
相同点:
- 都采用了 Master-Worker 的线程的模型
不同点:
- Memcached 执行主逻辑也是在 Worker 线程里,模型更加简单,实现了真正的线程隔离,通过各种锁机制来保证数据的线程安全。
- 而 Redis 把执行逻辑交还给 Master 线程,虽然一定程度上增加了模型复杂度,但也解决了数据的线程安全问题。
总结
让我们来回顾一下 Redis 多线程网络模型的设计方案:
- 使用 I/O 线程实现网络 I/O 多线程化,I/O 线程只负责网络 I/O 和命令解析,不执行具体的命令。
Redis 的多线程网络模型实际上并不是一个标准的 Master-Worker Reactor
模型,Redis 的多线程方案中,I/O 线程任务仅仅是通过 socket 读取客户端请求命令并解析,却没有真正去执行命令。
所有客户端命令最后还需要回到主线程去执行
,因此对多核的利用率并不算高,而且每次主线程都必须在分配完任务之后忙轮询等待所有 I/O 线程完成任务之后才能继续执行其他逻辑。
Redis 目前的多线程方案更像是一个折中的选择:既保持了原系统的兼容性,又能利用多核提升 I/O 性能,来解决网络IO的性能瓶颈。
<全文完>
猜你还喜欢
- 03-29 [编程相关] Winform窗体圆角以及描边完美解决方案
- 03-29 [前端问题] has been blocked by CORS policy跨域问题解决
- 03-29 [编程相关] GitHub Actions 入门教程
- 03-29 [编程探讨] CSS Grid 网格布局教程
- 10-12 [编程相关] python实现文件夹所有文件编码从GBK转为UTF8
- 10-11 [编程算法] opencv之霍夫变换:圆
- 10-11 [编程算法] OpenCV Camshift算法+目标跟踪源码
- 10-11 [Python] python 创建 Telnet 客户端
- 10-11 [编程相关] Python 基于 Yolov8 + CPU 实现物体检测
- 03-15 [脚本工具] 使用go语言开发自动化脚本 - 一键定场、抢购、预约、捡漏
- 01-08 [编程技术] 秒杀面试官系列 - Redis zset底层是怎么实现的
- 01-05 [编程技术] 《Redis设计与实现》pdf
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视推荐] 果断收藏!全球恐怖新片,这15部最强
[小说] 《江南作品全集》
[绘画] 油画棒原创作品【绽放】图文教程来咯~
[资料] 非常多行业-工作总结word 共736份,个人部门述职范文,完整内容直接套用
[书籍] 双色球中奖分析与擒号秘技全图解(实用案例全新版)
[课程] 解锁AI未来:14门顶尖的平台付费AI课程全收录
[短剧] 付费短剧 黑料女配霸榜热搜
[书籍] 王阳明:一切心法(合集共2册)【PDF】
[课程] 回医马氏传承班
[电影] 2024年国产动作片《迷雾刺杀》HD国语中字
[资料] [大学期末救急课] 猴博士+高斯课堂+斐多课堂,全集视频合集
[云资源] 价值2万元的老男孩Python教程
[书库] 史上最全摄影书推荐(附700本PDF版打包下载)
[云资源] 花了一千多元买的私人健身教程
[下载工具] Internet Download Manager 6.42.7 (IDM)
[影视] 灌篮高手 WEB-DL版下载/Slam Dunk/スラムダンク/灌篮高手:THE FIRST/灌篮高手电影版 2022 The First Slam Dunk 61.35G
[即时通讯] 腾讯QQ PC版9.7.22.29315去广告绿色纯净版
[开发环境] PhpStorm2023中文激活版v2023.3.3 正式版
[资料] 3000 套电影电视剧 LOGO 宣传片常用音效合集包
[安卓软件] 酷我音乐APP_v10.7.6.4 去广告破解豪华VIP版
[云资源] 价值2万元的老男孩Python教程
[影视] 灌篮高手 WEB-DL版下载/Slam Dunk/スラムダンク/灌篮高手:THE FIRST/灌篮高手电影版 2022 The First Slam Dunk 61.35G
[云资源] 花了一千多元买的私人健身教程
[书库] 史上最全摄影书推荐(附700本PDF版打包下载)
[动画] 北斗神拳(1984) [两季合集] [MKV]
[资料] 抗战阵亡将士资料+续编
[电视剧] 三体 (2024) 全8集 网飞版本 中文字幕 合集
[影视] 三大队 WEB-DL版下载/Endless Journey/请转告局长,三大队任务完成了 2023 三大队 6.7G
[纪录片] 河西走廊【10集 国语 中文字幕 1080P 10.8G MP4】
[安卓软件] OfficeSuite中文版APP v14.2.50872.0破解版
- 最新评论
-
我想看看mw2ddyy 评论于:04-26 好东西阿zfy123123 评论于:04-18 谢谢楼主xiaoqi 评论于:04-12 勿在线解压,勿手机解压,请在电脑上用最新款压缩软件解压!推荐360压缩或者好压CC下载站 评论于:04-10 无法解压啊,客服能不能给个解压教程ravengrey 评论于:04-10 谢谢支持!!CC下载站 评论于:03-26 很棒的资源,感谢分享云体风身 评论于:03-26 感谢分享,好东西云体风身 评论于:03-26 谢谢支持!CC下载站 评论于:03-14 央视精品,感谢付出提供。qwer9009 评论于:03-14
- 热门tag