1. 核心概念
在 Redis 6.0 之前,Redis 的核心网络模型是 单线程 的(基于 Reactor 模式)。这意味着接收客户端请求、解析请求、执行命令、发送响应都在同一个线程中完成。
Redis 6.0 引入了多线程 I/O,但请注意:Redis 的命令执行(Command Execution)依然是单线程的。
引入多线程的主要目的是为了解决 网络 I/O 的瓶颈。随着硬件性能提升,Redis 的性能瓶颈逐渐从 CPU 转向了网络读取和写入(Syscall 开销、协议解析、数据拷贝)。
2. 原理与源码关键点
2.1 为什么之前是单线程?
- CPU 不是瓶颈:Redis 是内存数据库,绝大多数操作极快,瓶颈通常在于内存大小或网络带宽。
- 避免复杂性:单线程避免了死锁、上下文切换、竞态条件,代码更易维护。
2.2 6.0 的多线程模型
Redis 6.0 的多线程仅用于处理 网络 I/O 任务:
- 网络读取(Socket Read):多线程并行读取客户端 Socket 数据。
- 协议解析(Protocol Parsing):多线程并行解析命令。
- 命令执行(Command Execution):依然由主线程串行执行。这保证了原子性,无需复杂的锁机制。
- 网络写入(Socket Write):多线程并行将响应数据写入 Socket。
2.3 源码流程简述
主线程在处理事件循环时:
- 将等待读取的客户端连接分配给一组 IO 线程。
- 主线程阻塞等待所有 IO 线程完成读取和解析。
- 主线程串行执行解析好的命令。
- 主线程将响应数据分配给 IO 线程。
- 主线程阻塞等待所有 IO 线程完成写入。
3. 性能优化与考量
- 性能提升:官方测试显示,开启多线程后,Redis 的吞吐量(QPS)可以提升 2-3 倍。
- 配置开启:默认情况下多线程是关闭的。需要在
redis.conf中配置:io-threads-do-reads yes io-threads 4 # 建议设置为 CPU 核心数的 3/4 - 线程安全:由于命令执行依然是单线程,因此用户无需担心 Lua 脚本、事务的原子性问题,也不需要修改现有的客户端代码。
4. 总结
Redis 6.0 引入多线程是为了突破网络 I/O 的性能瓶颈,而非 CPU 计算瓶颈。
面试回答示例:
“Redis 6.0 引入多线程主要是为了解决网络 I/O 读写带来的性能瓶颈。 它的关键点在于:I/O 多线程,执行单线程。即使用多个线程并行处理客户端的网络数据读取、协议解析和数据回写,但指令的实际执行依然由主线程串行完成。 这种设计既保留了 Redis 单线程模型的简单性(无锁、无竞态),又利用多核优势显著提升了高并发下的吞吐量。”