Redis总结(四)—— 复制、哨兵
1. 复制#
Redis的复制功能分为同步(sync)和命令传播(command propagate)两个操作:
-
同步:将从服务器的数据库状态更新至主服务器当前所处的数据库状态
-
命令传播:在主服务器的数据库状态被修改, 导致主从服务器的数据库状态出现不一致时, 让主从服务器的数据库重新回到一致状态
复制过程:
-
从节点执行
slaveof [masterIP] [masterPort]
,保存主节点信息。 -
从节点中的定时任务发现主节点信息,建立和主节点的 Socket 连接。
-
从节点发送 Ping 信号,主节点返回 Pong,两边能互相通信。
-
连接建立后,主节点将所有数据发送给从节点(数据同步)。
-
主节点把当前的数据同步给从节点后,便完成了复制的建立过程。接下来,主节点就会持续的把写命令发送给从节点,保证主从数据一致性。
数据同步过程:
Redis 2.8 之前使用 sync [runId] [offset]
同步命令,Redis 2.8 之后使用 psync [runId] [offset]
命令。两者不同在于,Sync 命令仅支持全量复制过程,Psync 支持全量和部分复制。
-
初次复制:从服务器第一次复制当前主服务器
-
断线后重复制:处于命令传播阶段的主从服务器,因为网络问题而中断复制,从服务器通过自动重连,重新连接上主服务器并继续复制
psync 具有完整重同步和部分重同步两种模式:
-
完整重同步:用于初次复制情况,执行过程同 sync,在这不赘述了。
-
部分重同步:用于断线后重复制情况,如果满足一定条件,主服务器只需要将断线期间执行的写命令发送给从服务器即可。
部分重同步的实现:
-
主从服务器的复制偏移量
-
主服务器每次向从服务器传播 n 个字节数据时,都会将自己的复制偏移量加 n。
-
从服务器接受主服务器传来的数据时,也会将自己的复制偏移量加 n
-
-
复制积压缓冲区
一个固定长度,先进先出的队列
当主服务器进行命令传播时,不仅会将命令发送给从服务器,还会发送给这个缓冲区
当从服务器向主服务器发送 psync 命令时,还需要将自己的复制偏移量带上,主服务器就可以通过这个复制偏移量和复制积压缓冲区的偏移量进行对比。
若复制积压缓冲区存在从服务器的复制偏移量 + 1 后的数据,则进行部分重同步,否则进行完整重同步。
-
run ID
运行 id 是在进行初次复制时,主服务器将会将自己的运行 id 发送给从服务器,让其保存起来。
当从服务器断线重连后,从服务器会将这个运行 id 发送给刚连接上的主服务器
心跳检测:
当完成了同步之后,主从服务器就会进入命令传播阶段,此时从服务器会以每秒 1 次的频率,向主服务器发送命令:REPLCONF ACK <replication_offset>
其中 replication_offset 是从服务器当前
的复制偏移量
发送这个命令主要有三个作用:
- 检测主从服务器的网络状态
- 辅助实现 min-slaves 选项
- 检测命令丢失(若丢失,主服务器会将丢失的写命令重新发给从服务器
主从复制的问题:
-
一旦主节点宕机,从节点晋升为主节点,同时需要修改应用方的主节点地址,还需要命令所有从节点去复制新的主节点,整个过程需要人工干预。
-
主节点的写能力受到单机的限制。
-
主节点的存储能力受到单机的限制。
-
原生复制的弊端在早期的版本中也会比较突出,比如:Redis 复制中断后,从节点会发起 psync。
此时如果同步不成功,则会进行全量同步,主库执行全量备份的同时,可能会造成毫秒或秒级的卡顿。
2. 哨兵#
Redis Sentinel 最小配置是一主一从。Redis 的 Sentinel 系统可以用来管理多个 Redis 服务器。
该系统可以执行以下四个任务:
-
监控:不断检查主服务器和从服务器是否正常运行。
-
通知:当被监控的某个 Redis 服务器出现问题,Sentinel 通过 API 脚本向管理员或者其他应用程序发出通知。
-
自动故障转移:当主节点不能正常工作时,Sentinel 会开始一次自动的故障转移操作,它会将与失效主节点是主从关系的其中一个从节点升级为新的主节点,并且将其他的从节点指向新的主节点,这
样人工干预就可以免了。
- 配置提供者:在 Redis Sentinel 模式下,客户端应用在初始化时连接的是 Sentinel 节点集合,从中获取主节点的信息。
工作原理:
-
每个 Sentinel 节点都需要定期执行以下任务:每个 Sentinel 以每秒一次的频率,向它所知的主服务器、从服务器以及其他的 Sentinel 实例发送一个 PING 命令
-
如果一个实例距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 所指定的值,那么这个实例会被 Sentinel 标记为主观下线
-
如果一个主服务器被标记为主观下线,那么正在监视这个服务器的所有 Sentinel 节点,要以每秒一次的频率确认主服务器的确进入了主观下线状态
-
如果一个主服务器被标记为主观下线,并且有足够数量的 Sentinel(至少要达到配置文件指定的数量)在指定的时间范围内同意这一判断,那么这个主服务器被标记为客观下线
-
一般情况下,每个 Sentinel 会以每 10 秒一次的频率向它已知的所有主服务器和从服务器发送 INFO 命令。
当一个主服务器被标记为客观下线时,Sentinel 向下线主服务器的所有从服务器发送 INFO 命令的频率,会从 10 秒一次改为每秒一次
-
Sentinel 和其他 Sentinel 协商客观下线的主节点的状态,如果处于 SDOWN 状态,则投票自动选出新的主节点,将剩余从节点指向新的主节点进行数据复制
-
当没有足够数量的 Sentinel 同意主服务器下线时,主服务器的客观下线状态就会被移除。
当主服务器重新向 Sentinel 的 PING 命令返回有效回复时,主服务器的主观下线状态就会被移除。
参考:
- 《Redis设计与实现》
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性