Redis I/O 多路复用技术原理
引言
Redis 是一个单线程却性能非常好的内存数据库, 主要用来作为缓存系统。 Redis 采用网络 I/O 多路复用技术来保证在多个连接时,系统的高吞吐量(TPS)。
系统吞吐量(TPS)指的是系统在单位时间内可处理的事务的数量,是用于衡量系统性能的重要指标。影响系统吞吐量的因素很多,包括并发数和系统资源(CPU、内存、系统I/O操作、外部接口)等,系统资源等这些因素可以用平均响应时间指标来衡量
五种 I/O 模型
要理解 Redis 采用网络 I/O 多路复用技术,就得先了解五种 I/O 模型,如下:
阻塞 I/O 模型
最传统的一种 I/O 模型,即在读写数据过程中会发生阻塞现象。
当用户线程发出 I/O 请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态(block),用户线程交出 CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除阻塞状态。
举例如下:
data = socket.read();
如果数据没有就绪,用户线程就会一直阻塞在 read 方法。
非阻塞 I/O 模型
当用户线程发起一个 read 操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个 error 时,它就知道数据还没有准备好,于是它可以再次发送 read 操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。
所以事实上,在非阻塞 I/O 模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞 I/O 不会交出 CPU,而会一直占用 CPU,从而导致 CPU 占用率非常高。
多路复用 I/O 模型
多路复用 I/O 模型是目前使用得比较多的 I/O 模型。
在多路复用 I/O 模型中,会有一个线程不断去轮询多个 socket 的状态,只有当 socket 真正有读写事件时,才真正调用实际的 I/O 读写操作。因为在多路复用 I/O 模型中,只需要使用一个线程就可以管理多个 socket,系统不需要建立新的进程或者线程,也不必维护这些线程和进程,并且只有在真正有 socket 读写事件进行时,才会使用 I/O 资源,所以它大大减少了资源占用(如 CPU)。
会思考的你也许会想到,可以采用多线程+ 阻塞 I/O 达到类似的效果,但是由于在多线程 + 阻塞 I/O 中,每个 socket对应一个线程,这样会造成很大的资源占用,并且尤其是对于长连接来说,线程的资源一直不会释放,如果后面陆续有很多连接的话,就会造成性能上的瓶颈。
而多路复用 I/O 模式,通过一个线程就可以管理多个 socket,只有当 socket 真正有读写事件发生才会占用资源来进行实际的读写操作。因此,多路复用IO比较适合连接数比较多的情况。
另外,多路复用 I/O 为何比非阻塞 I/O 模型的效率高是因为在非阻塞 I/O 中,不断地询问 socket 状态时通过用户线程去进行的,而在多路复用 I/O 中,轮询每个 socket 状态是内核在进行的,这个效率要比用户线程要高的多。
值得注意的是,多路复用 I/O 模型是通过轮询的方式来检测是否有事件到达,并且对到达的事件逐一进行响应。因此对于多路复用 I/O 模型来说,一旦事件响应太慢,那么就会导致后续的事件迟迟得不到处理,并且会影响新的事件轮询。
这就是说,如果 Redis 每条命令执行如果占用大量时间,就会造成其他线程阻塞,对于 Redis 这种高性能服务是致命的,所以 Redis 是面向高速执行的数据库。
信号驱动 I/O 模型
在信号驱动 I/O 模型中,当用户线程发起一个 I/O 请求操作,会给对应的 socket 注册一个信号函数,然后用户线程会继续执行,当内核数据就绪时会发送一个信号给用户线程,用户线程接收到信号之后,便在信号函数中调用 I/O 读写操作来进行实际的 I/O 请求操作。
这个一般用于 UDP 中,对 TCP 套接口几乎是没用的,原因是该信号产生得过于频繁,并且该信号的出现并没有告诉我们发生了什么事情。
异步 I/O 模型
异步 I/O 模型才是最理想的 I/O 模型,在异步 I/O 模型中,当用户线程发起 read 操作之后,立刻就可以开始去做其它的事。而另一方面,从内核的角度,当它收到一个 asynchronous read 之后,它会立刻返回,说明 read 请求已经成功发起了,因此不会对用户线程产生任何阻塞(block)。
然后,内核会等待数据准备完成,然后将数据拷贝到用户线程,当这一切都完成之后,内核会给用户线程发送一个信号,告诉它 read 操作完成了。
也就是说,用户线程完全不需要关心实际的整个 I/O 操作是如何进行的,只需要先发起一个请求,当接收内核返回的成功信号时表示 I/O 操作已经完成,可以直接去使用数据了。
这五种 I/O 模型中,前面四种 I/O 模型实际上都属于同步 I/O,只有最后一种是真正的异步 I/O,因为无论是多路复用 I/O模型还是信号驱动 I/O 模型,I/O 操作的第 2 个阶段都会引起用户线程阻塞,也就是内核进行数据拷贝的过程都会让用户线程阻塞。
为何 Redis 要使用 I/O 多路复用技术
现在来回答这个问题就 so easy 啦!
首先,Redis 是单线程架构,所有的命令操作都是先进入队列,然后一个一个按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以 I/O 操作在一般情况下往往不能直接返回,这会导致某一文件的 I/O 阻塞导致整个进程无法对其它客户提供服务,而采用 I/O 多路复用技术就是为了解决这个问题。
Redis 为何不采用异步 I/O 模型,这个不是效率更高吗?这玩意儿在多线程下才能发挥功效,而 Redis 是单线程架构哈。
epoll 是什么
epoll 其实只是众多实现 I/O多路复用模型的技术当中的一种而已,但是相比其他 I/O 多路复用技术(select, poll等),epoll有诸多优点(Redis 也支持 select 和 poll,默认使用 epoll)
- epoll 没有最大并发连接的限制,上限是最大可以打开文件的数目,这个数字一般远大于 2048,
- 效率提升, epoll 最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中, epoll 的效率就会远远高于 select 和 poll
- 内存拷贝, epoll 直接使用的 "共享内存",可以跳过传统的内存拷贝操作,效率更高
总结
Redis 采用 I/O 多路复用技术(epoll)是因为 Redis 是单线程架构,是为了避免网络 I/O 读写操作阻塞整个进程。
Redis I/O 多路复用技术原理的更多相关文章
- Lind.DDD.RedisClient~对StackExchange.Redis调用者的封装及多路复用技术
回到目录 两雄争霸 使用StackExchange.Redis的原因是因为它开源,免费,而对于商业化的ServiceStack.Redis,它将一步步被前者取代,开源将是一种趋势,商业化也值得被我们尊 ...
- 大数据相关技术原理资料整理(hdfs, spark, hbase, kafka, zookeeper, redis, hive, flink, k8s, OpenTSDB, InfluxDB, yarn)
hdfs: hdfs官方文档 深入理解HDFS的架构和原理 https://blog.csdn.net/kezhong_wxl/article/details/76573901 HDFS原理解析(总体 ...
- Redis单机数据库的实现原理
本文主要介绍Redis的数据库结构,Redis两种持久化的原理:RDB持久化.AOF持久化,以及Redis事件分类及执行原理.最后,分别介绍了单机班Redid客户端和Redis服务器的使用和实现原理. ...
- 液晶常用接口“LVDS、TTL、RSDS、TMDS”技术原理介绍
液晶常用接口“LVDS.TTL.RSDS.TMDS”技术原理介绍 1:Lvds Low-Voltage Differential Signaling 低压差分信号 1994年由美国国家半导体公司提出之 ...
- Oracle体系结构之控制文件的多路复用技术
在Windows操作系统中,如果注册表文件被损坏了,就会影响操作系统的稳定性.严重的话,会导致操作系统无法正常启动.而控制文件对于Oracle数据库来说,其作用就好象是注册表一样的重要.如果控制文件出 ...
- 进阶的Redis之哈希分片原理与集群实战
前面介绍了<进阶的Redis之数据持久化RDB与AOF>和<进阶的Redis之Sentinel原理及实战>,这次来了解下Redis的集群功能,以及其中哈希分片原理. 集群分片模 ...
- I/O多路复用技术(multiplexing)是什么?
作者:知乎用户链接:https://www.zhihu.com/question/28594409/answer/52763082来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- 解读I/O多路复用技术
前言 当我们要编写一个echo服务器程序的时候,需要对用户从标准输入键入的交互命令做出响应.在这种情况下,服务器必须响应两个相互独立的I/O事件:1)网络客户端发起网络连接请求,2)用户在键盘上键入命 ...
- Redis | 第5章 Redis 中的持久化技术《Redis设计与实现》
目录 前言 1. RDB 持久化 1.1 RDB 文件的创建与载入 1.2 自动间隔性保存 1.2.1 设置保存条件 1.2.2 dirty 计数器和 lastsave 属性 1.2.3 检查保存条件 ...
随机推荐
- IIS误删了默认网站,恢复方法
有时候安装好IIS后,会不小心把IIS的默认网站删除.重新去新建可能会出现一些错误例如"提示文件已存在无法执行"等奇怪的错误,下面是具体的默认网站的恢复方法 找到目录C:\wind ...
- Windows Service 2016 Datacenter\Stand\Embedded激活方法
安装好系统后连入互联网之后使用管理员身份打开命令行 输入命令 slmgr /skms kms.03k.org 弹出窗口提示模式修改成功后再输入命令:slmgr /ato 以下为各个版本的key 版本: ...
- oo第三单元——社交网络
第三单元的作业背景是实现一个社交观关系模拟系统,主要训练了JML的阅读和理解能力,和图的一些数据结构和算法. JML语言的理论基础 JML相对于实现代码是比较抽象的,规定了方法的前提副作用结果.数据的 ...
- 它来了,它来了,HarmonyOS应用开发在线体验来了
接下来是我们的两分钟科普,一分钟玩转HarmonyOS应用开发在线体验,一分钟简单了解"一次开发.多设备部署"的原理.萌新的开发者也能第一时间掌握,往下看吧~ 一分钟玩转Harmo ...
- xctf - stack2
xctf - stack2 文件check一下,几乎全开了 运行一下程序,好像很正常呢: 再来一个大的,好像有点儿问题,变1.00了 在ida中查看,在输入的时候没有检查数据大小 可以通过劫持eip获 ...
- 8-50.Pow(x,n)
题目描述: 解题思路: 第一想法是递归,结果f(x,n) = x * f(x,n-1);这种方法的空间复杂度太高了,太想当然. 看了下题解:采取分治的方法:f(x,n) = f(x,n/2) * f( ...
- Day16_88_通过反射机制执行方法
通过反射机制执行方法 * method.invoke(object,"admin","123"); * 代码 import java.lang.reflect. ...
- BB网络层测试
网络层测试2020 问题 1 以下不属于网络层的协议是___A_______. A DHCP B ICMP C IGMP D ARP 10 分 问题 2 如果目的网络.目的主机都对,但是 ...
- 常用head标签
最小推荐 <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content= ...
- Pytorch系列:(四)IO操作
首先注意pytorch中模型保存有两种格式,pth和pkl,其中,pth是pytorch默认格式,pkl还支持pickle库,不过一般如果没有特殊需求的时候,推荐使用默认pth格式保存 pytorch ...