Redis - 主从复制

2022/5/2 2:12:41

本文主要是介绍Redis - 主从复制,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一台master主机可以拥有多台slave从机,而一台slave从机又可以拥有多个slave从机,如此下去,形成强大的多级服务器集群架构(高扩展)。

主从复制的作用

主从复制,读写分离,容灾恢复。一台主机负责写入数据,多台从机负责备份数据。在高并发的场景下,即便是主机挂了,可以用从机代替主机继续工作,避免单点故障导致系统性能问题(高可用)。读写分离的架构,满足读多写少的并发应用场景

主从复制的架构

一个命令: slaveof 主机ip 主机port ,就可以确定主从关系;一个命令:./redis-sentinel sentinel.conf ,就可以开启哨兵监控。
搭建是简单的,维护是痛苦的。在高并发场景下,会有很多想不到的问题出现。我们只有清楚复制的原理,熟悉主机,从机宕机后的变化。才能很好的跨过这些坑。

架构图:一主二仆一兵(也可以多主多仆多兵)

搭建前的准备工作

笔者选择用一台服务器模拟三台主机,和生产环境的区别仅仅是ip地址和port端口不同。
第一步:将redis.conf 拷贝三份,名字分别是,redis6379.conf,redis6380.conf,redis6381.conf
第二步:修改三个文件的port端口,pid文件名,日志文件名,rdb文件名
第三步:分别打开三个窗口模拟三台服务器,开启redis服务。

[root@itdragon bin]# cp redis.conf redis6379.conf
[root@itdragon bin]# cp redis.conf redis6380.conf
[root@itdragon bin]# cp redis.conf redis6381.conf
[root@itdragon bin]# vim redis6379.conf
logfile "6379.log"
dbfilename dump_6379.rdb
[root@itdragon bin]# vim redis6380.conf
pidfile /var/run/redis_6380.pid
port 6380
logfile "6380.log"
dbfilename dump_6380.rdb
[root@itdragon bin]# vim redis6381.conf
port 6381
pidfile /var/run/redis_6381.pid
logfile "6381.log"
dbfilename dump_6381.rdb
[root@itdragon bin]# ./redis-server redis6379.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> keys *
(empty list or set)
[root@itdragon bin]# ./redis-server redis6380.conf 
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6380
127.0.0.1:6380> keys *
(empty list or set)
[root@itdragon bin]# ./redis-server redis6381.conf 
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6381
127.0.0.1:6381> keys *
(empty list or set)

主从复制的搭建步骤

基础搭建

第一步:查询主从复制信息,分别选择三个端口,执行命令:info replication。

# 6379 端口
[root@itdragon bin]# ./redis-server redis6379.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
......

# 6380 端口
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:0
......

# 6381 端口
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:0
......

三个端口都打印相同的信息:role:master 角色是master,connected_slaves:0 连接从机数量为零。

第二步:选择6379端口,执行命令:set k1 v1

127.0.0.1:6379> set k1 v1
OK

第三步:设置主从关系,分别选择6380端口和6381端口,执行命令:SLAVEOF 127.0.0.1 6379

# 6380 端口
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
......

# 6381 端口
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
......

# 6379 端口
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=98,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=98,lag=1
......

主从关系发生了变化:
6380端口和6381端口打印的信息: role:slave 从机;master_host:127.0.0.1 主机的ip地址;master_port:6379 主机的port 端口。
6379端口打印的信息: role:master 主机;connected_slaves:2 连了两个从机; slaveX : ID、IP 地址、端口号、连接状态、从库信息

第四步:全量复制,分别选择6380端口和6381端口,执行命令:get k1

# 6380 端口
127.0.0.1:6380> get k1
"v1"

# 6381 端口
127.0.0.1:6381> get k1
"v1"

两个端口都可以打印k1的值,说明在建立主从关系时,从机便拥有了主机的数据。

第五步:增量复制,选择6379端口,执行命令:set k2 v2。然后分别选择6380端口和6381端口,执行命令:get k2
# 6379 端口
127.0.0.1:6379> set k2 v2
OK

# 6380 端口
127.0.0.1:6380> get k2
"v2"

# 6381 端口
127.0.0.1:6381> get k2
"v2"

两个端口都可以打印k2的值,说明建立主从关系后,主机新增的数据都会复制给从机。

第六步:主从的读写分离,选择6380端口,执行命令:set k3 v3
# 6380 端口
127.0.0.1:6380> set k3 v3
(error) READONLY You can't write against a read only slave.

# 6379 端口
127.0.0.1:6379> set k3 v3
OK

从机6380写入失败,是因为读写分离的机制。

第七步:主机宕机的情况,选择6379端口,执行命令:shutdown

# 6379 端口
127.0.0.1:6379> SHUTDOWN
not connected> QUIT

# 6380 端口
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
......

# 6381 端口
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
......

从打印的结果得知:从机原地待命。

