Redis主从复制

Redis集群教程 官方文档
Redis集群规范官方文档
关于主从复制的redis.conf配置,详情见上面配置文件8)、REPLICATION

单机多节点方式

本地tar.gz搭建单机多节点方式。但我使用的是下面的docker方式

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
[root@localhost redis]# cp redis.conf redis79.conf
[root@localhost redis]# cp redis.conf redis80.conf
[root@localhost redis]# cp redis.conf redis81.conf
[root@localhost redis]#
[root@localhost redis]# ls
redis79.conf redis80.conf redis81.conf redis.conf

# 79配置文件修改
port 6379 # 端口号
pidfile /var/run/redis_6379.pid # pid进程文件
logfile "6379.log" # 日志文件
dbfilename dump_6379.rdb # rdb文件名称

# 80配置文件修改
port 6380
pidfile /var/run/redis_6380.pid
logfile "6380.log"
dbfilename dump_6380.rdb

# 81配置文件修改
port 6381
pidfile /var/run/redis_6381.pid
logfile "6381.log"
dbfilename dump_6381.rdb

# 启动
redis-server redis79.conf
redis-server redis80.conf
redis-server redis81.conf

Docker容器方式

关于配置文件,可查看手写配置文件模式

初始化

提前给出for循环代码

1
2
3
4
5
6
7
8
9
for n in $(seq 79 81); \
do \

docker run --name redis${n} -p 63${n}:6379 \
-v /app/docker/redis/redis.conf:/usr/local/etc/redis/redis.conf \
--net redis --ip 172.22.0.${n} -d redis \
redis-server /usr/local/etc/redis/redis.conf

done
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
57
# 1. 创建Docker自定义网络
[root@localhost ~]# docker network create redis --subnet 172.22.0.0/16 --gateway 172.22.0.1
7fcd7743a831171236b7fabb468bfea0ac538ff4a7c13fa74d02043027ebab36
# 2. 查看网络列表
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
cdd8f5efd833 bridge bridge local
c7b56eb97499 example_default bridge local
b0e468be22b6 host host local
09be5ec40300 my_net bridge local
37f49d03f5d5 none null local
7fcd7743a831 redis bridge local # 我们创建的网络,名称:redis
# 3. 查看网络详情
[root@localhost ~]# docker network inspect redis
[
{
"Name": "redis",
"Id": "7fcd7743a831171236b7fabb468bfea0ac538ff4a7c13fa74d02043027ebab36",
"Created": "2020-06-11T17:55:13.633443866-07:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.22.0.0/16",
"Gateway": "172.22.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
# 循环启动三个容器79,80,81
[root@localhost ~]# for n in $(seq 79 81); \
> do \
>
> docker run --name redis${n} -p 63${n}:6379 \
> -v /app/docker/redis/redis.conf:/usr/local/etc/redis/redis.conf \
> --net redis --ip 172.22.0.${n} -d redis \
> redis-server /usr/local/etc/redis/redis.conf
>
> done
7ce73d6edca0b6131d3fe492b582fb5cd2733b6ffc390965ef609c2020cf5102
63adb81f11be2611439092fddf2297626df45cdac487a17ce2feecf3f26d0544
c9572636b786a04227a4f326fa83fc4003a06cb0dfd14d492fd5c2b040eaac59
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c9572636b786 redis "docker-entrypoint..." 8 seconds ago Up 7 seconds 0.0.0.0:6381->6379/tcp redis81
63adb81f11be redis "docker-entrypoint..." 9 seconds ago Up 8 seconds 0.0.0.0:6380->6379/tcp redis80
7ce73d6edca0 redis "docker-entrypoint..." 9 seconds ago Up 9 seconds 0.0.0.0:6379->6379/tcp redis79

主机变从机

(1)启动三个Server 79、80、81。启动后默认都是 master,并且下面都没有从机。
(2)此时,把80,81执行命令SLAVEOF 172.22.0.79 6379 # 当79的从机
(3)此时,79仍为 master,但下面跟了两个从机 80、81。注意:此时的 80、81也变成了从机 slave。

在这里插入图片描述
1)、先进入79容器,查看信息

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost ~]# docker exec -it redis79 redis-cli
127.0.0.1:6379> INFO replication # 查看副本信息
# Replication
role:master # 主机
connected_slaves:0 # 没有从机
master_replid:c2fbb2437987a253f1b202fdeeee133363442668
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

