Redis NIO多路复用

🍥 一句话总结(真正的核心)

Redis 用 epoll 的 I/O 多路复用机制,让单线程也能同时处理成千上万连接,而不用为每个连接创建线程。

换句话说:

  • 不阻塞
  • 不多线程
  • 不并发锁
  • 极高并发能力

这是 Redis 快的核心基础之一。


🧵 Redis 为什么能用单线程支撑高并发?

因为:

Redis 不是为每个连接创建线程,而是使用 epoll 监听多个连接的读写事件。
只要某个连接“准备好了”,Redis 才处理它。

这就叫 I/O 多路复用模型


🟦 1. 什么是 I/O 多路复用?

关键字:One Thread + Many Connections + epoll 事件触发

示意图(你脑子里一定得有这个):

           ┌─────────────┐
           │   Redis     │   单线程
           └──────┬──────┘
                  │
              epoll_wait
                  │
 ┌───────────────┴─────────────────┐
 │             │            │      │
conn1  (读就绪) conn2 (读就绪) conn3 … connN

Redis 的事件循环主要做两件事:

  1. epoll 等待 socket 事件(不会阻塞 CPU)
  2. 哪个连接就绪,就处理哪个连接(执行命令)

没有就绪事件时 Redis 是 idle,不浪费 CPU。


🟩 2. Redis 的事件驱动模型(Event Loop)

Redis 内部有一个 "AE"(Abstract Event)事件框架:

    while(true):
        处理定时任务
        处理网络 I/O (epoll)
        执行客户端命令

两类事件:

  • 文件事件(File Events):网络连接相关,靠 epoll
  • 时间事件(Time Events):定时任务(过期 key 检查、AOF 刷盘、Cluster 心跳)

你可以理解为:

Redis = 一个加强版 Nginx + 数据结构存储引擎


🟥 3. 多路复用的核心:epoll

Redis 使用 Linux 的 epoll:

  • 使用 epoll_create 创建实例
  • 所有客户端 socket 注册到 epoll
  • 使用 epoll_wait 阻塞等待事件发生
  • 某个 socket 有读写时 → 回调对应的处理函数

简单流程:

客户端发送命令
↓
socket 缓冲区变为可读
↓
epoll_wait 返回事件
↓
Redis 单线程读取数据 + 执行命令
↓
写回结果

整个过程中:

❌ 没有一个连接对应一个线程
✔ 所有连接共享一个事件循环


🟧 4. 为什么 epoll 如此关键?

看看没有 epoll 的老旧模型:

(1)每连接一个线程?

  • 成百上千线程上下文切换
  • CPU 被抢占
    ❌ Redis 不干

(2)select/poll?

  • 每次都要把所有 FD 扫一遍
  • O(n) 遍历
    ❌ 高并发下效率崩溃

(3)epoll 的优势:

  • O(1) 级监听事件
  • 支持海量连接
  • 基于回调
  • 事件驱动,很轻量

这是 Redis 能在单线程达到 10+ 万 QPS 的基础。


🟨 5. 多路复用 + 单线程 = 无锁 + 极高效率

Redis 只有一个线程执行命令,所以:

  • 无加锁
  • 无竞争
  • 无线程切换
  • 无内存同步开销

几乎所有 CPU 被用于执行命令,而不是处理线程调度。

这就是 Redis 的 “极简哲学”:

复杂性交给操作系统(epoll),Redis 专心执行逻辑


🟫 6. 多路复用执行一次命令的完整流程(图)

            ┌──────────────────────────┐
            │        EventLoop         │
            └────────────┬─────────────┘
                         │
                    epoll_wait
                         │
          ┌──────────────┼────────────────┐
          │              │                │
   conn1 ready      conn2 ready      …   connN ready
          │
   读取命令(read)
          │
   解析命令(parse)
          │
   执行命令(execute)
          │
   写回结果(write)

所有 I/O 都是非阻塞的。


🧠 7. 面试高级回答(别人都不会的版本)

Redis 使用 epoll 作为 NIO 多路复用器,对所有客户端 socket 注册读写事件,通过单线程事件循环处理所有就绪事件,不需要额外的线程池,也没有锁竞争。事件驱动模型让 Redis 单线程也能轻松支撑十万级连接,这是 Redis 高性能的重要基础。

这句话你背一下,绝杀。


🧩 8. 总结一句话(记住)

Redis 的单线程之所以快,就是因为 epoll + 非阻塞 I/O + 事件驱动,让它能轻松处理海量连接,而无需开多线程、也没有锁开销。

posted @ 2025-12-05 15:30  中登程序猿  阅读(4)  评论(0)    收藏  举报