Redis主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
默认情况下,每台Redis服务器都是主节点,有一个主节点。可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。)
一、概述
主从的作用如下所示:
1.数据的热备份
2.故障恢复:在主服务器挂掉的时候,从服务器可以顶替过来
3.负载均衡:读写分离,写数据可以主服务器来做,读操作从服务器来操作
备注:主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
对于主从服务器来说,它们之间的数据同步主要有两种,一种是全量复制,一种是部分复制。
二、全量复制
全量复制发生在下面两个情形下:
1.从节点判断无法进行部分复制,向主节点发送全量复制的请求;
2.从节点发送部分复制的请求,但主节点判断无法进行部分复制;
全量复制是非常重型的操作的具体表现在下面几点:
(1)主节点通过bgsave命令fork子进程进行RDB持久化,该过程是非常消耗CPU、内存(页表复制)、硬盘IO的
(2)主节点通过网络将RDB文件发送给从节点,对主从节点的带宽都会带来很大的消耗
(3)从节点清空老数据、载入新RDB文件的过程是阻塞的,无法响应客户端的命令;如果从节点执行bgrewriteaof,也会带来额外的消耗
三、部分复制
由于全量复制在主节点数据量较大时效率太低,因此Redis2.8开始提供部分复制,用于处理网络中断时的数据同步。
过程如下:
首先,从节点根据当前状态,决定如何调用psync命令:
1.如果从节点之前未执行过slveof或最近执行了slaveof no one,则从节点发送命令为psync ? -1,向主节点请求全量复制;
2.如果从节点之前执行了slaveof,则发送命令为psync <runid> <offset>,其中runid为上次复制的主节点的runid,offset为上次复制截止时从节点保存的复制偏移量。
其次,主节点根据收到的psync命令,及当前服务器状态,决定执行全量复制还是部分复制:
1.如果主节点版本低于Redis2.8,则返回-ERR回复,
此时从节点重新发送sync命令执行全量复制;
2.如果主节点版本够新,且runid与从节点发送的runid相同,
且从节点发送的offset之后的数据在复制积压缓冲区中都存在,
则回复+CONTINUE,表示将进行部分复制,从节点等待主节点发送其缺少的数据即可;
3.如果主节点版本够新,但是runid与从节点发送的runid不同,
或从节点发送的offset之后的数据已不在复制积压缓冲区中(在队列中被挤出了),
则回复+FULLRESYNC <runid> <offset>,表示要进行全量复制,
其中runid表示主节点当前的runid,offset表示主节点当前的offset,
从节点保存这两个值,以备使用。
(这部分来自:https://www.cnblogs.com/kismetv/p/9236731.html)
四、补充知识:
1. 复制偏移量
主节点和从节点分别维护一个复制偏移量(offset),代表的是主节点向从节点传递的字节数。offset用于判断主从节点的数据库状态是否一致:如果二者offset相同,则一致;如果offset不同,则不一致,此时可以根据两个offset找出从节点缺少的那部分数据。
复制积压缓冲区是由主节点维护的、固定长度的、先进先出(FIFO)队列,默认大小1MB;当主节点开始有从节点时创建,其作用是备份主节点最近发送给从节点的数据。注意,无论主节点有一个还是多个从节点,都只需要一个复制积压缓冲区。
在命令传播阶段,主节点除了将写命令发送给从节点,还会发送一份给复制积压缓冲区,作为写命令的备份;除了存储写命令,复制积压缓冲区中还存储了其中的每个字节对应的复制偏移量(offset)。由于复制积压缓冲区定长且是先进先出,所以它保存的是主节点最近执行的写命令;时间较早的写命令会被挤出缓冲区。
(备注:这里的缓存区大小是可以设置的。)
每个Redis节点(无论主从),在启动时都会自动生成一个随机ID(每次启动都不一样),由40个随机的十六进制字符组成;runid用来唯一识别一个Redis节点。