15.Redis的复制(Master/Slave)

 

Redis的复制(Master/Slave)

1,什么是复制

Redis 的读并发量太大怎么办?

单机版的Redis 挂掉怎么办?

需要写并发又要安全,在redis 3.0 后,官方发布了集群方案

1.1,官网说明

官网说明: https://redis.io/topics/replication

在Redis复制的基础上(不包括Redis Cluster或Redis Sentinel作为附加层提供的高可用性功能),使用和配置领导者跟随者(主从)复制非常简单:它允许副本Redis实例精确主实例的副本。每当链接断开时,该副本将自动重新连接到主数据库,并且无论该主数据库发生什么情况,它都将尝试作为该副本的精确副本。

该系统使用三种主要机制工作:

  1. 当主节点和副本实例连接良好时,主节点通过向副本发送命令流来使副本保持更新,以便复制由于以下原因而对主节点上发生的数据集产生的影响:客户端写入,密钥已过期或驱逐任何其他更改主数据集的操作。
  2. 当主服务器和副本服务器之间的链接断开时,由于网络问题或由于在主服务器或副本服务器中检测到超时,副本服务器将重新连接并尝试进行部分重新同步:这意味着它将尝试仅获取该部件断开期间错过的命令流的大小。
  3. 如果无法进行部分重新同步,则副本将要求完全重新同步。这将涉及一个更复杂的过程,在该过程中,主服务器需要创建其所有数据的快照,将其发送到副本,然后在数据集更改时继续发送命令流。

默认情况下,Redis使用异步复制(低延迟和高性能)是绝大多数Redis用例的自然复制模式。但是,Redis副本异步地确认它们与主服务器定期接收的数据量。因此,主服务器不会每次都等待副本处理命令,但是,如果需要,它知道哪个副本已经处理了什么命令。这允许具有可选的同步复制。

1.2,行话

行话:也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slave机制,Master以写为主,Slave以读为主

2,有什么作用

  • 读写分离

  • 容灾恢复

3,怎么使用

  1. SLAVEOF <masterip> <masterport>配置命令
  2. 修改redis.conf配置文件中的replicaof <masterip> <masterport>配置项

3.1,配从不配主

3.2,配置命令  【SLAVEOF 主库IP 主库端口】

每次与master断开之后,都需要重新连接,除非你配置进redis.conf文件

Info replication可以查看

3.3,详细操作

  1. 拷贝多个redis.conf文件
  2. 开启daemonize yes
  3. Pid文件名字
  4. 指定端口
  5. Log文件名字
  6. Dump.rdb名字

3.4,一主二仆

演示问题:

  1. 切入点问题?slave1、slave2是从头开始复制还是从切入点开始复制?比如从k4进来,那之前的123是否也可以复制
  2. 从机是否可以写?set可否?
  3. 主机shutdown后情况如何?从机是上位还是原地待命
  4. 主机又回来了后,主机新增记录,从机还能否顺利复制?
  5. 其中一台从机down后情况如何?依照原有它能跟上大部队吗?

3.5,薪火相传

上一个Slave可以是下一个slave的Master,Slave同样可以接收其他 slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力

中途变更转向:会清除之前的数据,重新建立拷贝最新的

Slaveof 新主库IP 新主库端口

3.6,反客为主

1
SLAVEOF no one

使当前数据库停止与其他数据库的同步,转成主数据库

4,复制的原理

Slave启动成功连接到master后会发送一个sync命令

Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步

  1. 全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
  2. 增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步

但是只要是重新连接master,一次完全同步(全量复制)将被自动执行

Demo1

创建1个master,4个slave,2个slave通过配置命令创建,2个slave通过conf文件创建

master: 6379

slave-1: 6380,SLAVEOF <masterip> <masterport>配置命令

slave-2: 6381,SLAVEOF <masterip> <masterport>配置命令

slave-3: 6382,replicaof <masterip> <masterport>配置项

slave-4: 6383,replicaof <masterip> <masterport>配置项

master:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@localhost my_redis_6379]# /usr/local/redis-6.0.9/bin/redis-server my_redis_conf_6379.conf
[root@localhost my_redis_6379]# /usr/local/redis-6.0.9/bin/redis-cli

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6382,state=online,offset=392,lag=0
slave1:ip=127.0.0.1,port=6380,state=online,offset=392,lag=0
master_replid:aa532b76f66520a97f249f82ec316d5b4fb4a93c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:392
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:392
127.0.0.1:6379>

slave-1: 通过SLAVEOF <masterip> <masterport>配置命令创建

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
[root@localhost my_redis_6380]# /usr/local/redis-6.0.9/bin/redis-server my_redis_conf_6380.conf

