简单理解redis epoll运行原理


redis 是一个单线程却性能非常好的内存数据库, 主要用来作为缓存系统。 redis 采用 网络IO多路复用技术来保证在多连接的时候, 提高系统的高吞吐量。
Redis 是跑在单线程中的,所有的操作都是按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以 I/O 操作在一般情况下往往不能直接返回,这会导致某一文件的 I/O 阻塞导致整个进程无法对其它客户提供服务,而 I/O 多路复用就是为了解决这个问题而出现的。
下边就聊一聊网络IO模型:

I/O模型:

当客户端和服务端之间交互的时候,会在内核空间形成一个socket,通过socket来进行交互,可以把socket理解为一个文件。内核会给socket生成一个类似资源的句柄FD(文件描述符),调用底层api传入fd来进行读写。

BlockingIO(BIO)

同步并阻塞(传统阻塞型IO),当用户线程发起一个IO请求操作,内核会去查看要读取的数据是否就绪,对于阻塞IO来说,如果数据没有就绪,则会一直在那等待,直到数据就绪;当数据就绪之后,便将数据拷贝到用户线程,这样才完成了一个完整的IO读请求操作。
服务器实现模式为一个连接一个线程,就是客户端发送连接请求时候,服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情就会造成不必要的线程开销,比如socket阻塞在 accept 等待连接。BIO可以通过多线程的方式来改善并发性能,不过底层还是一个线程对应一个连接。
如下图:一个连接过来再内核中就会创建个线程,通过fd文件描述符来进行读写。
在这里插入图片描述

Non-blocking I/O(NIO)

同步非阻塞的I/O模型,当用户线程发起一个IO请求操作,内核会去查看要读取的数据是否就绪,对于非阻塞IO来说,如果数据没有就绪,则会返回一个标志信息告知用户线程当前要读的数据没有就绪。当数据就绪之后,便将数据拷贝到用户线程,这样才完成了一个完整的IO读请求操作。
NIO也是epoll的基础,服务器实现模式为一个线程处理多个请求(连接),就是客户端发送的连接请求都会注册到多路复用器上,多路复用器轮训到连接有I/O请求就进行处理。
缺点:每次调用都需要把fd集合从用户态拷贝到内核态,用户态和内核态切换,fd数据不断传递,这个开销很多时会很大
在这里插入图片描述

redis epoll

为了解决nio中用户态和内核态切换,fd数据不断传递问题,epoll采用了内存映射mmap,共享空间来解决。
共享空间里创建的红黑树保存所有socket fd,没有大小限制,且增删查的复杂度O(logN),创建双线链表存储就绪事件,时间复杂度O(1)。

为什么epoll快?

这是由于我们在调用epoll_create时,内核除了帮我们在epoll文件系统里建了个file结点,在共享空间里建了个红黑树用于存储以后epoll_ctl传来的socket外,还会再建立一个链表,用于存储准备就绪的事件,当epoll_wait调用时,仅仅观察这个链表里有没有数据即可。有数据就返回,没有数据就sleep,等到timeout时间到后即使链表没数据也返回。所以非常高效。

就绪链表怎么维护?

当我们执行epoll_ctl时,除了把socket放到epoll文件系统里file对象对应的红黑树上之外,还会给内核中断处理程序注册一个回调函数,告诉内核,如果这个句柄的中断到了,就把它放到准备就绪list链表里。所以,当一个socket上有数据到了,内核在把网卡上的数据copy到内核中后就来把socket插入到准备就绪链表里了。(注:好好理解这句话!)
从上面这句可以看出,epoll的基础就是回调呀!
在这里插入图片描述

如此,一颗红黑树,一张准备就绪句柄链表,少量的内核共享空间,就帮我们解决了大并发下的socket处理问题。

  1. 执行epoll_create时,创建了红黑树和就绪链表,
  2. 执行epoll_ctl时,如果增加socket句柄,则检查在红黑树中是否存在,存在立即返回,不存在则添加到树干上,然后向内核注册回调函数,用于当中断事件来临时向准备就绪链表中插入数据。
  3. 执行epoll_wait时立刻返回准备就绪链表里的数据即可。

epoll_create:创建一个epoll文件描述符,创建eventpoll,其中包含红黑树cache和双向链表
epollctl:对指定描述符fd执行op的绑定操作,把fd写入红黑树,同时在内核注册回调函数
epollwait:获取epfd上的io事件

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值