首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
开篇词 | 阅读Redis源码能给你带来什么?
01 | 带你快速攻略Redis源码的整体架构
02 | 键值对中字符串的实现,用char*还是结构体?
03 | 如何实现一个性能优异的Hash表?
04 | 内存友好的数据结构该如何细化设计?
05 | 有序集合为何能同时支持点查询和范围查询?
06 | 从ziplist到quicklist,再到listpack的启发
07 | 为什么Stream使用了Radix Tree?
08 | Redis server启动后会做哪些操作?
09 | Redis事件驱动框架(上):何时使用select、poll、epoll?
10 | Redis事件驱动框架(中):Redis实现了Reactor模型吗?
11 | Redis事件驱动框架(下):Redis有哪些事件?
12 | Redis真的是单线程吗?
13 | Redis 6.0多IO线程的效率提高了吗?
14 | 从代码实现看分布式锁的原子性保证
15 | 为什么LRU算法原理和代码实现不一样?
16 | LFU算法和其他算法相比有优势吗?
17 | Lazy Free会影响缓存替换吗?
18 | 如何生成和解读RDB文件?
19 | AOF重写(上):触发时机与重写的影响
20 | AOF重写(下):重写时的新写操作记录在哪里?
21 | 主从复制:基于状态机的设计与实现
22 | 哨兵也和Redis实例一样初始化吗?
23 | 从哨兵Leader选举学习Raft协议实现(上)
24 | 从哨兵Leader选举学习Raft协议实现(下)
25 | Pub/Sub在主从故障切换时是如何发挥作用的?
26 | 从Ping-Pong消息学习Gossip协议的实现
27 | 从MOVED、ASK看集群节点如何处理命令?
28 | Redis Cluster数据迁移会阻塞吗?
29 | 如何正确实现循环缓冲区?
30 | 如何在系统中实现延迟监控?
31 | 从Module的实现学习动态扩展功能
32 | 如何在一个系统中实现单元测试?
当前位置:
首页>>
技术小册>>
Redis源码剖析与实战
小册名称:Redis源码剖析与实战
### 09 | Redis事件驱动框架(上):何时使用select、poll、epoll? 在深入探讨Redis的事件驱动框架之前,了解底层I/O多路复用机制的选择——特别是`select`、`poll`、`epoll`之间的差异与适用场景——是至关重要的。Redis作为一个高性能的键值存储系统,其高效运作离不开对I/O操作的精心优化。本章将详细解析这三种I/O多路复用技术的原理、优缺点,以及Redis为何在不同场景下会选择不同的机制。 #### 一、引言 在网络编程中,服务器需要同时处理多个客户端的连接请求和数据传输,这种能力通常通过I/O多路复用技术实现。I/O多路复用允许单个线程或进程同时监视多个文件描述符(File Descriptor, FD),以检测是否有I/O事件发生(如可读、可写或错误),从而有效地管理多个网络连接。 #### 二、select机制 ##### 2.1 原理 `select`是最早出现的I/O多路复用技术之一,其基本原理是:进程通过调用`select`函数,可以同时监视多个文件描述符的状态变化。`select`函数会阻塞进程,直到有一个或多个文件描述符就绪(即达到可读、可写或异常条件),或者超时发生。 `select`函数的原型如下: ```c #include <sys/select.h> #include <sys/time.h> #include <unistd.h> int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); ``` 其中,`nfds`是文件描述符集合中最大文件描述符的值加1,`readfds`、`writefds`、`exceptfds`分别用于指示需要检查的读、写、异常条件的文件描述符集合,`timeout`用于设置超时时间。 ##### 2.2 优缺点 **优点**: - 跨平台性好,几乎所有支持POSIX标准的操作系统都支持`select`。 - 实现简单,易于理解和使用。 **缺点**: - **性能瓶颈**:随着监视的文件描述符数量增加,`select`的效率会显著下降。因为`select`采用轮询的方式检查所有文件描述符,时间复杂度为O(n)。 - **文件描述符限制**:单个`select`调用能监视的文件描述符数量有限制,通常为1024个(可通过修改FD_SETSIZE调整,但影响全局)。 - **数据拷贝开销**:每次调用`select`时,都需要将文件描述符集合从用户空间拷贝到内核空间,返回时再从内核空间拷贝回用户空间,增加了不必要的内存拷贝开销。 #### 三、poll机制 ##### 3.1 原理 `poll`是`select`的一个改进版本,它解决了`select`的一些限制,特别是文件描述符数量的限制。`poll`使用`pollfd`结构数组代替`select`中的文件描述符集合,从而避免了`select`在文件描述符数量上的限制。 `poll`函数的原型如下: ```c #include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout); ``` 其中,`fds`是一个指向`pollfd`结构数组的指针,`nfds`是数组中元素的数量,`timeout`是等待的超时时间(毫秒)。 ##### 3.2 优缺点 **优点**: - 突破了`select`的文件描述符数量限制,理论上可以监视的文件描述符数量仅受系统内存限制。 - 提供了更多的灵活性,比如可以监视文件描述符的精确事件类型(如边缘触发或水平触发)。 **缺点**: - 与`select`一样,`poll`也采用轮询方式检查文件描述符,时间复杂度为O(n),随着监视的文件描述符数量增加,性能会下降。 - 数据拷贝开销仍然存在,每次调用都需要在用户空间和内核空间之间拷贝数据。 #### 四、epoll机制 ##### 4.1 原理 `epoll`是Linux特有的一种I/O事件通知机制,它显著提高了大量并发连接时的I/O处理效率。与`select`和`poll`不同,`epoll`使用基于事件驱动的方式来工作,它只会在有事件发生时通知用户程序,避免了无用的轮询操作。 `epoll`提供了三种操作模式:`EPOLL_CTL_ADD`(添加新的文件描述符到epoll实例中)、`EPOLL_CTL_DEL`(从epoll实例中删除文件描述符)、`EPOLL_CTL_MOD`(修改文件描述符上的事件)。 `epoll_wait`函数用于等待一组文件描述符上的事件: ```c #include <sys/epoll.h> int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); ``` 其中,`epfd`是epoll实例的文件描述符,`events`用于接收触发事件的`epoll_event`结构数组,`maxevents`是数组的最大长度,`timeout`是等待的超时时间(毫秒)。 ##### 4.2 优缺点 **优点**: - **高效性**:`epoll`采用基于事件通知的方式,只在有事件发生时通知用户程序,避免了无用的轮询,时间复杂度降低为O(1)。 - **支持大量并发**:由于避免了无用的轮询,`epoll`能够高效地处理成千上万的并发连接。 - **内存拷贝减少**:使用`epoll`时,内核和用户空间之间只传递事件通知,减少了数据拷贝的开销。 **缺点**: - 仅限于Linux操作系统,跨平台性差。 - 使用复杂度较`select`和`poll`略高,需要更多的编程技巧和对Linux内核的理解。 #### 五、Redis中的选择 Redis在事件驱动框架中,根据运行平台的特性和性能需求,灵活选择了`select`、`poll`、`epoll`中的一种或多种作为I/O多路复用的实现方式。 - **在Linux系统上**,Redis默认使用`epoll`,因为它提供了最高的性能和最好的并发处理能力。 - **在非Linux系统上**,如macOS或Windows,Redis可能会回退到使用`select`或`poll`,因为这些系统不支持`epoll`。 Redis的源码中,这一选择是通过宏定义和条件编译来实现的,确保了Redis在不同操作系统上的可移植性和性能优化。 #### 六、总结 了解`select`、`poll`、`epoll`的原理、优缺点以及Redis中的选择策略,对于深入理解Redis的性能优化和事件驱动框架至关重要。每种I/O多路复用技术都有其适用的场景,Redis通过灵活选择最适合当前运行环境的机制,确保了其高性能和高效能。随着技术的发展,未来可能会有更多更高效的I/O多路复用技术出现,Redis也会持续演进,以适应不断变化的技术环境。
上一篇:
08 | Redis server启动后会做哪些操作?
下一篇:
10 | Redis事件驱动框架(中):Redis实现了Reactor模型吗?
该分类下的相关小册推荐:
Redis的Lua脚本编程
Redis面试指南
Redis零基础到实战
Redis核心技术与实战