2)、接下来,我们再开启一个xshell会话标签,连接80,把80默认的主机设置为从机

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
[root@localhost ~]# docker exec -it redis80 redis-cli
127.0.0.1:6379> INFO replication # 查看副本信息
# Replication
role:master # 主机
connected_slaves:0 # 没有从机
master_replid:1465d4699fdfa472186b10c0f756a670c271ba7e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379> SLAVEOF 172.22.0.79 6379 # 当79的从机
OK
127.0.0.1:6379> INFO replication # 查看副本信息
# Replication
role:slave # 由主机变为了从机
master_host:172.22.0.79 # 主机IP
master_port:6379 # 主机端口
master_link_status:up # 主从连接状态正常
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:14
slave_priority:100 # 权重,用于主机挂了进行竞选主机,权重低的成为主机。注意:是低的被选中
slave_read_only:1 # 从机只读,不能进行写操作
connected_slaves:0 # 没有从机
master_replid:a27886dd61a798fd50d1396b063cfe310be9be24
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14
127.0.0.1:6379>

3)、此时,我们再对79进行查看,发现,多个一个从机80

1
2
3
4
5
6
7
8
9
10
11
12
13
14
127.0.0.1:6379> INFO replication # 查看副本信息
# Replication
role:master # 主机
connected_slaves:1 # 此时从机由0变为了1
slave0:ip=172.22.0.80,port=6379,state=online,offset=112,lag=1 # 从机信息
master_replid:a27886dd61a798fd50d1396b063cfe310be9be24
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:112
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:112
127.0.0.1:6379>

4)、同理,我们再新建一个xshell会话框,对81进行设置为从机

1
2
3
4
[root@localhost ~]# docker exec -it redis81 redis-cli
127.0.0.1:6379> SLAVEOF 172.22.0.79 6379 # 当79的从机
OK
127.0.0.1:6379>

5)、此时,我们看到79下面,有了两个从机80 和 81

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
127.0.0.1:6379> INFO replication # 查看副本信息
# Replication
role:master # 主机
connected_slaves:2 # 2台从机
slave0:ip=172.22.0.80,port=6379,state=online,offset=210,lag=1 # 从机80
slave1:ip=172.22.0.81,port=6379,state=online,offset=210,lag=1 # 从机81
master_replid:a27886dd61a798fd50d1396b063cfe310be9be24
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:210
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:210
127.0.0.1:6379>

主写从读

还是这张图,此时,只能 79 进行 set。而 80、81只能查。所以称之为:主写从读

在这里插入图片描述

1)、我们查看79, 80, 81 里面所有的key,发现都是空

1
2
3
4
5
6
7
8
9
10
11
# 79
127.0.0.1:6379> KEYS *
(empty array)

# 80
127.0.0.1:6379> KEYS *
(empty array)

# 81
127.0.0.1:6379> KEYS *
(empty array)

2)、我们对79进行set一个key,发现80, 81也能查到

1
2
3
4
5
6
7
8
9
10
11
12
13
# 79
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> KEYS *
1) "k1"

# 80
127.0.0.1:6379> KEYS *
1) "k1"

# 81
127.0.0.1:6379> KEYS *
1) "k1"

3)、我们对80 ,81从机分别进行set一个key,发现,不能设置。
结论:只有主机可写,从机只能读。

1
2
3
4
5
6
7
# 80
127.0.0.1:6379> set k2 v2
(error) READONLY You can't write against a read only replica.

# 81
127.0.0.1:6379> set k2 v2
(error) READONLY You can't write against a read only replica.

主机挂了

主机 79 挂了,查看从机 80,81 状态,发现80、81仍然是从机,因为没有配置哨兵,所以还连接到79主机。
主机 79 回来了,并对 79 set一个key,再查看从机80、81状态,发现仍可以正常获取结果(主机恢复还会继续同步)

1)、主机 79 挂了,查看从机 80,81 状态,发现80, 81仍然是从机,因为没有配置哨兵,所以还连接到79主机。

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
# 79
127.0.0.1:6379> SHUTDOWN
[root@localhost ~]#

# 80
127.0.0.1:6379> INFO replication # 查看副本信息
# Replication
role:slave # 仍然是从机,因为没有配置哨兵
master_host:172.22.0.79
master_port:6379
master_link_status:down # 与主机断开连接
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:4126
master_link_down_since_seconds:8
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:a27886dd61a798fd50d1396b063cfe310be9be24
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:4126
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:4126

# 81
127.0.0.1:6379> INFO replication # 查看副本信息
# Replication
role:slave # 仍然是从机,因为没有配置哨兵
master_host:172.22.0.79
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:290
master_link_down_since_seconds:6
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:381d951aa7a04b49318565dd6d26b644f9f649f7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:290
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:290

2)、主机 79 回来了,并对 79 set一个key,再查看从机80, 81状态,发现仍可以正常获取结果

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
# 79
[root@localhost ~]# docker start redis79
redis79
[root@localhost ~]# docker exec -it redis79 redis-cli
127.0.0.1:6379> set k2 v2
OK

