redis-主从复制

总以为书写在书上的历史离我们很远,其实很近,因为过去的每一天都将成为历史,只不过它们太过平凡,不会被历史所铭记而已。但是它们却是我们唯一的历史,应当用情去描绘,哪怕会有一些错误,也要勇敢的走下去。

master/slave

功能:

  • 主从复制

  • 读写分离

  • 容灾备份

常用三种配置方案:

一主二从

一台为master,2台或多台为slave

  1. 配从(库)不配主(库)

  2. 从库配置:

    1
    slaveof master_ip master_port

    每次主机与从机断开连接之后都需要重新连接,除非在redis.conf配置文件中写好

  3. 查看信息

    1
    info replication

实例

master与slave关系的确立:

假设有三台主机,都没有在配置文件中配置master与slave的从属关系。现在三台主机都开启了redis服务

三台主机的关系现在是平等的,master主机不需要配置。slave主机需要配置是那个主机的从机slaveof master_ip master_port

两台主机都这么配置了之后,master主机是谁也就明确了。slave主机的作用就是备份master主机的数据,所以有几台slave就有几个备份主机

slave何时备份master的数据

无论slave主机何时成为master主机的从机,都会立刻同步备份所有master主机的数据

从机是否能写数据

从机上只能读数据,不能写数据。即读写分离

主机服务停止之后从机状态

master主机服务停止之后,slave主机是否能自动成为master?

默认配置情况下,master主机服务停止之后,slave主机不会自动成为master,而是会等待与master主机的连接

master主机重新恢复服务之后,slave主机会自动连接master主机并实现数据同步备份

从机服务停止之后再恢复时角色

如果没有在redis.conf配置文件中配置属于那台主机的从机,那么其恢复之后无法成为slave主机,只有重新输入命令让其成为slave

在其恢复之后,会马上与master主机进行数据同步备份

薪火相传

链式的主从关系

一台机器角色不只一种,除了第一台的master和最后一台的slave角色只有一种外,中间的机器既可以作为上一台机器的slave,又可以作为下一台机器的master

反客为主

在一主二从的这种关系体系中,当master主机redis服务停止之后,slave主机使用命令slaveof no one来成为master主机,

其它从机可以重新使用slaveof master_ip master_port命令来成为这台新的master的slave

如果这时之前的master主机修复之后,其仍然为master的角色,但是没有slave了

复制规则

原理:slave连接到master后会发送一个sync命令

全量复制:slave第一次连接到master会进行一次全量复制

增量复制:连接master之后的复制为增量复制

重新全量复制:当slave与master连接断开后,再次连接master时又会进行一次全量复制

哨兵模式sentinel

即为自动化的反客为主模式,master服务停止之后slave通过投票选举出新的master。有一点不同:之前的master恢复之后会作为slave

模式的开启

在redis.conf的相同目录下配置sentinel.conf

1
touch sentinel.conf

添加

1
sentinel monitor master_name master_ip master_ip num
  • master_name为随意起master主机的名字
  • num为规定的选举投票数,必须要票数大于num才能成为master。所以在一主二从的体系中,num为1,即master主机挂掉之后,剩下的两个从机投票,当某一个从机获得两票的时候,其成为master。当然如果从机不止两台,那么这个数字就需要变化。这个数字的值需要超过剩下slave数量的一半,比如说有1台master,10台slave,那么投票数必须要超过5票。必须要获得一半以上的民心

执行

1
redis-sentinel /dir/to/sentinel.conf

这条命令执行的时间应该为主从机关系确立后就执行,它执行后就会立刻监控master主机的状态,一旦master主机挂掉,就立刻从从机中进行选举,并选出新的master主机

总结:

之前有RDB数据备份和AOF指令记录,但是这两种策略的缺陷就是仅仅是针对同一台主机。而实际中的情况要更加糟糕,可能这台主机都挂掉了,所以很有必要使用多台主机进行备份,可能会想到使用脚本来写一个定时备份的功能,将数据复制到其它主机上,但是redis自身提供了这一功能,而且更好。

这就是master/slave模式,这种模式下有两种方案:

  1. 一台主机作为master进行写操作,其它主机作为slave从机用来备份。
    • 如果不进行其它设置,那么主机挂掉之后,其它从机会进入等待。知道master恢复,重新连接
    • 在master主机挂掉之后,我们还可以从slave主机中选择一台手动指定为master,重新分配slave,并形成新的master/slave模式。挂掉的master恢复后就没有了slave
    • 这种手动设置的方法有一定的缺陷,虽然可以将配置写入redis.conf配置文件中,但是在主机挂掉的情况下还是需要手动配置,所以就有了自动化的哨兵模式sentinel,按照配置文件sentinel.conf中指定的规则,可以在master挂掉的情况下自动重新分配master,原先挂掉的master恢复后可作为从机运行
  2. 链式的master/slave方案中,master主机不止一台,作为slave的主机同样可以作为其slave主机的master。这种情况下,如果master主机挂掉了,其slave也是其它主机的master不会成为master,会等待master的恢复

docker中redis主从复制的启动

在docker中使用的redis默认开启了远程连接,所有不需要关心配置问题,而且我都没有找到配置文件在哪里,不过只需要配置好端口就可以使用主从复制。如果要使用配置文件来完成master/slave的话,应该是用挂载配置文件的方式吧

这里来完成链式的master/slave模式,一共三个redis服务

1
2
3
4
5
6
7
8
9
10
11
12
sudo docker pull redis
sudo docker run --name redis-master -p 6379:6379 -d redis
sudo docker run --name redis-middle -p 6380:6379 -d redis
sudo docker run --name redis-slaver -p 6381:6379 -d redis

sudo docker exec -it redis-master redis-cli

sudo docker exec -it redis-middle redis-cli
> slaveof 192.168.0.6 6379

sudo docker exec -it redis-slaver redis-cli
> slaveof 192.168.0.6 6380

这里需要注意的就是设置master的ip地址时不能使用127.0.0.1,否则显示连接为down,找了半天错误,并不是配置问题。主要问题就是两个,一个是端口要映射正确,第二个就是ip地址设置正确。