Redis主从复制讲解以及主从状态检测

什么是Redis主从复制?
主从复制就是主机数据更新后根据配置和策略,自动同步到备份机的master/slaver机制,master以写为主,slave以读为主。
为什么要有主从复制机制?

  • 读写分离,性能扩展
  • 容灾快速恢复

Redis主从复制讲解以及主从状态检测_第1张图片

配置

一台主机上的一个redis可以有多个配置,不同的配置监听不同的端口号。

主配置文件redis-6382.conf

daemonize yes
pidfile /var/run/redis-6382.pid
port 6382
logfile "/usr/local/redis/redis-5.0.4/data/6382.log"
dbfilename dump-6382.rdb
dir /usr/local/redis/redis-5.0.4/data/
appendonly no
slave-read-only yes

从配置文件redis-6383.conf

daemonize yes
pidfile /var/run/redis-6383.pid
port 6383
logfile "/usr/local/redis/redis-5.0.4/data/6383.log"
dbfilename dump-6383.rdb
dir /usr/local/redis/redis-5.0.4/data/
appendonly no
slaveof 127.0.0.1 6382

开启主从redis

redis-server redis-6382.conf
redis-server redis-6383.conf

查看是否开启成功

ps -aux | grep redis

在这里插入图片描述
开启客户端redis

redis-cli -p 6382

查看主从复制的相关信息:info replication
Redis主从复制讲解以及主从状态检测_第2张图片

redis-cli -p 6383

Redis主从复制讲解以及主从状态检测_第3张图片
查看run_id(标识作用)

redis-cli -p 6382 info server | grep run

从机不能写数据,只能在主机上写,从机可以读

一主多仆模式
一个master,多个slave直接相连

薪火相传模式
上一个slave可以是下一个slave的master,slave同样可以接受其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻master的写压力,取中心化降低了风险。
在redis客户端通过slaveof ip port 指定属于哪个从主redis(将配置文件中的slaveof这一行去掉,则启动时,默认为master)
举例:假设现在6379端口监听的是主机,6380是6379下的一个从机,6381是6380下的一个从机,那么此时从info replication查看6380是master还是slave?
答案是slave,但是后面还会有个键值为 connected_slaves:1以及他的slave的信息。也就是中间的6380的角色还是slave,不会因为它有slave而变成master,那么问题来了,6380监听的redis上能否写数据?
答案是不能,那这种模式的意义何在?
就是为了减轻master的压力,在一个master直接连了n个slave的模式下,master每写一次数据,就会复制n次数据到slave。但是,如果是这种“薪火相传”的模式,master每写一次,只需传递一次数据到它直接相连的slave,再由该slave传递给其他slave。所以,中间的这个slave不是为了让它变成master,而是它的角色依然是slave,即不可写,只是为了分担master的压力。
另一个注意点: 如果某个slave中途变更master,则会清除它之前的数据,再将新的master数据拷贝过来。
薪火相传模式的缺点是:一旦某个slave宕机,它的slaves都无法备份数据了。
Redis主从复制讲解以及主从状态检测_第4张图片

主从复制原理

  • 每次从机联通后,都会给主机发送sync指令
  • 主机立刻进程存盘操作,发送RDB文件给从机
  • 从机收到RDB文件后进行全盘加载
  • 之后每次主机的写操作,都会立刻发送给从机,从机执行相同的命令(即生成自己的快照)

所以即使某个slave中途宕机,从新加入,还是可以恢复所有的数据。
Redis主从复制讲解以及主从状态检测_第5张图片

问题
问题一:切入点问题:slave是从头开始复制内存中的数据还是从切入点(加入点,即中途将一个slave加入的时刻)开始复制?比如在slave2加入之前,master已经写入两条数据,slave2加入之后,master又写入一条数据,此时slave能读到几条数据?
答案是从头开始复制,即能读取到3条数据。
问题二:主机shutdown后从机上位还是原地待命?
原地待命,可以检测到master宕机,即master_link_status值为down,但是依旧不能写。除非重写指定它为master。
问题三:一台从机宕调后,再次重启,是否还能读取所有数据(宕机之前的旧数据和宕机之后新增的数据)?
可以(原因见上面的主从复制原理)

反客为主
方法一:手动
当master挂掉之后,可以在redis客户端用命令slaveof no one 将给slave变成master,然后再手动将master直接相连的slave所属的master改掉,命令:slaveof ip port ,而变为master的那个slave下的slave不用管,因为它们本来就把该slave当做master。
显然手动方式很麻烦。
方法二:哨兵模式
具体请看:Redis Sentinel 哨兵模式配置详解和实践

全量复制

对于一个存储了很多信息的master,slave需要同步连接master之前的数据,以及连接当前的数据,就用到全量复制。
1.psyns ? -1 第一个参数表示run_id 第二个参数表示偏移量,第一次不知道两个值,所以传?和-1
2.master收到slave的消息后,把run_id和偏移量传给slave
3.slave报错master的基本信息
4.master生成快照,bgsave是触发redis生成快照的方式之一
5.redis的buffer缓冲区中保存了最新数据
Redis主从复制讲解以及主从状态检测_第6张图片

部分复制

如果slave突然断开连接,为保证这段时间master中的数据不会在slave中丢失,当slave再次连接的时候,使用部分复制实现数据同步(虽然可以使用全量复制,但是全量复制开销大)
下图中的第四步,slave把自己的run_id和偏移量给master,如果master发现偏移量在自己的buffer(队列)内,则返回contiune,把buffer中的数据传给slave,如果超出了buffer,为了保证数据不丢失,则只能使用全量复制。这样,slave和master数据就能达到同步。
Redis主从复制讲解以及主从状态检测_第7张图片

心跳检测

如果主服务器超过一秒钟没有收到从服务器发送来的REPLCONF ACK命令,那么主服务器就知道从服务器之间的连接出现了问题。
通过向主服务器发送info replication命令,在slave一行中,有个lag键值对,该值表示该从服务器最后一次向主服务器发送REPLCONF ACK命令距离现在过了多少秒,该值一般在0~1秒间跳动,如果超过1秒的话,那么说明主从服务器之间的连接出现了故障。

你可能感兴趣的:(Redis)