[root@localhost my_redis_6380]# /usr/local/redis-6.0.9/bin/redis-cli -h 127.0.0.1 -p 6380

127.0.0.1:6380>
127.0.0.1:6380> INFO replication
# Replication
role:master
connected_slaves:0
master_replid:eca3c70215c1e8d02464d7168a00d1da1068b26e
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:6380> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6380> INFO replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:378
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:aa532b76f66520a97f249f82ec316d5b4fb4a93c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:378
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:379
repl_backlog_histlen:0
127.0.0.1:6380>

slave-3: 通过修改redis.conf配置文件中的replicaof <masterip> <masterport>配置项创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
################################# REPLICATION #################################

# Master-Replica replication. Use replicaof to make a Redis instance a copy of
# another Redis server. A few things to understand ASAP about Redis replication.
#
# +------------------+ +---------------+
# | Master | ---> | Replica |
# | (receive writes) | | (exact copy) |
# +------------------+ +---------------+
#
# 1) Redis replication is asynchronous, but you can configure a master to
# stop accepting writes if it appears to be not connected with at least
# a given number of replicas.
# 2) Redis replicas are able to perform a partial resynchronization with the
# master if the replication link is lost for a relatively small amount of
# time. You may want to configure the replication backlog size (see the next
# sections of this file) with a sensible value depending on your needs.
# 3) Replication is automatic and does not need user intervention. After a
# network partition replicas automatically try to reconnect to masters
# and resynchronize with them.
#
# replicaof <masterip> <masterport>
replicaof 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
[root@localhost my_redis_6382]# /usr/local/redis-6.0.9/bin/redis-cli -p 6382
127.0.0.1:6382>
127.0.0.1:6382> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_repl_offset:1274
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:aa532b76f66520a97f249f82ec316d5b4fb4a93c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1274
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1274
127.0.0.1:6382>
  1. 切入点问题?slave1、slave2是从头开始复制还是从切入点开始复制?比如从k4进来,那之前的123是否也可以复制

master:

1
2
127.0.0.1:6379> set k1 v1
OK

slave-2:

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
[root@localhost my_redis_6381]# /usr/local/redis-6.0.9/bin/redis-server my_redis_conf_6381.conf

[root@localhost my_redis_6381]# /usr/local/redis-6.0.9/bin/redis-cli -p 6381

127.0.0.1:6381>
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:0
master_replid:3f400816a7cb785b4bcf782f58af51e5ff9dd599
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:6381>
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6381>
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:1806
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:aa532b76f66520a97f249f82ec316d5b4fb4a93c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1806
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1807
repl_backlog_histlen:0
127.0.0.1:6381>
127.0.0.1:6381> get k1
"v1"
127.0.0.1:6381>

master:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:3
slave0:ip=127.0.0.1,port=6382,state=online,offset=2390,lag=1
slave1:ip=127.0.0.1,port=6380,state=online,offset=2390,lag=0
slave2:ip=127.0.0.1,port=6381,state=online,offset=2390,lag=0
master_replid:aa532b76f66520a97f249f82ec316d5b4fb4a93c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2390
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2390
127.0.0.1:6379> set k2 v2
OK

slave-2:

1
2
127.0.0.1:6381> get k2
"v2"

从机会从头开始复制,获取master的全部数据。

  1. 从机是否可以写?set可否?

master:

1
2
127.0.0.1:6379> get k2
"v2"

master可读可写

slave-2:

1
2
127.0.0.1:6381> set k3 v3
(error) READONLY You can't write against a read only replica.

从机不可写,只能读

  1. 主机shutdown后情况如何?从机是上位还是原地待命

master:

1
2
127.0.0.1:6379> SHUTDOWN
not connected> quit

slave-1, slave-2, slave-3:

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
127.0.0.1:6380/6381/6382> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:2656
master_link_down_since_seconds:93
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:aa532b76f66520a97f249f82ec316d5b4fb4a93c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2656
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2656
127.0.0.1:6380/6381/6382> set k3 v3
(error) READONLY You can't write against a read only replica.
127.0.0.1:6380/6381/6382> get k1
"v1"

主机shutdown后,从机状态保持不变,不会自动选举出新的master,也依旧不能写入数据,但是可以读数据。

  1. 主机又回来了后,主机新增记录,从机还能否顺利复制?

