概述

  • 官方说明:https://redis.io/topics/replication
  • 作用:读(Slave)写(Master)分离,容灾恢复
  • 哨兵模式可以实现无人值守
  • 缺点:主从复制无疑会带来延迟(Master机器同步到Slave机器),使用哨兵模式则延迟会更明显。

测试配置准备(一台主机两台备机)

拷贝多个配置文件分别命名区分 redis{port}.conf

  • Master 端口6379
  • Slave1 端口6380
  • Slave2 端口6381
  • 其他方便区别配置
    • 使用后台方式启动服务 daemonize yes
    • pidfile redis{port}.pid
    • logfile redis{port}.log
    • dbfilename dump{port}.rdb

测试1 Master<Slave1, Slave2

  • 分别启动并连接上三个服务
    redis-server redis{port}.conf ps -ef|grep redis|grep -v grep redis-cli -p {port}
  • 客户端分别查看主从复制的信息 info replication
    # Replication role:master connected_slaves:0 master_replid:d3d1de9a393d82c4dc1787800471fffba1323b3a master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0
  • 开始数据主从复制
    • Master

      set k1 v1
      set k2 v2
    • Slave1和Slave2

      get k1
      slaveof 127.0.0.1 6379
      get k1
      get k2
    • 可以看到Slave已经把Master的数据复制过来了
    • Master继续设置KV,验证Slave数据同步
    • 再次查看主从复制信息 info replication 可以看到匹配的信息
    • Slave上进行写操作则会报错
      (error) READONLY You can't write against a read only replica.
  • 将Master shutdown,Slave不动
    • Slave查看 info replication
    • 可以看到Slave数据依然在,且与Master的关系还在
    • 当Master重新启动,主从关系恢复如初
  • 将Slave1 shutdown,Master不动
    • Slave2的主从关系不会有变化
    • Slave1重新启动后,主从关系消失了,需要重新 slaveof 127.0.0.1 6379 进行数据同步
    • 如果希望Slave挂/断掉重启后“再续前缘”,需进行Slave-server的配置 replicaof 127.0.0.1 6379

测试2 Master<Slave1<Slave2(Slave1是Slave2的Master)

  • 上一个Slave可以是下一个Slave的Master,这样可以分担Master的写压力
  • Slave2改变Master:slaveof 127.0.0.1 6380
  • 查看Slave1的主从信息变化:info replication
  • 目前从整体上看,数据完整性和之前“一主二仆”模式是一样的,只是现在Slave2是从Slave1同步数据,变成“薪火相传”模式,那么Slave1怎么分担Master的压力?继续操作..
  • 将Master shutdown,模拟Master机器挂掉了,此时可以对Slave1 slaveof no one,让Slave1“反客为主”新的Master(role有Slave变成Master),这样就可以对其进行写操作,并和Slave2继续主从关系
  • 此时,原Master服务重启恢复,将成为单独的Master服务,被原Slave1、Slave2孤立在外。
  • 然后,将Slave1重新挂给Master,恢复最原始的“一主二仆”关系,会发现Slave1和Slave2在Slave1“反客为主”时期写的数据消失了,而变成了Master的数据。由此可知Slave变更Master后,Slave的数据会先清空,然后同步为新的Master的数据

哨兵(sentinel)模式

说明

  • 前面的测试中,当Master挂掉,还需要人为的将某个Slave转换为Master,而实际上机器挂掉可能发生在任意时刻,比如凌晨,所以不能依靠人为处理。
  • 哨兵模式弥补了上面的缺点,达到所谓“无人值守”的效果。
  • 效果1:使用哨兵模式,会另启动一个进程,对Master进行监控,如果监控到Master故障,则根据投票机制自动将某个Slave升级为新的Master(查看sentinel日志可以看到投票细节)。
  • 效果2:哨兵模式将Slave1升级为Master后,如果原Master恢复,哨兵监控到后,会自动把原Master降级挂给Slave1,主从关系完全变更。

配置与测试

  • 恢复“一主二仆”模式,一个Master(79),两个Slave(80、81)
  • 新建sentinel配置文件 vi sentinel.conf,内容:
    sentinel monitor master6379 127.0.0.1 6379 1
    说明:
    • sentinel monitor ... 指示sentinel监听后面机器上的Master
    • master6379 给后面要监听的Master取个名字
    • 127.0.0.1 6379 监听目标Master服务的ip和端口
    • 最后的数字m=1表示sentinel投票数,即当有n个sentinel(sentinel集群)认为这个Master挂了时,才会认为它真的挂了,然后进行故障迁移动作。这里是单机测试,所以n直接设置为1。
    • 可以新行,监听多个主机Master
  • 启动哨兵
    redis-sentinel sentinel.conf 或者 redis-server sentinel.conf --sentinel
    启动后可以看到日志:
    # Sentinel ID is 89568e210930ec9fe58e4cf856a5ef8e14501955 # +monitor master master6379 127.0.0.1 6379 quorum 1 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ master6379 127.0.0.1 6379 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ master6379 127.0.0.1 6379
  • 将Master shutdown,观察哨兵日志
    # +sdown master master6379 127.0.0.1 6379 # +odown master master6379 127.0.0.1 6379 #quorum 1/1 # +new-epoch 1 # +try-failover master master6379 127.0.0.1 6379 # +vote-for-leader 89568e210930ec9fe58e4cf856a5ef8e14501955 1 # +elected-leader master master6379 127.0.0.1 6379 # +failover-state-select-slave master master6379 127.0.0.1 6379 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ master6379 127.0.0.1 6379 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ master6379 127.0.0.1 6379 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ master6379 127.0.0.1 6379 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ master6379 127.0.0.1 6379 # +failover-state-reconf-slaves master master6379 127.0.0.1 6379 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ master6379 127.0.0.1 6379 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ master6379 127.0.0.1 6379 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ master6379 127.0.0.1 6379 # +failover-end master master6379 127.0.0.1 6379 # +switch-master master6379 127.0.0.1 6379 127.0.0.1 6380 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ master6379 127.0.0.1 6380 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ master6379 127.0.0.1 6380 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ master6379 127.0.0.1 6380
    可以看出,哨兵监控到79Master挂掉了,然后投票确定,然后重新选举80为新的Master。
  • 查看原Slave的主从信息,可以看出80Slave的role变成了Master
  • 重启79Master,查看哨兵日志和主从关系
    * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ master6379 127.0.0.1 6380
    从日志也能看出,哨兵对79进行了convert-to-slave操作
01-26 05:57