Write by lyc at 2018-2-7
Modify by lyc at 2020-4-13 细化文档
参考博文:
Redis主从复制学习
Redis master-slave replication(配置Redis主从复制)

一、Redis主从复制原理

1.主从复制原理

Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下:

  • 从服务器连接主服务器,发送SYNC命令;
  • 主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
  • 主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
  • 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
  • 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
  • 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

2.Redis主从节能读写功能说明

  • 一个master可以有多个slave
  • 默认配置下,master节点可以进行读和写,slave节点只能进行读操作,写操作被禁止,即开启只读 slave-read-only yes
  • 不要修改配置让slave节点支持写操作,没有意义,原因是:
    • 原因1:在slave写入的数据不会被同步到其他节点;
    • 原因2:当master节点修改同一条数据后,slave节点的数据会被覆盖掉
  • slave节点挂了不影响其他slave节点的读和master节点的读和写,重新启动后会将数据从master节点同步过来
  • master节点挂了以后,不影响slave节点的读,Redis将不再提供写服务,master节点启动后Redis将重新对外提供写服务。

3.对有密码的情况说明一下,当master节点设置密码时:

  • 客户端访问master需要密码
  • 启动slave需要密码,在配置中进行配置即可
  • 客户端访问slave不需要密码

4.Master持久化功能关闭时主从复制的安全性

当有需要使用到主从复制机制时,一般都会强烈建议把master的持久化开关打开。即使为了避免持久化带来的延迟影响,不把持久化开关打开,那么也应该把master配置为不会自动启动的。

为了更好地理解当一个不进行持久化的master如果允许自动启动所带来的危险性。可以看看下面这种失败情形:

假设我们有一个redis节点A,设置为master,并且关闭持久化功能,另外两个节点B和C是它的slave,并从A复制数据。

如果A节点崩溃了导致所有的数据都丢失了,它会有重启系统来重启进程。但是由于持久化功能被关闭了,所以即使它重启了,它的数据集是空的。
而B和C依然会通过主从复制n机制从A复制数据,所以B和C会从A那里复制到一份空的数据集,并用这份空的数据集将自己本身的非空的数据集替换掉。于是就相当于丢失了所有的数据。

即使使用一些HA工具,比如说sentinel来监控master-slaves集群,也会发生上述的情形,因为master可能崩溃后迅速恢复。速度太快而导致sentinel无法察觉到一个failure的发生。

二、Redis主从搭建

1.slave 配置文件配置

1
2
3
4
5
6
$ vim 6379_redis.conf
slave-serve-stale-data yes
slave-read-only yes
slave-priority 100
slaveof <masterip> <masterport>
# masterauth <master-password>
  • slave-serve-stale-data yes 当从库同主机失去连接或者复制正在进行,从机库有两种运行方式:
    • slave-serve-stale-data yes (默认设置),从库会继续响应客户端的请求。
    • slave-serve-stale-data no 除去INFO和SLAVOF命令之外的任何请求都会返回一个错误”SYNC with master in progress”。
  • slave-read-only no 设置你的slave服务是否为只读,从库设置成yes,开启只读,命令行下可以通过 CONFIG SET 来动态修改配置
  • slave-priority 100 slave优先级,如果master不再正常工作了,哨兵将用它来选择一个slave提升为master。数字越小优先级越高,但是数字为0时这个slave永远不会提升为master
  • slaveof <masterip> <masterport> 设置当本机为slave服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
  • masterauth <master-password> 当master服务设置了密码保护时,slave服务连接master的密码。命令行下可以通过 config set masterauth <password> 来动态修改配置

2.命令行配置

  • redis > slaveof 192.168.99.207 6379
  • 或在redis-server启动命令后加上–slaveof 启动时生效。

3.断开主从

在redis命令行里执行 slaveof no one 可以让一个从库变成主库。

1
2
# redis命令行在从库断开主从
redis > slaveof no one

三、总结:相关的参数,注释掉的参数都是使用默认值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
################################# REPLICATION #################################
##复制选项,slave复制对应的master。
# slaveof <masterip> <masterport>

