原创

redis网络模型-IO多路复用


无论是阻寒IO还是非阻寒IO,用户应用在一阶段都需要调用recvfrom来获取数据,差别在于无数据时的处理方案:

  • 如果调用recvfrom时,恰好没有数据,阻塞IO会使进程阻塞,非阻塞IO使CPU空转,都不能充分发挥CPU的作用。
  • 如果调用recvfrom时,恰好有数据,则用户进程可以直接进入第二阶段,读取并处理数据

比如服务端处理客户端Socket请求时,在单线程情况下,只能依次处理每一个socket,如果正在处理的socket恰好未就绪(数据不可读或不可写),线程就会被阻塞,所有其它客户端socket都必须等待,性能自然会很差。

举个例子,这就像服务员给顾客点餐,分两步:

  1. 顾客思考要吃什么 (等待数据就绪)
  2. 顾客想好了,开始点餐(读取数据)

要提高效率的几种办法

方案一:增加更多服务员(多线程)

方案二:不排队,谁想好了吃什么(数据就绪了),服务员就给谁点餐(用户应用就去读取数据)

问题是用户进程如何知道内核中数据是否就绪?

文件描述符(FD)

文件描述符(File Descriptor): 简称FD,是一个从0 开始递增的无符号整数,用来关联Linux中的一个文件。在Linux中,一切皆文件,例如常规文件、视频、硬件设备等,当然也包括网络套接字 (Socket)。

IO多路复用:是利用单个线程来同时监听多个FD,并在某个FD可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源。

微信截图_20230212174606

IO多路复用的实现方式

IO多路复用:是利用单个线程来同时监听多个FD,并在某个FD可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源。 不过监听FD的方式、通知的方式又有多种实现,常见的有:

  • select
  • poll
  • epoll

差异:

  • select和poll只会通知用户进程有FD就绪,但不确定具体是哪个FD,需要用户进程逐个遍历FD来确认
  • epoll则会在通知用户进程FD就绪的同时,把已就绪的FD写入用户空间

微信截图_20230212175008

举个例子假如有9个客户在点单其中有一个客户点完了服务员前面的提示灯被按亮了,因为只有一个灯所以不知道是谁按的所以服务员得一个个轮询是谁点好了单

上面这个例子就是最早期的IO多路复用的方案,也就是select和poll的实现方案

弊端就是通知的方式不太好,不知道是谁通知的

后来进行了升级,一按按钮服务员前面的显示屏会显示是几号桌的客户点好了,epoll就是使用这种方案

redis原理
网络模型
  • 作者:陌攻(联系作者)
  • 发表时间:2023-02-16 09:17
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 公众号转载:请在文末添加作者公众号二维码
  • 评论