(1) master直接恢复:一切都恢复到之前的样子
master:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@localhost my_redis_6379]# /usr/local/redis-6.0.9/bin/redis-server my_redis_conf_6379.conf
[root@localhost my_redis_6379]# /usr/local/redis-6.0.9/bin/redis-cli
127.0.0.1:6379> keys *
1) "k1"
2) "k2"
127.0.0.1:6379> set k3 v3
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:3
slave0:ip=127.0.0.1,port=6380,state=online,offset=108,lag=1
slave1:ip=127.0.0.1,port=6382,state=online,offset=108,lag=1
slave2:ip=127.0.0.1,port=6381,state=online,offset=108,lag=1
master_replid:24b1b1610140212ba044a316b76f53d67d515009
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:108
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:108

slave-1, slave-2, slave-3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
127.0.0.1:6380/6381/6382> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:234
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:24b1b1610140212ba044a316b76f53d67d515009
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:234
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:234
127.0.0.1:6380/6381/6382> get k3
"v3"

(2) slave 变成master之后,原master

master:6379 shutdown之后,slave-2:6381 使用SLAVEOF no one命令手动变成新的master后,其他slave需要手动连接到新master slave-2:6381上

slave-2:6381

1
2
3
4
5
6
7
8
9
10
11
12
13
14
127.0.0.1:6381> SLAVEOF no one
OK
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:0
master_replid:1c971da5e052faebcbf05721d5c0d59e6a14f94a
master_replid2:24b1b1610140212ba044a316b76f53d67d515009
master_repl_offset:486
second_repl_offset:487
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:486

slave-1, slave-3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
127.0.0.1:6380/6382> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:486
master_link_down_since_seconds:526
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:24b1b1610140212ba044a316b76f53d67d515009
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:486
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:486
  1. 其中一台从机down后情况如何?依照原有它能跟上大部队吗?

master:

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:3
slave0:ip=127.0.0.1,port=6382,state=online,offset=0,lag=1
slave1:ip=127.0.0.1,port=6380,state=online,offset=0,lag=1
slave2:ip=127.0.0.1,port=6381,state=online,offset=0,lag=0
master_replid:cb94b9c2350916f815229ef83734adbb6824648d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:0

slave-3:

1
2
127.0.0.1:6382> SHUTDOWN
not connected> quit

master:

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
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=42,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=42,lag=1
master_replid:cb94b9c2350916f815229ef83734adbb6824648d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:42
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:42
127.0.0.1:6379> keys *
1) "k2"
2) "k3"
3) "k1"
127.0.0.1:6379> MSET k4 v4 k5 v5
OK
127.0.0.1:6379>
127.0.0.1:6379> keys *
1) "k2"
2) "k4"
3) "k3"
4) "k1"
5) "k5"
127.0.0.1:6379>

slave-3:

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost my_redis_6382]# /usr/local/redis-6.0.9/bin/redis-server my_redis_conf_6382.conf
[root@localhost my_redis_6382]# /usr/local/redis-6.0.9/bin/redis-cli -p 6382
127.0.0.1:6382>
127.0.0.1:6382> keys *
1) "k4"
2) "k2"
3) "k3"
4) "k5"
5) "k1"
127.0.0.1:6382> get k5
"v5"
127.0.0.1:6382>

其中一台从机down后,重新连接到master之后,能重新获取全部数据。

  1. slave指向其他slave

新建slave-4: 6383指向slave-3:6382

slave-4: 6383

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
################################# REPLICATION #################################

# Master-Replica replication. Use replicaof to make a Redis instance a copy of
# another Redis server. A few things to understand ASAP about Redis replication.
#
# +------------------+ +---------------+
# | Master | ---> | Replica |
# | (receive writes) | | (exact copy) |
# +------------------+ +---------------+
#
# 1) Redis replication is asynchronous, but you can configure a master to
# stop accepting writes if it appears to be not connected with at least
# a given number of replicas.
# 2) Redis replicas are able to perform a partial resynchronization with the
# master if the replication link is lost for a relatively small amount of
# time. You may want to configure the replication backlog size (see the next
# sections of this file) with a sensible value depending on your needs.
# 3) Replication is automatic and does not need user intervention. After a
# network partition replicas automatically try to reconnect to masters
# and resynchronize with them.
#
# replicaof <masterip> <masterport>
replicaof 127.0.0.1 6382

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
[root@localhost my_redis_6383]# /usr/local/redis-6.0.9/bin/redis-server my_redis_conf_6383.conf
[root@localhost my_redis_6383]# /usr/local/redis-6.0.9/bin/redis-cli -p 6383
127.0.0.1:6383>
127.0.0.1:6383> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6382
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:853
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:cb94b9c2350916f815229ef83734adbb6824648d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:853
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:840
repl_backlog_histlen:14
127.0.0.1:6383>
127.0.0.1:6383> keys *
1) "k3"
2) "k1"
3) "k5"
4) "k2"
5) "k4"
127.0.0.1:6383>

