Redis的单多线程、主从复制、RDB与AOF原理学习心得
Redis单线程与多线程机制
首先,要搞懂Redis是单线程还是多线程
- 核心命令处理 =单线程
Redis 处理客户端的读写命令(get/set/delete…) 全程只用一个主线程。所有命令排队执行,不存在多线程竞争、锁、线程切换开销,这是 Redis 极快的核心原因之一 - 网络 IO / 持久化 =多线程
Redis 不是全程单线程,
后台任务用多线程:
网络 IO 读写(6.0+ 引入多线程 IO)RDB 快照、AOF 重写
异步删除、lazy free主从复制
一、单线程机制
- 基于内存
所有操作在内存完成,纳秒级响应 - 单线程无锁竞争
不用加锁、解锁
没有线程上下文切换
代码简单、稳定、不易出 bug - 关键:使用了 IO 多路复用技术
一个线程就能同时监听成千上万个连接,这是 Redis 高性能的底层基石。
IO多路复用
单个线程,通过一个系统调用,同时监听多个 socket 的读写事件。
当某个 socket 就绪(可读 / 可写),就去处理,不阻塞、不浪费 CPU。
分步流程
1.注册监听:主线程把所有客户端 Socket 连接,全部注册到 IO 多路复用器 中。多路复用器:统一托管所有连接。
2.阻塞等待事件:多路复用器进入阻塞状态,不占用 CPU,静静等待任意客户端发请求(读 / 写事件)。
3. 事件触发:某一个 / 多个客户端发送数据,对应 Socket 变为就绪状态。
4.唤醒主线程:多路复用器立刻返回就绪的连接列表,唤醒主线程。
5.串行处理任务:主线程遍历就绪连接,逐个执行 Redis 命令(单线程串行,无锁竞争)。
6.结果返回:命令处理完成,把响应数据写回对应客户端,之后主线程再次回到阻塞等待状态,继续等待新事件。
Redis的主从复制
简介
Redis 主从复制,指一台主节点(Master) 将自身的数据,自动同步到一台或多台从节点(Slave) 的机制。
架构上遵循一主多从模式:
- 主节点:承担写操作,接收新增、修改、删除请求
- 从节点:默认只读,只处理查询请求,不对外提供写服务
流程图示
核心特点
读写分离:如图
其中master节点专门负责写操作(set k1 v1)
follower节点专门负责读操作(get k1)
注意:
1.数据必须一致(一致性问题)不是强一致,
而是最终一致(同步数据有延时,允许在一段时间内数据不一致)
言下之意:master有新数据那么follower也必须要有这个新数据
2.master如果一旦宕机,那将如何?follower一直等待master活过来,
依然作为master的小弟(从机 不会篡位)。此时会产生问题:在这段时间内,redis主从架构不能提供写服务
哨兵模式
1.核心作用:
解决主从复制中主节点宕机后无法自动故障转移的问题,实现主节点的自动选举与切换
2. 工作原理与流程
- 健康监控
哨兵通过定时任务(类似 setInterval()),定期向 master 节点发送远程调用,做健康检查。
如果返回 status = “unavailable”,判定 master 节点宕机。 - 故障通知
哨兵检测到 master 宕机后,会向所有 follower 节点发送通知,告知 master 已宕机,让它们准备进行新主选举。 - 故障转移与主从切换
从 follower 中选举一台作为新的 master 节点。
原 master 节点恢复后,会自动降级为新 master 的从节点,继续同步数据(master<->follower 关系反转)。
3.流程图示
- 哨兵一旦监听到Master节点宕机此时就会给follower节点发送通知,告知,master已经宕机,做好选举准备,随机选择一台机器上位,那么当原来的master恢复后,那么这个master节点就会自动成为新的master节点的从机
RDB与AOF
一、核心概念
Redis 是内存数据库,数据默认存储在内存中,服务重启会丢失数据。持久化就是把内存数据写入磁盘,实现数据的灾备与恢复,主要分为 RDB 和 AOF 两种方案,也支持两者结合的混合持久化。
二、RDB(Redis Database)持久化
1. 原理
将 Redis 内存中的数据做快照(snapshot),保存为一个 .rdb 二进制文件,用于灾备与恢复。
2. 优缺点
| 优点 | 缺点 |
|---|---|
| 性能好:直接序列化内存数据,文件体积小,恢复速度快 | 会丢失数据:两次快照之间的数据无法保存,故障时会丢失最近一次快照后的所有数据 |
| 不占用磁盘额外开销(相比 AOF 日志) | 快照过程中如果数据量极大,fork 子进程可能短暂影响性能 |
3. 两种实现方式
(1)save(同步阻塞)
特点:主线程直接执行快照,会阻塞所有客户端请求,生产环境不推荐。
配置方式(redis.conf):
格式:save <秒数> <修改次数>,表示指定秒数内修改次数达到阈值则触发RDB
save 3600 1 # 3600秒(1小时)内至少1次修改
save 300 100 # 300秒(5分钟)内至少100次修改
save 60 10000 # 60秒内至少10000次修改
(2)bgsave(非阻塞,主流方式)
特点:主线程调用 fork() 创建子进程,由子进程完成快照写入磁盘,主线程继续处理客户端请求,不阻塞业务。
关键技术:
写时复制(Copy-On-Write, COW)
- 子进程 fork 时,和父进程共享同一份内存数据副本;
- 主线程后续修改数据时,会先复制一份副本给子进程,保证子进程快照的是 fork 瞬间的数据,互不干扰。
三、AOF(Append Only File)持久化
1. 原理
记录客户端发送的每一条写命令,追加到.aof日志文件末尾,重启时重放日志恢复数据。
2. 优缺点
| 优点 | 缺点 |
|---|---|
| 数据安全:支持每秒 / 每次写操作同步,几乎不丢数据 | 性能开销大:文件会持续膨胀,重放恢复速度慢 |
| 日志可读,可手动修改(如误删数据时) | 写命令追加 + 重写会占用额外磁盘 IO,高并发场景性能不如 RDB |
3. 配置与刷盘策略(redis.conf)
appendonly yes # 开启AOF持久化
刷盘策略(三选一)
appendfsync always 每次写操作都同步刷盘,数据零丢失,性能最差
appendfsync everysec # 每秒刷盘一次,默认配置,平衡性能与数据安全
appendfsync no 不主动刷盘,由操作系统决定,性能好但可能丢数据
4. AOF 重写机制
AOF 文件会随写操作持续变大,Redis 会自动触发重写,压缩日志体积:
auto-aof-rewrite-percentage 100 # 文件大小比上一次重写后增长100%(即翻倍)时触发
auto-aof-rewrite-min-size 64mb # 触发重写的最小文件大小(低于64MB不触发)
四、RDB vs AOF 对比与建议
| 维度 | RDB | AOF |
|---|---|---|
| 数据安全 | 丢数据(取决于快照间隔) | 几乎不丢数据(取决于刷盘策略) |
| 性能 | 高(快照写入,恢复快) | 低(日志追加 + 重放,恢复慢) |
| 文件体积 | 小(二进制快照) | 大(命令日志,重写后会压缩) |
| 故障恢复 | 快 | 慢 |
