为什么需要主从复制
主从复制是构建高可用,高性能集群的基础
- 利用主从复制,从节点能实时同步主节点的数据。当主节点发生宕机,通过主从切换,进行故障转移,继续为客户端提供服务器,不需要停机修复故障。
- 从节点能对主节点的读请求进行分流,降低主节点压力
单机存在的缺点
- 宕机后需要停机维护,无法对外提供服务。
- 单机的系统资源有限(cpu,内存,带宽,链接数),面对日益增长的需求,系统资源会达到瓶颈。
主从复制配置
- 使用slave of 命令进行动态配置
slaveof <ip> <port> //成为从服务器
salveof not one //取消作为从服务器,本机的数据不会丢失,从新作为从服务器会清空现有的数据
- 使用配置文件进行配置
slaveof <ip> <port>
slave-read-only //从服务器只读
使用命令 info replication 能看到复制相关信息
- run_id:redis服务器每次启动后会生成一个不同的run_id,标识当前的redis服务器。当主服务器的run_id发生改变时,所有的从服务器都需要进行全量复制
- master_repl_offset:复制偏移量,redis服务器数据写入的字节数,当从服务器的偏移量小于主服务器时,从服务器落后于主服务器,需要进行复制同步。
全量复制
全量复制流程
- 新的从服务器,会发送 psync命令给主服务器,上报主服务器的runid和当前的复制偏移数量,由于是第一次进行同步,没有主服务器的runid、当前的复制偏移量为-1。
- 主节点会判断从节点psync携带的信息,当没有主runid或者runid与当前主节点的runid或在复制偏移量不在backlog_buffer的范围内会使用全量复制进行同步。
- 主节点返回fullresync命令,携带主节点的runid和当前的复制偏移量,并且执行bgsave命令,生成rdb文件。
- 在生成rdb文件的过程中,如果有新的数据产生,会将数据写入到backlog-buffer缓冲中。
- rdb文件生成完成后,会将rdb文件和backlog-buffer中的数据发送给从节点。
- 从节点会清空当前的数据,把旧的rdb文件删除,重新装载新的rdb文件和backlog-buffer数据。
部分复制
- 从节点与主节点失去联系
- 主节点会将失去联系这段时间内哦,发送变化的数据存入backlog-buffer缓冲区中
- 从节点重新联系上主节点,发送psync命令,runid,复制偏移量给主节点
- 主节点判断复制偏移量是否在backlog-buffer缓冲区范围中,如果是进行部分复制
- 主服务器将backlog-buffer的数据发送给从节点。
- 从节点同步backlog-buffer中的数据,达到主从数据一致的目的。
存在问题
主从延时
- 主从数据不一致
由于存在网络延时,主节点上修改的数据,不能马上同步到从节点。客户端读取主节点和读取从节点的数据不一致。不过一般从节点同步的数据的时间非常短,不必太再意主从延时。 - 从节点读取到过期数据
redis删除过期数据有种策略。
1、操作数据时,判断数据是否过期。
2、定时采样数据,判断是否过期。
当定时采样数据的速度比不上数据过期的速度时,redis会存在大量的过期数据。
从节点是无法主动删除数据的(无论数据是否过期),只能通过同步主节点删除数据的操作,删除过期数据。当从节点与主节点失去联系或者正在同步时,会导致从节点会读取到过期数据。可以通过配置slave-serve-stale-data改变其行为,yes:返回数据给客户端(数据可能是过期的),no:已连接的客户端会被阻塞,新的连接请求会被拒绝
避免全量复制
- 从节点第一次全量复制,无法避免。调整maxmemory,较小的数据内存占用,能够降低全量复制对性能的影响。
- 设置合理的复制缓冲区大小,延长从节点失去联系的时间。重新连接后进行部分复制。
- 避免主节点重新启动,导致runid发生改变。
复制风暴
- 当主节点多从节点
- 在一台服务器上部署多个redis主节点