概述
Redis 采用单线程 Reactor 模式处理客户端请求,其高性能的核心就在于 I/O 多路复用 技术。
基础概念
什么是 I/O 多路复用?
- 核心思想:使用一个进程/线程同时监听多个文件描述符(Socket),当某些描述符就绪(可读/可写)时,通知程序进行相应操作。
- 解决的问题:避免为每个连接创建线程/进程带来的资源消耗,实现高并发连接处理。
Redis 的架构选择
# 传统多线程模型 vs Redis 单线程 + 多路复用
# 传统模型:1 个连接 → 1 个线程 → 高内存消耗、上下文切换开销大
# Redis 模型:N 个连接 → 1 个线程 + I/O 多路复用 → 低内存、无锁、高效
Redis 中多路复用的实现
支持的底层机制
Redis 在不同操作系统下使用不同的多路复用实现:
- Linux:
epoll(最优选择) - macOS/BSD:
kqueue - Solaris:
evport - 其他 Unix:
select(性能较差,备选)
Redis 通过 ae(Async Event)抽象层统一封装这些接口。
核心工作流程
- 初始化服务器,监听端口
- 将监听套接字注册到多路复用器
- 进入事件循环:
- 通过多路复用器等待事件(阻塞调用)
- 事件就绪后返回:
- 新连接到达 → 接受连接,注册读事件
- 数据可读 → 读取命令,解析,放入命令队列
- 可写事件 → 将响应数据发送给客户端
- 处理时间事件(定时任务)
- 循环执行步骤 3
源码级实现解析
事件循环结构
typedef struct aeEventLoop {
int maxfd; // 当前最大文件描述符
int setsize; // 监听的文件描述符数量上限
long long timeEventNextId; // 下一个时间事件 ID
aeFileEvent *events; // 文件事件数组
aeFiredEvent *fired; // 就绪事件数组
aeTimeEvent *timeEventHead; // 时间事件链表头
void *apidata; // 多路复用器的特定数据(epoll/kqueue 等)
aeBeforeSleepProc *beforesleep;
aeBeforeSleepProc *aftersleep;
} aeEventLoop;