slave-3: 6382

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
127.0.0.1:6382> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:867
slave_priority:100
slave_read_only:1
connected_slaves:1
slave0:ip=127.0.0.1,port=6383,state=online,offset=867,lag=0
master_replid:cb94b9c2350916f815229ef83734adbb6824648d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:867
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:29
repl_backlog_histlen:839
127.0.0.1:6382>
127.0.0.1:6382> keys *
1) "k4"
2) "k2"
3) "k3"
4) "k5"
5) "k1"
127.0.0.1:6382>
127.0.0.1:6382> set k6 v6
(error) READONLY You can't write against a read only replica.
127.0.0.1:6382>

被指向为master的slave仍然不能写入数据

master:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:3
slave0:ip=127.0.0.1,port=6380,state=online,offset=1091,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=1091,lag=0
slave2:ip=127.0.0.1,port=6382,state=online,offset=1091,lag=1
master_replid:cb94b9c2350916f815229ef83734adbb6824648d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1091
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1091
127.0.0.1:6379> set k6 v6
OK

slave-4:

1
2
127.0.0.1:6383> get k6
"v6"

5,哨兵模式

5.1,什么是哨兵模式

反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库

5.2,怎么玩(使用步骤)

结构:

1
2
3
4
5
6
7
master: 6379

slave-1: 6380
slave-2: 6381
slave-3: 6382

slave-4: 6383 --> slave3: 6382

(1) 自定义的my_redis_sentinel目录下新建sentinel.conf文件,名字绝不能错

1
2
[root@localhost my_redis_sentinel]# touch sentinel.conf
[root@localhost my_redis_sentinel]# vim sentinel.conf

(2) 配置哨兵配置文件sentinel.conf,填写内容

1
sentinel monitor 被监控主机名字(自己起名字) 127.0.0.1 6379 1

如:

1
sentinel monitor host6379 127.0.0.1 6379 1

上面最后一个数字1,表示主机挂掉后salve投票看让谁接替成为主机,得票数多少后成为主机

(3) 启动哨兵

1
2
3
4
5
6
7
8
9
[root@localhost bin]# ll
total 36272
-rw-r--r--. 1 root root 0 Dec 5 22:08 my_redis_log.log
-rwxr-xr-x. 1 root root 4796896 Nov 29 11:49 redis-benchmark
-rwxr-xr-x. 1 root root 9094264 Nov 29 11:49 redis-check-aof
-rwxr-xr-x. 1 root root 9094264 Nov 29 11:49 redis-check-rdb
-rwxr-xr-x. 1 root root 5049408 Nov 29 11:49 redis-cli
lrwxrwxrwx. 1 root root 12 Nov 29 11:49 redis-sentinel -> redis-server
-rwxr-xr-x. 1 root root 9094264 Nov 29 11:49 redis-server

使用redis bin目录下的redis-sentinel文件启动哨兵。

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
[root@localhost my_redis_sentinel]# /usr/local/redis-6.0.9/bin/redis-sentinel sentinel.conf
3620:X 07 Dec 2020 21:25:52.708 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
3620:X 07 Dec 2020 21:25:52.708 # Redis version=6.0.9, bits=64, commit=00000000, modified=0, pid=3620, just started
3620:X 07 Dec 2020 21:25:52.708 # Configuration loaded
3620:X 07 Dec 2020 21:25:52.709 * Increased maximum number of open files to 10032 (it was originally set to 1024).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 6.0.9 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in sentinel mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 26379
| `-._ `._ / _.-' | PID: 3620
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'

3620:X 07 Dec 2020 21:25:52.710 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
3620:X 07 Dec 2020 21:25:52.712 # Sentinel ID is 050fd7336f2201e2b8161b3141a1fb5024787e64
3620:X 07 Dec 2020 21:25:52.712 # +monitor master host6379 127.0.0.1 6379 quorum 1
3620:X 07 Dec 2020 21:25:52.713 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:25:52.714 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:25:52.716 * +slave slave 127.0.0.1:6382 127.0.0.1 6382 @ host6379 127.0.0.1 6379

(4) 正常主从演示,原有的master挂了,投票新选,重新主从继续开工,info replication查查看