第八步:主机宕机后恢复,选择6379端口,重启Redis服务,执行命令:set k4 v4。分别选择6380端口和6381端口,执行命令:get k4

# 6379 端口
[root@itdragon bin]# ./redis-server redis6379.conf 
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> set k4 v4
OK

# 6380 端口
127.0.0.1:6380> get k4
"v4"

# 6381 端口
127.0.0.1:6381> get k4
"v4"

主机重启后,一切正常。

第九步:从机宕机后恢复,选择6380端口,执行命令:shutdown。选择6379端口,执行命令:set k5 v5。选择6380端口,重启Redis服务后执行命令:get k5

# 6380 端口
127.0.0.1:6380> SHUTDOWN
not connected> QUIT
[root@itdragon bin]# ./redis-server redis6380.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6380
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
......
127.0.0.1:6380> get k5
"v5"

# 6379 端口
127.0.0.1:6379> set k5 v5
OK

从机宕机后,一切正常。笔者用的是redis.4.0.2版本的。看过其他教程,从机宕机恢复后,只能同步主机新增数据,也就是k5是没有值的,可是笔者反复试过,均有值。留着备忘!

第十步:去中性化思想,选择6380端口,执行命令:SLAVEOF 127.0.0.1 6381。选择6381端口,执行命令:info replication

# 6380 端口
127.0.0.1:6380> SLAVEOF 127.0.0.1 6381
OK

# 6381 端口
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
......
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=1677,lag=1
......

虽然6381 是6380的主机,是6379的从机。在Redis眼中,6381依旧是从机。一台主机配多台从机,一台从机在配多台从机,从而实现了庞大的集群架构,同时也减轻了一台主机的压力,缺点是增加了服务器间的延迟。

哨兵监控

哨兵有三大任务:
1)监控:哨兵会不断地检查你的Master和Slave是否运作正常;
2)提醒:当被监控的某个Redis出现问题时, 哨兵可以通过API向管理员或者其他应用程序发送通知;
3)自动故障迁移:若一台主机出现问题时,哨兵会自动将该主机下的某一个从机设置为新的主机,并让其他从机和新主机建立主从关系。

哨兵搭建步骤:
第一步:新开一个窗口,取名sentinel,方便观察哨兵日志信息。
第二步:创建sentinel.conf文件,也可以从redis的解压文件夹中拷贝一份。
第三步:设置监控的主机和上位的规则,编辑sentinel.conf,输入 sentinel monitor itdragon-redis 127.0.0.1 6379 1 保存退出。解说:指定监控主机的ip地址,port端口,得票数。
第四步:前端启动哨兵,执行命令:./redis-sentinel sentinel.conf。
第五步:模拟主机宕机,选择6379窗口,执行命令:shutdown。
第六步:等待从机投票,在sentinel窗口中查看打印信息。
第七步:启动6379服务器,若从机得票数大于设置值,则成为新的主机。若之前的主机恢复后,哨兵也宕机了,那就多配几个哨兵并且相互监控
语法结构:sentinel monitor 自定义数据库名 主机ip 主机port 得票数

# sentinel窗口
[root@itdragon bin]# vim sentinel.conf
sentinel monitor itdragon-redis 127.0.0.1 6379 1
[root@itdragon bin]# ./redis-sentinel sentinel.conf
......
21401:X 29 Nov 15:39:15.052 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ itdragon-redis 127.0.0.1 6380
21401:X 29 Nov 15:39:15.052 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ itdragon-redis 127.0.0.1 6380
21401:X 29 Nov 15:39:45.081 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ itdragon-redis 127.0.0.1 6380

21401:X 29 Nov 16:40:52.055 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ itdragon-redis 127.0.0.1 6380
21401:X 29 Nov 16:41:02.028 * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ itdragon-redis 127.0.0.1 6380
......

# 6379端口
127.0.0.1:6379> SHUTDOWN
not connected> QUIT

# 6380端口
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=72590,lag=0
......

# 6381端口
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
......

+slave:一个新的从服务器已经被 Sentinel 识别并关联。
+sdown:给定的实例现在处于主观下线状态。
-sdown:给定的实例已经不再处于主观下线状态。

主从复制的原理

全量复制
实现原理:建立主从关系时,从机会给主机发送sync命令,主机接收命令,后台启动的存盘进程,同时收集所有用于修改命令,传送给从机
增量复制
实现原理:主机会继续将新收集到的修改命令依次传给从机,实现数据的同步效果

主从复制的缺点

最大的缺点就是延迟,主机负责写,从机负责备份,这个过程有一定的延迟,当系统很繁忙时,延迟问题会更加严重,从机器数量的增加也会使这个问题更加严重。

总结

1、查看主从复制关系命令:info replication
2、设置主从关系命令:slaveof 主机ip 主机port
3、开启哨兵模式命令:./redis-sentinel sentinel.conf
4、主从复制原理:开始是全量复制,之后是增量复制
5、哨兵模式三大任务:监控,提醒,自动故障迁移



这篇关于Redis - 主从复制的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程