redis入门第七课:主从复制

2019-05-23  本文已影响0人  阿狸404

1.主从复制在windows环境下的搭建

1.1 搭建一主两从

复制三份下载好的redis到同一个包redis下,并命名为redis6379,redis6380,redis6381,如图所示:


1556073069(1).png

1.2 修改redis.windows.conf配置文件

# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6379
# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6380
slaveof 127.0.0.1 6379
# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6381
slaveof 127.0.0.1 6379

这样我们就搭建了主服务器:127.0.0.1 6379,从服务器:127.0.0.1 6380,127.0.0.1 6380.

1.3 启动服务器

为了方便,我们写三个脚本来启动服务。如图所示:


1556073323(1).png
@echo off
title redis6379
cd redis6379
redis-server.exe redis.windows.conf
exit
@echo off
title redis6380
cd redis6380
redis-server.exe redis.windows.conf
exit
@echo off
title redis6381
cd redis6381
redis-server.exe redis.windows.conf
exit

启动如下:


master:6379.png
slave:6380.png
slave:6381

1.4 测试

开启各个redis客户端测试:

主服务器:set msg "hello"
如下所示:

D:\company\redis\redis6379>redis-cli -p 6379
127.0.0.1:6379> set msg "hello world"
OK
127.0.0.1:6379>

从服务器获取:get msg
如下所示:

D:\company\redis\redis6380>redis-cli -p 6380
127.0.0.1:6380> get msg
"hello world"
127.0.0.1:6380>
D:\company\redis\redis6381>redis-cli -p 6381
127.0.0.1:6381> get msg
"hello world"
127.0.0.1:6381>

这样搭建主从复制算成功了。接下来我们详细讲解下集群。

2. 主从复制概述

2.1 定义

主从复制:就是一台redis服务器B从另一台redis服务器A复制数据。我们称服务器A为主服务器,B服务器为从服务器。其中,每台从服务器只能有一台主服务器,但是一台主服务器可以有多台从服务器。
数据的复制是单向的,只能由主服务器复制到从服务器。

2.2 作用

3. 如何使用主从复制

3.1 建立复制

建立复制有三种方式:

3.2 断开复制

通过slaveof<masterip><masterport>命令建立主从复制关系以后,可以通过slaveof no one断开。需要注意的是,从节点断开复制后,不会删除已有的数据,只是不再接受主节点新的数据变化。

4. 主从复制原理

主从复制为三个阶段:
连接建立阶段(即准备阶段)、数据同步阶段、命令传播阶段。

4.1 连接建立阶段

4.2 数据同步阶段

数据同步方式有全量复制和部分复制。

4.2.1 全量复制
  1. 全量复制需要执行bgsave,fork出子线程进行rdb持久化,消耗内存,IO。
  2. 复制完之后,从服务器需要删除旧的所有数据并载入RDB文件,这个过程是阻塞的,从服务器不能提供服务。
  3. 在复制未完成之前,master/slave因为网络问题断开连接,而这个时候,master是无法得知某个命令最终
    同步给了多少个slave数据库。但是redis提供了一个配置项来限制只有数据至少同步给多少个slave的时候,master才是可写的:
    min-slaves-to-write 3 表示只有当3个或以上的slave连接到master,master才是可写的
    min-slaves-max-lag 10 表示允许slave最长失去连接的时间,如果10秒还没收到slave的响应,则master认为该slave已断开。
4.2.2 部分复制

当slave与master断开连接,我们需要提供一种类似断开续传的功能,在断开连接之后的部分复制。
部分复制的实现,依赖于三个重要的概念:
复制偏移量
master在内存中创建一个backlog,master和slave都会保存一个复制偏移量offset,这个偏移量就是每次master如果发送N个字节数据,master的offset就会增加N,如果slave接收到这N个字节数据,并载入。则slave复制偏移量offset增加N。然后redis就通过master和slave的偏移量来判断主从服务器的状态一致性,如果不一致,就需要确定再次复制的位置(就是复制积压缓冲区)。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制,但是如果没有找到对应的offset,那么就会执行一次全量同步。

图片.png
比如我们前面搭建的一主两从的主从复制,这里如果主服务器的offset:900,两个从服务器A,B的分别为:offset:900,offset:900.此时主从服务器状态是一致的。
图片.png
现在主服务器发送100个字节数据,两个从服务器接收了,并载入。这时服务器状态是一致的。
图片.png
但是,现在主服务器发送100个字节数据,从服务器A断线没接收到,我们可以看到主从服务器的offset不一致了,那么在从服务器重启之后,这个数据如何恢复呢?就需要复制积压缓冲区。
复制积压缓冲区
复制积压缓冲区是由主服务器维护的固定长度的先进先出的队列,默认大小为1M。

在命令传播阶段,主节点除了将写命令发送给从节点,还会发送一份给复制积压缓冲区,作为写命令的备份;除了存储写命令,复制积压缓冲区中还存储了其中的每个字节对应的复制偏移量(offset) 。由于复制积压缓冲区定长且先进先出,所以它保存的是主节点最近执行的写命令;时间较早的写命令会被挤出缓冲区。

由于该缓冲区长度固定且有限,因此可以备份的写命令也有限,当主从节点offset的差距过大超过缓冲区长度时,将无法执行部分复制,只能执行全量复制。反过来说,为了提高网络中断时部分复制执行的概率,可以根据需要增大复制积压缓冲区的大小(通过配置repl-backlog-size)来设置;例如如果网络中断的平均时间是60s,而主节点平均每秒产生的写命令(特定协议格式)所占的字节数为100KB,则复制积压缓冲区的平均需求为6MB,保险起见,可以设置为12MB,来保证绝大多数断线情况都可以使用部分复制。

从节点将offset发送给主节点后,主节点根据offset和缓冲区大小决定能否执行部分复制:

4.3 命令传播

数据同步完成,就进入了命令传播阶段,主要是猪服务器将写命令发送给从服务器,从服务器更新数据,从而保证主从数据的一致性。

4.3.2 心跳机制

在命令传播阶段,除了发送写命令,主从节点还维持着心跳机制:PING和REPLCONF ACK。心跳机制对于主从复制的超时判断、数据安全等有作用。

6.1 主--从:PING

在命令传播阶段,主服务器定时发送PING命令到从服务器,为了让从节点进行超时判断。。PING发送的频率由repl-ping-slave-period参数控制,单位是秒,默认值是10s

6.1 从--主:REPLCONF ACK

在命令传播阶段,从节点会向主节点发送REPLCONF ACK命令,频率是每秒1次;命令格式为:REPLCONF ACK{offset},其中offset指从节点保存的复制偏移量。主要有以下三个作用:

上一篇 下一篇

猜你喜欢

热点阅读