##如果master设置了requirepass,那么slave要连上master,需要有master的密码才行。
##masterauth就是用来配置master的密码,这样可以在连上master后进行认证。
# masterauth <master-password>

##当从库同主机失去连接或者复制正在进行,从机库有两种运行方式:
## 1) 如果slave-serve-stale-data设置为yes(默认设置),从库会继续响应客户端的请求。
## 2) 如果slave-serve-stale-data设置为no,除去INFO和SLAVOF命令之外的任何请求都会返回一个错误”SYNC with master in progress”。
slave-serve-stale-data yes

#作为从服务器,默认情况下是只读的(yes),可以修改成NO,用于写(不建议)。
slave-read-only yes

##是否使用socket方式复制数据。
##目前redis复制提供两种方式,disk和socket。如果新的slave连上来或者重连的slave无法部分同步,就会执行全量同步,master会生成rdb文件。
##有2种方式:disk方式是master创建一个新的进程把rdb文件保存到磁盘,再把磁盘上的rdb文件传递给slave。socket是master创建一个新的进程,直接把rdb文件以socket的方式发给slave。disk方式的时候,当一个rdb保存的过程中,多个slave都能共享这个rdb文件。socket的方式就的一个个slave顺序复制。在磁盘速度缓慢,网速快的情况下推荐用socket方式。
repl-diskless-sync no

##diskless复制的延迟时间,防止设置为0。
##一旦复制开始,节点不会再接收新slave的复制请求直到下一个rdb传输。所以最好等待一段时间,等更多的slave连上来。
repl-diskless-sync-delay 5

##slave根据指定的时间间隔向服务器发送ping请求。
##时间间隔可以通过 repl_ping_slave_period 来设置,默认10秒。
# repl-ping-slave-period 10

##复制连接超时时间。
##master和slave都有超时时间的设置。
##master检测到slave上次发送的时间超过repl-timeout,即认为slave离线,清除该slave信息。slave检测到上次和master交互的时间超过repl-timeout,则认为master离线。
##需要注意的是repl-timeout需要设置一个比repl-ping-slave-period更大的值,不然会经常检测到超时。
# repl-timeout 60

##是否禁止复制tcp链接的tcp nodelay参数,可传递yes或者no。默认是no,即使用tcp nodelay。
##如果master设置了yes来禁止tcp nodelay设置,在把数据复制给slave的时候,会减少包的数量和更小的网络带宽。但是这也可能带来数据的延迟。
##默认我们推荐更小的延迟,但是在数据量传输很大的场景下,建议选择yes。
repl-disable-tcp-nodelay no

##复制缓冲区大小,这是一个环形复制缓冲区,用来保存最新复制的命令。
##这样在slave离线的时候,不需要完全复制master的数据,如果可以执行部分同步,只需要把缓冲区的部分数据复制给slave,就能恢复正常复制状态。缓冲区的大小越大,slave离线的时间可以更长,复制缓冲区只有在有slave连接的时候才分配内存。没有slave的一段时间,内存会被释放出来,默认1m。
# repl-backlog-size 5mb

##master没有slave一段时间会释放复制缓冲区的内存,repl-backlog-ttl用来设置该时间长度。单位为秒。
# repl-backlog-ttl 3600

##当master不可用,Sentinel会根据slave的优先级选举一个master。最低的优先级的slave,当选master。而配置成0,永远不会被选举。
slave-priority 100

##redis提供了可以让master停止写入的方式,如果配置了min-slaves-to-write,健康的slave的个数小于N,mater就禁止写入。master最少得有多少个健康的slave存活才能执行写命令。
##这个配置虽然不能保证N个slave都一定能接收到master的写操作,但是能避免没有足够健康的slave的时候,master不能写入来避免数据丢失。设置为0是关闭该功能。
# min-slaves-to-write 3

#延迟小于min-slaves-max-lag秒的slave才认为是健康的slave。
# min-slaves-max-lag 10