什么是主从复制
在 Redis 复制的基础上,使用和配置主从复制非常简单,能使得从 Redis 服务器(下文称 slave)能精确得复制主 Redis 服务器(下文称 master)的内容。每次当 slave 和 master 之间的连接断开时, slave 会自动重连到 master 上,并且无论这期间 master 发生了什么, slave 都将尝试让自身成为 master 的精确副本。
这个系统的运行依靠三个主要的机制:
当一个 master 实例和一个 slave 实例连接正常时, master 会发送一连串的命令流来保持对 slave 的更新,以便于将自身数据集的改变复制给 slave,包括客户端的写入、key 的过期或被逐出等等。
当 master 和 slave 之间的连接断开之后,因为网络问题、或者是主从意识到连接超时, slave 重新连接上 master 并会尝试进行部分重同步:这意味着它会尝试只获取在断开连接期间内丢失的命令流。
当无法进行部分重同步时, slave 会请求进行全量重同步。这会涉及到一个更复杂的过程,例如 master 需要创建所有数据的快照,将之发送给 slave ,之后在数据集更改时持续发送命令流到 slave 。
小结:
简单来讲,就是一个主redis服务器,配置几个全量的从属服务器,实现服务的高可用,但无法实现扩容操作。也就是在AKF的X轴上扩展,不了解AKF的小伙伴可以补一下AKF的xyz三轴架构基础哦~(无基础不影响本文理解)。
无sentinel(哨兵)主从配置
无哨兵配置的主从模式,当master(主)挂掉后,需要人工手动下线master,并且人工指定新的master。
- Master(主)配置
无需对配置文件做任何更改,直接启动就行,这里使用56379这个端口作为master的端口
- slave(从)配置
...
# 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 56480
# TCP listen() backlog.
...
# replicaof <masterip> <masterport>
replicaof 127.0.0.1 56379
# 这里是配置从服务器认56379为主
...
# security of read only replicas using 'rename-command' to shadow all the
# administrative / dangerous commands.
replica-read-only yes
# 开启只读模式,实现读写分离,写全部在master实现
再设置一台56481为从服务器。
启动服务器
启动主服务器
➜ test redis-server 56379.conf
启动从属服务器
➜ test redis-server 56479.conf
➜ test redis-server 56480.conf
连接服务器测试
主服务器
# 连接主服务器
➜ test redis-cli -p 56379
# 新建数据
127.0.0.1:56379> set k1 aaa
OK
127.0.0.1:56379> set k2 aaa
OK
127.0.0.1:56379> keys *
1) "k1"
2) "k2"
127.0.0.1:56379>
从服务器
# 连接从属服务器56479
➜ test redis-cli -p 56479
# 查看数据,发现同步一致
127.0.0.1:56479> keys *
1) "k2"
2) "k1"
127.0.0.1:56479> get k1
"aaa"
# 因为从属服务器开启了只读模式,所以无法插入数据
127.0.0.1:56479> set k3 bbb
(error) READONLY You can't write against a read only replica.
127.0.0.1:56479>
➜ test redis-cli -p 56480
# 查看数据,发现同步一致
127.0.0.1:56480> keys *
1) "k1"
2) "k2"
127.0.0.1:56480> get k2
"aaa"
# 因为从属服务器开启了只读模式,所以无法插入数据
127.0.0.1:56480> set k4
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:56480>
至此,简单的主从配置已经完成,接下来测试master挂了的情况。
人工降级干预
手动关闭56379主服务器,模拟主服务器掉线
# 退出主服务器
127.0.0.1:56379> quit
# 关闭主服务器
➜ test redis-cli -p 56379 shutdown
➜ test
此时测试从属服务器,已有数据查询不受影响,但是无法插入新数据
127.0.0.1:56480> keys *
1) "k1"
2) "k2"
127.0.0.1:56480> set k1 a
(error) READONLY You can't write against a read only replica.
手动升级56479为主服务器
# 手动设置56479为大哥(主服务器)
127.0.0.1:56479> slaveof no one
OK
# 测试数据插入和删除,都OK
127.0.0.1:56479> set k3 ccc
OK
127.0.0.1:56479> get k3
"ccc"
127.0.0.1:56479>
查看另一台从属服务器状态
# 测试发现56480不认新的带头大哥,需要手动教育一下
127.0.0.1:56480> get k3
(nil)
# 开始教育!
127.0.0.1:56480> SLAVEOF 127.0.0.1 56479
OK
# 教育成功,非常的听话
127.0.0.1:56480> get k3
"ccc"
127.0.0.1:56480> set k5 ffff
(error) READONLY You can't write against a read only replica.
小结:
发现手动干预需要两步,第一步指定新的带头大哥(Master),第二步,教育不听话的老式小弟,听新的带头大哥指令。
有一两个小弟,手动教育起来没那么麻烦,万一十个八个的让人工手动操作也有些头疼,能不能程序自动实现这个教育功能呢?
接下来介绍哨兵模式,我们指定3个哨兵,帮我们完成选举新的带头大哥+教育小弟听话
哨兵模式
申明一下:此时,系统中的带头大哥是56479,小弟为56379 56480
手动停掉所有服务
# 关闭服务器
127.0.0.1:56479> quit
➜ test redis-cli -p 56479 shutdown
➜ test
# 关闭服务器
127.0.0.1:56480> quit
➜ test redis-cli -p 56480 shutdown
➜ test
配置哨兵
新建配置文件
➜ test touch 56380.conf
➜ test vi 56380.conf
############ 配置文件内容################
# 配置端口为56380
port 56380
# 配置监控对象为56479 投票为2票,我们总共设置3个哨兵,2票接可以当选新大哥
sentinel monitor myMaster 127.0.0.1 56479 2
同样的方式创建56381.conf和56382.conf,只需要在配置文件中改端口就行,全部监控带头大哥(56479)
启动哨兵
# 七佛难过哨兵 56380,同样的方式在新的终端启动56381 和 56382
➜ test redis-sentinel 56380.conf
启动成功图示
启动主服务器和相应的从服务器
# 启动主服务器
➜ test redis-server 56479.conf
此时哨兵的前台出现如下信息:
31396:X 30 Nov 2021 14:14:01.349 # -sdown master myMaster 127.0.0.1 56479
31396:X 30 Nov 2021 14:14:03.082 * +sentinel sentinel 8d5de677e4e127e1c331dde7b4a71d434149b6d5 127.0.0.1 56380 @ myMaster 127.0.0.1 56479
31396:X 30 Nov 2021 14:14:03.254 * +sentinel sentinel 7b7158b36f6dca652aa2979a41878d5732032d68 127.0.0.1 56381 @ myMaster 127.0.0.1 56479
# 启动从服务器
➜ test redis-server 56379.conf
➜ test redis-server 56480.conf
此时哨兵输出如下:
# 发现带头大哥(56479)的小弟(56480)正在追随带头大哥!
31350:X 30 Nov 2021 14:24:07.759 * +slave slave 127.0.0.1:56480 127.0.0.1 56480 @ myMaster 127.0.0.1 56479
# 发现带头大哥(56479)的小弟(56379)正在追随带头大哥!
31350:X 30 Nov 2021 14:28:59.556 * +slave slave 127.0.0.1:56379 127.0.0.1 56379 @ myMaster 127.0.0.1 56479
至此,哨兵的简单配置和使用已经OK,接下来我们手动模拟带头大哥去世(下线),看看哨兵能不能像我们想的一样扶持新的带头大哥上位!
手动下线Master(56479)
127.0.0.1:56479> quit
➜ test redis-cli -p 56479 shutdown
➜ test
此时,哨兵的输出:
# 总有一个优秀哨兵先发现情况,开始投票扶持新的带头大哥
31304:X 30 Nov 2021 14:33:57.338 # +sdown master myMaster 127.0.0.1 56479
31304:X 30 Nov 2021 14:33:57.391 # +odown master myMaster 127.0.0.1 56479 #quorum 3/2
31304:X 30 Nov 2021 14:33:57.391 # +new-epoch 4
31304:X 30 Nov 2021 14:33:57.391 # +try-failover master myMaster 127.0.0.1 56479
# 开始选举新任带头大哥!
31304:X 30 Nov 2021 14:33:57.392 # +vote-for-leader 8d5de677e4e127e1c331dde7b4a71d434149b6d5 4
31304:X 30 Nov 2021 14:33:57.396 # 7b7158b36f6dca652aa2979a41878d5732032d68 voted for 8d5de677e4e127e1c331dde7b4a71d434149b6d5 4
31304:X 30 Nov 2021 14:33:57.396 # 17af0cea2f7aa70101de4f080d666b8e3897cf11 voted for 8d5de677e4e127e1c331dde7b4a71d434149b6d5 4
31304:X 30 Nov 2021 14:33:57.468 # +elected-leader master myMaster 127.0.0.1 56479
31304:X 30 Nov 2021 14:33:57.468 # +failover-state-select-slave master myMaster 127.0.0.1 56479
31304:X 30 Nov 2021 14:33:57.524 # +selected-slave slave 127.0.0.1:56480 127.0.0.1 56480 @ myMaster 127.0.0.1 56479
31304:X 30 Nov 2021 14:33:57.524 * +failover-state-send-slaveof-noone slave 127.0.0.1:56480 127.0.0.1 56480 @ myMaster 127.0.0.1 56479
31304:X 30 Nov 2021 14:33:57.607 * +failover-state-wait-promotion slave 127.0.0.1:56480 127.0.0.1 56480 @ myMaster 127.0.0.1 56479
31304:X 30 Nov 2021 14:33:57.778 # +promoted-slave slave 127.0.0.1:56480 127.0.0.1 56480 @ myMaster 127.0.0.1 56479
31304:X 30 Nov 2021 14:33:57.778 # +failover-state-reconf-slaves master myMaster 127.0.0.1 56479
31304:X 30 Nov 2021 14:33:57.835 * +slave-reconf-sent slave 127.0.0.1:56379 127.0.0.1 56379 @ myMaster 127.0.0.1 56479
31304:X 30 Nov 2021 14:33:58.497 # -odown master myMaster 127.0.0.1 56479
31304:X 30 Nov 2021 14:33:58.498 * +slave-reconf-inprog slave 127.0.0.1:56379 127.0.0.1 56379 @ myMaster 127.0.0.1 56479
31304:X 30 Nov 2021 14:33:58.498 * +slave-reconf-done slave 127.0.0.1:56379 127.0.0.1 56379 @ myMaster 127.0.0.1 56479
31304:X 30 Nov 2021 14:33:58.549 # +failover-end master myMaster 127.0.0.1 56479
# 56480当选新任大哥,开始登基!
31304:X 30 Nov 2021 14:33:58.549 # +switch-master myMaster 127.0.0.1 56479 127.0.0.1 56480
# 哨兵帮助我们教育小弟56379,扶持新任带头大哥54680执掌天下大事!
31304:X 30 Nov 2021 14:33:58.549 * +slave slave 127.0.0.1:56379 127.0.0.1 56379 @ myMaster 127.0.0.1 56480
# 哨兵帮助我们教育上一任带头大哥56479成为小弟,一旦抢救成功,回来继续做小弟,扶持新任带头大哥54680执掌天下大事!
31304:X 30 Nov 2021 14:33:58.549 * +slave slave 127.0.0.1:56479 127.0.0.1 56479 @ myMaster 127.0.0.1 56480
31304:X 30 Nov 2021 14:34:28.588 # +sdown slave 127.0.0.1:56479 127.0.0.1 56479 @ myMaster 127.0.0.1 56480
此时,我们启动56479看看会发生什么
# 56479抢救成功,回来了~
➜ test redis-server 56479.conf
➜ test
哨兵输出:
# 抢救成功就继续的做小弟吧,大哥已经没有你的位置了!
31350:X 30 Nov 2021 14:41:58.790 # -sdown slave 127.0.0.1:56479 127.0.0.1 56479 @ myMaster 127.0.0.1 56480
小结:
至此,我们发现,哨兵可以完美的帮助我们完成新的master的选举和扶持,无需手动干预,可以保证redis服务的高可用!
总结
- 本文主要简单的讲述了主从配置和带哨兵的主从配置
- 通过实践发现,带哨兵的主从配置是我们更喜欢的选择,可以帮我们提高服务的高可用
- 除了上文的配置外,还有许多其他的配置,大家可以深入研究配置文件选择适合自己的配置,不要“为了技术而技术”
- 例如哨兵的默认监控时间间隔为3分钟,对于生产环境来说,显然风险太高,可以手动设置为1秒一次等。。。