# 80
127.0.0.1:6379> INFO replication # 查看副本信息
# Replication
role:slave
master_host:172.22.0.79
master_port:6379
master_link_status:up # 主从连接状态恢复
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:66
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:381d951aa7a04b49318565dd6d26b644f9f649f7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:66
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:53
repl_backlog_histlen:14
127.0.0.1:6379> KEYS * # 正常获取结果
1) "k2"
2) "k1"

# 81
127.0.0.1:6379> INFO replication # 查看副本信息
# Replication
role:slave
master_host:172.22.0.79
master_port:6379
master_link_status:up # 主从连接状态恢复
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:52
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:ac963a6e46078744b3d4ee714155a312778b9a8b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:52
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:52
127.0.0.1:6379> KEYS * # 正常获取结果
1) "k2"
2) "k1"

从机挂了

80从机挂了,79 set一个key,再启动 80。
情况1、80配置文件中指定了当 79从机,那么会以 slave方式启动,启动后会进行全量复制,则可以查看到数据。
情况2、80配置文件中未指定当 79从机,那么会以 master方式启动,启动后不进行任何复制。会选择加载自己的 RDB,或 AOF,所以此时查看不到数据。
若此时执行了命令 SLAVEOF 172.22.0.79 6379 # 当79的从机,那么也会进行全量复制,则可以查看到数据。

1)、从机80挂了

1
2
3
# 80
127.0.0.1:6379> SHUTDOWN
[root@localhost ~]#

2)、此时,对79主机,set一个key,

1
2
3
4
5
6
7
# 79
127.0.0.1:6379> set k3 v3
OK
127.0.0.1:6379> KEYS *
1) "k3"
2) "k2"
3) "k1"

3)、再次启动80,还能继续拿到刚才的key吗?答:不能
如果从机进行命令行配置的话,是不进行持久化的,重启server端,默认启动变成主机

如果在里面配置文件配置好主人的话,启动服务端后,默认就是从,进行全量复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@localhost ~]# docker start redis80
redis80
[root@localhost ~]# docker exec -it redis80 redis-cli
127.0.0.1:6379> KEYS *
1) "k1"
2) "k2"
127.0.0.1:6379> INFO replication # 查看副本信息
# Replication
role:master
connected_slaves:0
master_replid:21803fbeb5f9047356e7f8bcdad2b88267163df0
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379>

4)、再把80变为79下的从机,发现79下的数据,全部被同步过来了【全量复制】

1
2
3
4
5
6
7
127.0.0.1:6379> SLAVEOF 172.22.0.79 6379 # 当79的从机
OK
127.0.0.1:6379> KEYS *
1) "k1"
2) "k3" # 发现k3同步过来
3) "k2"
127.0.0.1:6379>

增/全量复制

slave第一次连接master时,会给master发送一个sync同步命令。(第一次建立连接也就是执行slaveof命令,或写入配置文件,第一次启动server端时)
master接收到命令之后,master启动后台的存盘进程,同时收集所有接收到用于修改数据的命令,在后台执行完毕之后,
master将传送整个数据文件给slave,并完成一次数据的同步。
全量复制:而slave接收到数据文件之后,将其存盘并加载到内存中。
增量复制:master继续将新的所有收集到的所有修改数据的命令依次传给slave,完成同步。
只要重新连接master,就会自动进行一次完全同步(全量复制)。

1)、全量复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 80
[root@localhost ~]# docker exec -it redis80 redis-cli
127.0.0.1:6379> INFO replication
# Replication
role:master # 主机
connected_slaves:0
master_replid:21803fbeb5f9047356e7f8bcdad2b88267163df0
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379> SLAVEOF 172.22.0.79 6379 # 把80变为从机,认79当主机。第一次建立连接,进行全量复制
OK
127.0.0.1:6379> KEYS *
1) "k1"
2) "k3"
3) "k2"

2)、增量复制

1
2
3
4
5
6
7
8
9
10
# 79
127.0.0.1:6379> set k4 v4 # 这时候,80从机会进行增量复制
OK

# 80
127.0.0.1:6379> KEYS *
1) "k1"
2) "k3"
3) "k2"
4) "k4"

多层链路

我们让 80当79从机,81当80从机。
此时
79:主,下面有个从 80
80:从,下面有个从 81
81:主,下面无从

在这里插入图片描述

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
57
58
59
60
61
62
63
64

# 81
127.0.0.1:6379> SLAVEOF 172.22.0.80 6379 # 当80的从机
OK
127.0.0.1:6379> INFO replication
# Replication
role:slave # 从机
master_host:172.22.0.80 # 主机是80
master_port:6379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:2233
slave_priority:100
slave_read_only:1 # 只读
connected_slaves:0 # 无从机
master_replid:ac963a6e46078744b3d4ee714155a312778b9a8b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2233
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2233

