三 Redis多路复用(epoll)

本文解析了Redis官方为何仅支持Linux版本,重点讲解了epoll在网络模型中的优势,包括无限制的连接数和高并发下的IO效率。此外,详细介绍了epoll的工作原理,包括创建、添加文件句柄、等待事件和整体流程,以及为何选择红黑树作为内部数据结构。
摘要由CSDN通过智能技术生成

1 疑问解答

  1. 为什么redis官方只支持Linux版本?

    因为只有Linux支持epoll网络模型,window下的select模型在高并发下性能不如epoll。

  2. epoll相比selete、poll优势点?

    epoll监听的连接数基本没有限制,select所能打开的最大连接数有FD_SETSIZE宏定义限制(当然可以自己配置,但会影响性能),poll使用链表存储的没有最大连接数的限制;

    高并发下IO效率问题:epoll的时间复杂度是O(1),select和poll都是O(n)

2 epoll原理

2.1 创建动作

要使用 epoll 首先需要调用 epoll_create() 函数。整个方法主要会做两件事

  1. 创建并初始化一个 eventpoll 对象。对象结构见eventpoll结构体

  2. 把 eventpoll 对象映射到一个文件句柄,并返回这个文件句柄。

struct eventpoll {
    ...
    wait_queue_head_t wq;
    ...
    struct list_head rdllist;
    struct rb_root rbr;
    ...
};
  1. wq: 等待队列,当调用 epoll_wait(fd) 时会把进程添加到 eventpoll 对象的 wq 等待队列中。

  2. rdllist: 保存已经就绪的文件列表。

  3. rbr: 使用红黑树(提高增删等维护动作效率)来管理所有被监听的文件。

2.2 向epoll添加文件句柄

通过调用 epoll_ctl() 函数可以向 epoll 添加要监听的文件。方法原型为:long epoll_ctl(int epfd, int op, int fd,struct epoll_event *event);

  1. epfd: 通过调用 epoll_create() 函数返回的文件句柄。

  2. op: 要进行的操作,有3个选项:

    1. EPOLL_CTL_ADD:表示要进行添加操作。

    2. EPOLL_CTL_DEL:表示要进行删除操作。

    3. EPOLL_CTL_MOD:表示要进行修改操作。

  3. fd: 要监听的文件句柄。

  4. event: 告诉内核需要监听什么事。(可读、可写等)

2.3 等待被监听的文件状态改变

把被监听的文件句柄添加到epoll后,就可以通过调用 epoll_wait() 等待被监听的文件状态发生改变。epoll_wait() 调用会阻塞当前进程,当被监听的文件状态发生改变时,epoll_wait() 调用便会返回。

long epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

各个参数的意义:

  1. epfd: 调用 epoll_create() 函数创建的epoll句柄。

  2. events: 用来存放就绪文件列表。

  3. maxevents: events 数组的大小。

  4. timeout: 设置等待的超时时间。

2.4 整体流程

最后,我们通过一张图来总结epoll的原理:

  1. 通过调用 epoll_create() 函数创建并初始化一个 eventpoll 对象。

  2. 通过调用 epoll_ctl() 函数把被监听的文件句柄 (如socket句柄) 封装成 epitem 对象并且添加到 eventpoll 对象的红黑树中进行管理。

  3. 通过调用 epoll_wait() 函数等待被监听的文件状态发生改变。

  4. 当被监听的文件状态发生改变时(如socket接收到数据),会把文件句柄对应 epitem 对象添加到 eventpoll 对象的就绪队列 rdllist 中。并且把就绪队列的文件列表复制到 epoll_wait() 函数的 events 参数中。

  5. 唤醒调用 epoll_wait() 函数被阻塞(睡眠)的进程。 

附:为什么使用红黑树

  • 插入效率高:调用epoll_ctl监听sockt会在红黑树插入节点,而红黑树插入节点最多两次旋转,相比AVL重平衡效率更高。
  • 查询效率高:红黑树最长链路不会超过最短链路两倍,查询效率高且相对平衡。
  • 内存占用相对小:相比于跳表来说,红黑树指针数更少,占用更少的内存空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值