我是靠谱客的博主 俊逸帆布鞋,最近开发中收集的这篇文章主要介绍redis的io多路复用技术,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

redis单线程为什么会那么快?

主要有两点:
1.内存操作
2.io多路复用技术

什么是io多路复用?

一、简单理解就是:一个服务端进程可以同时处理多个套接字描述符。
多路:多个客户端连接(连接就是套接字描述符)
复用:使用单进程就能够实现同时处理多个客户端的连接
以上是通过增加进程和线程的数量来并发处理多个套接字,免不了上下文切换的开销,而IO多路复用只需要一个进程就能够处理多个套接字,从而解决了上下文切换的问题。

其发展可以分select->poll→epoll三个阶段来描述。

二、如何简单理解select/poll/epoll呢?

按照以往惯例,还是联系一下我们日常中的现实场景,这样更助于大家理解。

举栗说明:

领导分配员工开发任务,有些员工还没完成。如果领导要每个员工的工作都要验收check,那在未完成的员工那里,只能阻塞等待,等待他完成之后,再去check下一位员工的任务,造成性能问题。

那如何解决这个问题呢?

select

领导找个Team Leader(后文简称TL),负责代自己check每位员工的开发任务。

TL 的做法是:遍历问各个员工“完成了么?”,完成的待CR check无误后合并到Git分支,对于其他未完成的,休息一会儿后再去遍历…

这样存在什么问题呢?

这个TL存在能力短板问题,最多只能管理1024个员工
很多员工的任务没有完成,而且短时间内也完不成的话,TL还是会不停的去遍历问询,影响效率。
select具有良好的跨平台支持,其缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024。

poll

换一个能力更强的New Team Leader(后文简称NTL),可以管理更多的员工,这个NTL可以理解为poll。

poll改变了文件描述符集合的描述方式,使用了pollfd结构而不是select的fd_set结构,使得poll支持的文件描述符集合限制远大于select的1024。

epoll

在上一步poll方式的NTL基础上,改进一下NTL的办事方法:遍历一次所有员工,如果任务没有完成,告诉员工待完成之后,其应该做xx操作(制定一些列的流程规范)。这样NTL只需要定期check指定的关键节点就好了。这就是epoll。

epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。

小结
select就是轮询,在Linux上限制个数一般为1024个
poll解决了select的个数限制,但是依然是轮询
epoll解决了个数的限制,同时解决了轮询的方式

三、IO多路复用在Redis中的应用

Redis 服务器是一个事件驱动程序, 服务器处理的事件分为时间事件和文件事件两类。

文件事件:Redis主进程中,主要处理客户端的连接请求与相应。
时间事件:fork出的子进程中,处理如AOF持久化任务等。
由于Redis的文件事件是单进程,单线程模型,但是确保持着优秀的吞吐量,IO多路复用起到了主要作用。

文件事件是对套接字操作的抽象,每当一个套接字准备好执行连接应答、写入、读取、关闭等操作时,就会产生一个文件事件。因为一个服务器通常会连接多个套接字,所以多个文件事件有可能会并发地出现。

IO多路复用程序负责监听多个套接字并向文件事件分派器传送那些产生了事件的套接字。文件事件分派器接收IO多路复用程序传来的套接字,并根据套接字产生的事件的类型,调用相应的事件处理器。示例如图所示:
在这里插入图片描述
文件处理器的四个组成部分

Redis的IO多路复用程序的所有功能都是通过包装常见的select、poll、evport和kqueue这些IO多路复用函数库来实现的,每个IO多路复用函数库在Redis源码中都有对应的一个单独的文件。
Redis为每个IO多路复用函数库都实现了相同的API,所以IO多路复用程序的底层实现是可以互换的。如图:
在这里插入图片描述
多个IO复用库实现可选
Redis把所有连接与读写事件、还有我们没提到的时间事件一起集中管理,并对底层IO多路复用机制进行了封装,最终实现了单进程能够处理多个连接以及读写事件。这就是IO多路复用在redis中的应用。

四、总结

Redis 6.0 之后的版本开始选择性使用多线程模型。

Redis 选择使用单线程模型处理客户端的请求主要还是因为 CPU 不是 Redis 服务器的瓶颈,使用多线程模型带来的性能提升并不能抵消它带来的开发成本和维护成本,系统的性能瓶颈也主要在网络 I/O 操作上;

而 Redis 引入多线程操作也是出于性能上的考虑,对于一些大键值对的删除操作,通过多线程非阻塞地释放内存空间也能减少对 Redis 主线程阻塞的时间,提高执行的效率。

最后

以上就是俊逸帆布鞋为你收集整理的redis的io多路复用技术的全部内容,希望文章能够帮你解决redis的io多路复用技术所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部