redis-IO多路复用

2022-04-26  本文已影响0人  sizuoyi00

Linux 文件描述符
内核(kernel)利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。

在讨论IO的时候,参与者通常有两个角色:系统内核和用户进程。用户进程发送 IO请求过后,系统内核在准备好IO数据后,会通过内存拷贝的方式,将准备好的缓存IO数据共享给用户进程缓存。

传统的I/O 模型, 一般叫做 BIO Blocking I/O 阻塞模型。



由于这个模型对其他fd所对应的服务有影响。
所以在需要处理多个客户端的服务的时候, 我们大多数不会选择这个模型。 这个时候就出现了 我们经常听到的 NIO Non-Blocking IO。

比如说我们有一个餐馆, 如果一个 服务生, 只管理一张桌子,就算没有客人也只在桌子旁边等着 就是上面所说的BIO。
如果一个服务生管理多张桌子(multiplexing), 一张桌子没有客人的时候回去处理其他桌子(Non-Blocking)。 那这就是 BIO了。


在这个流程图上,我们可以看到在传统的 BIO 上面, 这里多了一层 select, select 的用处是来选择哪个fd(file descriptor) 是可以被读的。 如果可读就将上面的数据 读取出来。

是否异步主要在系统内核数据拷贝到用户进程这个步骤来区分,同步的话是通知用户进程数据准备好了,可以拷贝了,然后用户进程阻塞去拷贝数据。异步的话,是操作系统帮你把数据拷贝后,然后通知你数据好了,可以直接用了。

select poll epoll
https://zhuanlan.zhihu.com/p/126278747

select

int select(

    int nfds,
    fd_set *readfds, // 读数据到达fd
    fd_set *writefds, // 写数据到达fd
    fd_set *exceptfds, //异常fd
    struct timeval *timeout); 
    // 返回就绪fd个数

select模型

  1. 最大并发数限制,因为一个进程所打开的FD(文件描述符)是有限制的,由FD_SETSIZE设置,默认值是1024/2048,因此Select模型的最大并发数就被相应限制了。自己改改这个FD_SETSIZE?想法虽好,可是先看看下面吧…
  2. 效率问题,select每次调用都会线性扫描全部的FD集合,随后将就绪的fd做上标记,这样效率就会呈现线性下降,把FD_SETSIZE改大的后果就是,大家都慢慢来,什么?都超时了??!!
  3. 内核/用户空间 内存拷贝问题,如何让内核把FD消息通知给用户空间呢?在这个问题上select采取了内存拷贝方法。

poll模型
基本上效率和select是相同的,只不过优化了select文件描述符1024的限制。select缺点的2和3它都没有改掉。

Epoll的提升
把其他模型逐个批判了一下,再来看看Epoll的改进之处吧,其实把select的缺点反过来那就是Epoll的优点了。

  1. Epoll没有最大并发连接的限制,上限是最大可以打开文件的数目,这个数字一般远大于2048, 一般来说这个数目和系统内存关系很大,具体数目可以cat /proc/sys/fs/file-max察看。
  2. 效率提升,Epoll最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关(异步通知机制),因此在实际的网络环境中,Epoll的效率就会远远高于select和poll。
  3. 内存拷贝,Epoll在这点上使用了“共享内存”,这个内存拷贝也省略了

redis的IO多路复用:redis利用epoll实现IO多路复用,将连接信息与事件放到队列中,然后依次放到文件事件分派器,事件分派器将事件分发给事件处理器(连接应答-命令请求-命令回复)

redis-io多路复用
上一篇下一篇

猜你喜欢

热点阅读