Redis是基于内存的键值存储,支持多种数据结构,采用单线程非阻塞I/O实现高性能,提供RDB/AOF持久化,适用于缓存、消息队列及实时数据处理。
一、单线程事件驱动模型
核心特点:
-
单线程主循环:Redis 主线程采用 Reactor 模式,通过 I/O 多路复用(如
epoll/kqueue)处理网络请求,避免多线程上下文切换开销。 -
异步处理:
- 主线程处理所有命令执行、网络 I/O。
- 后台线程(如 Redis 6.0+ 的 I/O 多线程)仅负责网络数据的读写解析,命令执行仍为单线程,确保原子性。
优势:
- 避免锁竞争,简化代码逻辑。
- 最大化利用 CPU 缓存,降低延迟。
局限:
- 长耗时命令(如
KEYS *、大 Key 删除)会阻塞主线程。 - 需通过 Pipeline 或 Lua 脚本 优化批量操作。
二、模块化架构组成
Redis 的代码结构高度模块化,核心模块包括:
| 模块 | 功能 |
|---|---|
| 事件处理器 | 基于 aeEventLoop 的事件循环,监听并分发网络事件(如连接、读写)。 |
| 网络层 | 管理 TCP 连接、协议解析(RESP:Redis Serialization Protocol)。 |
| 数据存储引擎 | 实现字符串、哈希、列表等数据结构,内存分配由 jemalloc 或 libc 管理。 |
| 持久化模块 | 处理 RDB(快照)和 AOF(日志)的生成、加载与重写。 |
| 高可用模块 | 包含 Sentinel(故障转移)和 Cluster(分片)的实现。 |
| 客户端管理 | 维护客户端连接状态、输入/输出缓冲区。 |
三、持久化机制
-
RDB(Redis Database) :
- 原理:定时生成内存快照(二进制文件),
fork子进程执行,主线程继续服务。 - 触发条件:
save配置项或手动执行BGSAVE。 - 优点:文件紧凑,恢复速度快。
- 缺点:可能丢失最后一次快照后的数据。
- 原理:定时生成内存快照(二进制文件),
-
AOF(Append-Only File) :
- 原理:记录所有写操作命令(文本日志),支持
fsync策略(always/everysec/no)。 - 重写机制:定期压缩 AOF 文件(移除冗余命令),通过
BGREWRITEAOF触发。 - 优点:数据安全性高(最多丢失 1 秒数据)。
- 缺点:文件体积大,恢复速度慢。
- 原理:记录所有写操作命令(文本日志),支持
-
混合持久化(Redis 4.0+) :
- AOF 文件由 RDB 头部 + 增量 AOF 命令 组成,兼顾恢复速度与数据安全。
四、高可用架构
-
主从复制(Replication) :
- 异步复制:从节点异步同步主节点数据,支持级联复制。
- 故障切换:需手动或通过 Sentinel 自动切换主节点。
-
Sentinel(哨兵) :
- 功能:监控主从节点,自动故障转移与配置更新。
- 部署:至少 3 个 Sentinel 节点,通过 Raft 协议达成共识。
-
Cluster(集群) :
- 数据分片:16384 个哈希槽分散到多个节点,支持动态扩缩容。
- 高可用:每个分片为一主多从,主节点故障时从节点自动晋升。
五、线程模型演进(Redis 6.0+)
-
I/O 多线程:
- 网络读写:由多个后台线程并行处理,提升吞吐量(如 10 万 QPS → 50 万 QPS)。
- 命令执行:仍由主线程串行处理,保证原子性。
-
配置参数:
io-threads 4 # 启用 4 个 I/O 线程(需大于 1 生效) io-threads-do-reads no # 默认仅写操作多线程,读操作仍单线程
六、通信协议与客户端交互
-
RESP 协议:
- 基于 TCP 的文本协议,支持简单字符串、错误、整数、批量字符串和数组类型。
- 示例:客户端发送
SET key value对应协议为*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n。
-
Pipeline: 客户端批量发送命令,减少网络往返(RTT),提升吞吐量。
七、内存管理与优化
-
数据结构优化:
ziplist(压缩列表):小规模 Hash/List 使用连续内存,减少碎片。quicklist(快速列表):List 的底层实现,结合ziplist与链表优势。
-
内存淘汰策略:
volatile-lru、allkeys-lfu等策略控制内存溢出。
-
碎片整理:
- 重启或使用
MEMORY PURGE(需jemalloc)回收碎片。
- 重启或使用
八、适用场景与架构适配
| 场景 | 架构选择 | 优化要点 |
|---|---|---|
| 缓存 | 单机/主从 + Sentinel | 设置合理 TTL,禁用持久化,监控命中率。 |
| 会话存储 | Cluster | 使用 Hash 结构存储用户数据,避免大 Key。 |
| 消息队列 | 单机 + Stream 数据结构 | 监控消费者组延迟,启用 AOF 持久化。 |
| 实时统计 | Cluster + HyperLogLog | 利用 PFADD/PFCOUNT 节省内存。 |
总结
Redis 的软件架构通过 单线程事件循环、高效数据结构 和 模块化设计,在内存操作、持久化、高可用等方面实现了高性能与灵活性的平衡。结合业务场景选择合适的部署模式(单机/Sentinel/Cluster)并优化配置(如内存淘汰策略、I/O 多线程),可最大化其性能潜力,支撑高并发、低延迟的应用需求。