Redis源码简洁剖析16—服务器、复制和哨兵原创
命令请求的过程
Redis 服务器负责与多个客户端建立网络连接,处理客户端发送的命令请求,在数据库中保存客户端执行命令所产生的数据。
Redis 服务器中的 serverCron 函数默认每隔 100 毫秒执行一次,负责管理服务器的资源,并保持服务器自身的良好运转。
整体流程都在下面的两张图里了~
复制
什么是复制
在 Redis 中,可以通过设置 slaveof 选项,让一个服务器去复制(replicate)另一个服务器:
- 主服务器(master)
- 从服务器(slave)
为什么需要复制
在 Redis 集群中,保证在单机故障情况下,能够有副本,可通过哨兵(Sentinel)机制实现 Redis 集群的高可用。
复制的实现
Redis 的复制分为两个操作:
同步操作(sync):从服务器的数据库状态更新至主服务器当前的状态
命令传播(command propagate):主服务器上的写命令,传播给从服务器
同步
当客户端向从服务器发送 SLAVEOF 命令,要求从服务器复制主服务器时,从服务器首先需要执行同步操作,将从服务器的数据库状态更新至主服务器当前的数据库状态。
命令传播
在同步之后,主服务器的所有写命令,都需要传播给从服务器,以保证主从服务器数据库状态的一致。
新版复制功能实现
Redis 从 2.8 版本开始,使用 PSYNC 命令代替 SYNC 命令来执行复制时的同步操作。PSYNC 命令有完整重同步和部分重同步两种模式。
- 完整重同步:和 SYNC 命令执行的步骤一样
- 部分重同步:处理断线后重复制的情况。当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只接收并执行这些命令,就可以将数据库更新至主服务器的最新状态。
哨兵 Sentinel
什么是 Sentinel
Sentinel(哨兵)是 Redis 的高可用解决方案:由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器及从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令。
Sentinel 本质上只是运行在特殊模式下的 Redis 服务器,具体细节可参考:Redis Sentinel Documentation
简易工作原理
下图展示了服务器与 Sentinel 系统:
下图展示了主服务器下线时的情况:
下图展示了故障转移:
下图展示原主服务器(Server1)再次上线后,降级为从服务器的流程:
Sentinel 系统选举
Sentinel 系统选举领头 Sentinel 的方法是 Raft 算法。
具体参考:Raft 算法分析 生动形象的网站:http://thesecretlivesofdata.com/raft/ 论文:https://raft.github.io/raft.pdf