Redis的I/O多路复用模型

Redis是跑在单线程的,所有的操作都是按顺序线性执行的,由于读写操作需要等待用户输入或者输出是阻塞的,所以某一个文件I/O阻塞会导致整个进程无法对其他客户提供服务,I/O多路复用就是为了解决这个问题而出现的。

阻塞I/O 当对某个文件描述符进行读写时,如果当前文件描述符不可读或者不可写,那么线程就会阻塞在那里,无法对其他操作做出相应。导致整个服务不可用。所以在需要处理多个客户端任务时,往往不会用阻塞模型。

在I/O多路复用模型中,有几个很重要的函数,比如select、poll、epoll,这些函数能够同时监控多个文件描述符的可读可写情况,当其中某些文件描述符可读可写时,函数就会返回可读可写的文件描述符。

文件事件处理器使用I/O多路复用模块同时监听多个文件描述符,虽然整个文件事件处理器是在单线程上运行的,但是通过I/O多路复用模块的引入,实现了同时对多个文件描述符读写的监控,提高了网络模型的性能。

I/O多路复用模块:
I/O多路复用模块封装了底层的select、epoll等函数,Redis会根据编译平台的不同选择不同的I/O多路复用函数,select是作为一个保底的方案,linux环境下会选择epoll。

select、poll、epoll的区别

  1. select--------->时间复杂度是O(n)
    因为当有I/O事件发生时,select采用的是无差别轮询的方式遍历所有的流,找出能读或者能写的流,再对他们进行操作。这个无差别轮询的事件复杂度是O(n)
    监听的fd数量有限制,32位机试1024个,64位机试2048个。
  2. poll------------>时间复杂度是O(n)
    poll本质上和select没有区别,但是他没有最大连接数的限制,因为他是基于链表来存储的。
  3. epoll------------>时间复杂度是O(1)
    epoll会把哪个流发送了什么时间通知我们,时间复杂度降到了O(1)。

select、poll、epoll都是I/O多路复用的机制,是同步I/O,他们都需要在读写事件就绪后,自己负责读写,这个读写的过程是阻塞的,而异步I/O无需自己进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。

Linux 中一切皆文件,比如 C++ 源文件、视频文件、Shell脚本、可执行文件等,就连键盘、显示器、鼠标等硬件设备也都是文件。一个 Linux 进程可以打开成百上千个文件,为了表示和区分已经打开的文件,Linux 会给每个文件分配一个编号(一个 ID),这个编号就是一个整数,被称为文件描述符(File Descriptor)

参考链接:https://www.cnblogs.com/aspirant/p/9166944.html
https://www.cnblogs.com/john8169/p/9780484.html

猜你喜欢

转载自blog.csdn.net/weixin_43338519/article/details/107615825