10、Redis IO多路复用技术以及epoll实现原理
Redis是一个单线程的但性能是非常好的内存数据库,主要用来作为缓存系统。Redis采用网络IO多路复用技术来保证在多连接的时候,系统吞吐量高。
10.1 为什么Redis要使用IO多路复用
首先,Redis是跑在单线程中的,所有的操作都是顺序线性执行的,但是由于读写操作等待用户输入或者输出都是阻塞的,所以I/O操作往往不能直接返回,这会导致某一文件的I/O阻塞导致整个进程无法为客户服务,而I/O多路复用模型就是为了解决这个问题而出现的。
select、poll、epoll都是IO多路复用的模型。I/O多路复用就是通过一种机制,可以监视多个文件描述符,一旦某个描述符就绪,能够通知应用程序进行相应操作。
Redis的I/O模型使用的就是epoll,不过它也提供了select和kqueue的实现,默认采用epoll。
那么epoll到底什么东西?我们一起来看看。
10.2 epoll实现机制
10.2.1 场景举例
设想一个如下场景:
有100W个客户端同时与一个服务器保持着TCP连接。而每一时刻只有几百上千个TCP连接是活跃着的(事实上大部分场景都是这样的情况)。如何实现这样的高并发?
在select/poll时代,服务器进程每次都要把100W个连接告诉操作系统(从用户态复制句柄数据结构到内核态),让操作系统内核去查询这些套接字上是否有事件发生,轮询完后,再将句柄数据复制到用户态,让服务器应用程序轮询处理已经发生的网络事件,这一过程资源消耗较大,因此select/poll一般只能处理几千的并发连接。
如果没有I/O事件发生,我们的程序就会阻塞在select处。但是依然存在一个问题