/usr/local/redis-6.0.9/bin/redis-sentinel sentinel.conf输出日志:

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
3620:X 07 Dec 2020 21:30:23.524 # +sdown master host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:23.524 # +odown master host6379 127.0.0.1 6379 #quorum 1/1
3620:X 07 Dec 2020 21:30:23.524 # +new-epoch 1
3620:X 07 Dec 2020 21:30:23.524 # +try-failover master host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:23.530 # +vote-for-leader 050fd7336f2201e2b8161b3141a1fb5024787e64 1
3620:X 07 Dec 2020 21:30:23.530 # +elected-leader master host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:23.530 # +failover-state-select-slave master host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:23.597 # +selected-slave slave 127.0.0.1:6382 127.0.0.1 6382 @ host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:23.597 * +failover-state-send-slaveof-noone slave 127.0.0.1:6382 127.0.0.1 6382 @ host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:23.652 * +failover-state-wait-promotion slave 127.0.0.1:6382 127.0.0.1 6382 @ host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:24.315 # +promoted-slave slave 127.0.0.1:6382 127.0.0.1 6382 @ host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:24.315 # +failover-state-reconf-slaves master host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:24.377 * +slave-reconf-sent slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:25.328 * +slave-reconf-inprog slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:25.328 * +slave-reconf-done slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:25.381 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:26.399 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:26.399 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:26.457 # +failover-end master host6379 127.0.0.1 6379
3620:X 07 Dec 2020 21:30:26.457 # +switch-master host6379 127.0.0.1 6379 127.0.0.1 6382
3620:X 07 Dec 2020 21:30:26.457 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6382
3620:X 07 Dec 2020 21:30:26.457 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6382
3620:X 07 Dec 2020 21:30:26.457 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ host6379 127.0.0.1 6382
3620:X 07 Dec 2020 21:30:26.686 * +slave slave 127.0.0.1:6383 127.0.0.1 6383 @ host6379 127.0.0.1 6382
3620:X 07 Dec 2020 21:30:56.517 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ host6379 127.0.0.1 6382

slave-3: 6382,被选为新的master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@localhost bin]# /usr/local/redis-6.0.9/bin/redis-cli -p 6382
127.0.0.1:6382> info replication
# Replication
role:master
connected_slaves:3
slave0:ip=127.0.0.1,port=6383,state=online,offset=49086,lag=1
slave1:ip=127.0.0.1,port=6380,state=online,offset=49086,lag=1
slave2:ip=127.0.0.1,port=6381,state=online,offset=48953,lag=1
master_replid:85aba463c276379cc0294f8c5bd4620815899d4e
master_replid2:cb94b9c2350916f815229ef83734adbb6824648d
master_repl_offset:49086
second_repl_offset:18789
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:29
repl_backlog_histlen:49058

slave-1, slave-2, slave-4:

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
127.0.0.1:6380/6381/6383> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6382
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:58459
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:85aba463c276379cc0294f8c5bd4620815899d4e
master_replid2:cb94b9c2350916f815229ef83734adbb6824648d
master_repl_offset:58459
second_repl_offset:18789
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:840
repl_backlog_histlen:57620
127.0.0.1:6383> keys *
1) "k3"
2) "k1"
3) "k6"
4) "k5"
5) "k2"
6) "k4"
127.0.0.1:6383>

问题:如果之前的master重启回来,会不会双master冲突?

原master: 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
[root@localhost my_redis_6379]# /usr/local/redis-6.0.9/bin/redis-server my_redis_conf_6379.conf
[root@localhost my_redis_6379]# /usr/local/redis-6.0.9/bin/redis-cli
127.0.0.1:6379>
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6382
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:70305
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:85aba463c276379cc0294f8c5bd4620815899d4e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:70305
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:69324
repl_backlog_histlen:982

新master: 6382

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
127.0.0.1:6382> info replication
# Replication
role:master
connected_slaves:4
slave0:ip=127.0.0.1,port=6383,state=online,offset=76962,lag=0
slave1:ip=127.0.0.1,port=6380,state=online,offset=76815,lag=0
slave2:ip=127.0.0.1,port=6381,state=online,offset=76815,lag=0
slave3:ip=127.0.0.1,port=6379,state=online,offset=76815,lag=0
master_replid:85aba463c276379cc0294f8c5bd4620815899d4e
master_replid2:cb94b9c2350916f815229ef83734adbb6824648d
master_repl_offset:76962
second_repl_offset:18789
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:29
repl_backlog_histlen:76934

之前的master恢复后,会自动变为新master的slave。

5.3,一组sentinel能同时监控多个Master

在哨兵配置文件sentinel.conf中多添加几行配置即可

1
2
3
sentinel monitor <hostname1> <host_ip_1> <host_port_1> 1
sentinel monitor <hostname2> <host_ip_2> <host_port_2> 1
sentinel monitor <hostname3> <host_ip_3> <host_port_3> 1

6,复制的缺点

由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。