# 80
127.0.0.1:6379> SLAVEOF 172.22.0.79 6379 # 当79的从机
OK
127.0.0.1:6379> INFO replication
# Replication
role:slave # 从机
master_host:172.22.0.79 # 主机是79
master_port:6379
master_link_status:up
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_repl_offset:2247
slave_priority:100
slave_read_only:1 # 还是只读
connected_slaves:1 # 自己做为从机,底下连接还有一个从机
slave0:ip=172.22.0.81,port=6379,state=online,offset=2247,lag=1 # 从机81
master_replid:ac963a6e46078744b3d4ee714155a312778b9a8b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2247
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:894
repl_backlog_histlen:1354

# 79
127.0.0.1:6379> INFO replication
# Replication
role:master # 主机
connected_slaves:1 # 有一个从机
slave0:ip=172.22.0.80,port=6379,state=online,offset=2261,lag=1 # 从机80
master_replid:ac963a6e46078744b3d4ee714155a312778b9a8b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2261
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2261

手动从变主

81 主机挂了,80从机执行 SLAVEOF no one # 自己由从机变为主机,可以切换角色为 master。此时,可读可写,但不会进行任何增/全量复制。
即使 81主机再次启动,80从机相当于互不影响的隔离状态。
因为81主机默认master启动,底下也不会有从机。因为我们是手动进行配置的主从关系,如果想持久化,可以写入配置文件

1)、主机81挂了,从机80自己手动变为主机

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
# 80
127.0.0.1:6379> SHUTDOWN
[root@localhost ~]#


# 81
127.0.0.1:6379> INFO replication
# Replication
role:slave # 从机
master_host:172.22.0.80
master_port:6379
master_link_status:down # 主机挂了
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:4095
master_link_down_since_seconds:8
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:ac963a6e46078744b3d4ee714155a312778b9a8b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:4095
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:4095
127.0.0.1:6379> SLAVEOF no one # 自己由从机变为主机
OK
127.0.0.1:6379> INFO replication
# Replication
role:master # 变为主机
connected_slaves:0
master_replid:0374649c368975a158a2dfbc3dea53848196f3fb
master_replid2:ac963a6e46078744b3d4ee714155a312778b9a8b
master_repl_offset:4095
second_repl_offset:4096
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:4095

2)、主机80回来了,底下也不会有从机。因为我们是手动进行配置的主从关系,如果想持久化,可以写入配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@localhost ~]# docker start redis80
redis80
[root@localhost ~]# docker exec -it redis80 redis-cli
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:0
master_replid:676180674e192164ff4dfcdb807014b833a71799
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379>

手写配置文件模式

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
# 创建网络
docker network create redis --subnet 172.22.0.0/16 --gateway 172.22.0.1

# 创建目录,进入
mkdir -p /app/docker/redis/
cd /app/docker/redis/

# 下载redis.conf配置文件
wget http://download.redis.io/redis-stable/redis.conf

# 修改绑定所有IP
sed -i 's/bind 127.0.0.1/bind 0.0.0.0/g' redis.conf

# copy出来三份79, 80 ,81
cp redis.conf redis79.conf
cp redis.conf redis80.conf
cp redis.conf redis81.conf

# 把80, 81认79当主机
sed -i 's/# replicaof <masterip> <masterport>/replicaof 172.22.0.79 6379/g' redis80.conf
sed -i 's/# replicaof <masterip> <masterport>/replicaof 172.22.0.79 6379/g' redis81.conf


# 循环启动三个容器
for n in $(seq 79 81); \
do \

docker run --name redis${n} -p 63${n}:6379 \
-v /app/docker/redis/redis${n}.conf:/usr/local/etc/redis/redis.conf \
--net redis --ip 172.22.0.${n} -d redis \
redis-server /usr/local/etc/redis/redis.conf

done


# 进入容器
docker exec -it redis79 redis-cli
docker exec -it redis80 redis-cli
docker exec -it redis81 redis-cli

# 查看副本信息
INFO replication

# 关闭server端,这时候会停止docker容器
SHUTDOWN

# 容器停止的容器redis79
docker start redis79

# 测试完之后删除容器79,80,81
docker rm -f redis79 redis80 redis81

# ?匹配一个字符 *匹配0个或多个字符
# 也就是出了redis.conf文件之外,其他都强制移动到/tmp下,如果/tmp中存在,就覆盖
mv -f /app/docker/redis/redis?*.conf /tmp/

未写出演示过程,再这里写一下演示总结。

1)、for循环启动容器之后,79是主, 80 ,81是从。79(可写可读),80(只读), 81(只读)

2)、SHUTDOWN关闭79容器之后,80 , 81 依旧只读。检测到79主机挂了:master_link_status:down

3)、再次启动79主机,很快,80,81检测到79主机存活:master_link_status:up

4)、如果SHUTDOWN把80或81关闭,此时给79设置set一个key,再次启动80, 81仍是79的从机,并启动时全量同步数据。