redis 主从复制和哨兵模式(二)

Redis 主从复制

为了分担单机 redis 的数据服务压力,需要进行读写分离,所以搭建 redis 的主从结构,主节点负责写,从节点负责读,主节点定期把数据同步到从节点。

配置主从

# 配置文件中增加一行以哪个 redis 为主
slaveof ip port
# 主节点的密码
masterauth h123

# 从节点只读,默认配置
slave-read-only yes
# 关闭 TCP_NODELAY ,无论多大的包都直接发送,默认即可
repl-disable-tcp-nodelay no
# 主节点默认每 10 秒向从节点发送心跳包,默认即可
repl-ping-slave-period 10

主从拓扑结构

slaveof 只是说明本机是哪台的从节点,所以很灵活的实现可种主从结构

  • 一主一从:用于主节点故障转移从节点,当主节点的“写”命令并发高且需要持久化,可以只在从节点开启AOF(主节点不需要),这样即保证了数据的安全性,也避免持久化对主节点的影响
  • 一主多从:用于读场景比较多的场合,但这样会造成主节点需要同步较多的从节点,影响主节点的带宽。
  • 树状主从:主节点推送更少的从节点,由从节点来递归推送

可以使用 info 命令查询当前 redis 的从节点个数和位置,需要自己依次遍历查询才能得到完整的拓扑结构

数据同步

redis 2.8版本以上使用psync命令完成同步,过程分全量复制部分复制

  • 全量复制:一般用于初次复制场景(第一次建立SLAVE后全量)
  • 部分复制:网络出现问题,从节点再次连接主节点时,主节点补发缺少的数据,每次数据增量同步

故障修复

当主节点出现故障时,已经不能对外提供写服务 ,但从节点可以提供读服务

可以将其中一台从节点转变成主节点,需要人工处理,无法实现高可用

处理流程

  1. 修改一台从节点为主节点,在节点执行 slaveof no one
  2. 让其它从节点以现在的主节点为主节点,redis-cli 执行 slaveof ip port

Redis 哨兵机制(Sentinel)

哨兵机制主要是为了解决主从复制不能自动切换 master 的问题,当主节点故障时,由 sentinel 自动完成故障发现和修复,并通知应用方,实现高可用

配置哨兵节点配置文件,并启动三个哨兵

# 后台启动
daemonize yes
# 监控主节点
sentinel monitor mymaster 127.0.0.1 6379 1
# 启动哨兵 
./redis-sentinel conf/sentinel.conf  

哨兵的监控任务

  1. 每 10 秒会向主节点和从节点发送 info 命令获取最新拓扑图
  2. 每个哨兵节点会每隔 2 秒向 redis 数据节点的指定主题(__sentinel__:hello)上发送该哨兵节点对于主节点的判断以及当前哨兵节点的信息;同时每个哨兵节点自己也会订阅这个主题,用来了解其它节点的判断,其实就是通过 publish/subscribe 来完成的。
  3. 每隔 1 秒每个哨兵会向主节点,从节点及其余哨兵节点发送一次 ping 命令做心跳检查,用来判断节点是否正常。

判断主节点是否异常

主观下线(sdown):ping 命令如果在配置的 down-after-milliseconds 之后没有收到有效回复,那么就认为该数据节点主观下线。

客观下线:超过选举个数哨兵认为异常

当有哨兵节点判断主节点异常时,此时该哨兵节点会通过指令sentinel is-masterdown-by-addr寻求其它哨兵节点对主节点的判断,当超过quorum(选举)个数的哨兵节点回答下线,则认为该主节点客观下线

哨兵领导者的选举

当主节点客观下线时,需要选举出一个哨兵节点做为哨兵领导者,以完成后续选出新的主节点的工作。

这个选举的大体思路是:

  • 每个哨兵节点通过向其他哨兵节点发送sentinel is-master-down-by addr命令来申请成为哨兵领导者。
  • 而每个哨兵节点在收到一个sentinel is-master-down-by addr命令时,只允许给第一个节点投票,其他节点的该命令都会被拒绝。
  • 如果一个哨兵节点收到了半数以上的同意票,则成为哨兵领导者。
  • 如果前面三步在一定时间内都没有选出一个哨兵领导者,将重新开始下一次选举。

    可以看到,这个选举领导者的流程很像 Raft 中选举 Leader 的流程。

如何选择谁成为主节点

在剩下的从节点中,按照以下顺序来选择新的主节点:

  • 过滤掉“不健康”的数据节点:比如主观下线、断线的从节点、五秒内没有回复过哨兵节点 Ping 命令的节点、与主节点失联的从节点。
  • 选择 Slave-Priority(从节点优先级)最高的从节点,如果存在则返回,不存在则继续后面的流程。
  • 选择复制偏移量最大的从节点,这意味着这个从节点上面的数据最完整,如果存在则返回,不存在则继续后面的流程。
  • 到了这里,所有剩余从节点的状态都是一样的,选择 runid 最小的从节点。

提升从节点为主节点

最后就是把从节点转移成主节点,并让其它从节点以它为主节点,和手动处理是一样的流程,只是发起命令人变成了哨兵

  1. 修改它为主节点,在节点执行 slaveof no one
  2. 让其它从节点以现在的主节点为主节点,执行 slaveof ip port
  3. 哨兵节点集合会将原来的主节点更新为从节点,当其恢复之后命令它去复制新的主节点的数据。

你可能感兴趣的:(redis,java,主从复制)