前言

这期来聊聊什么是主从复制?主从复制能干什么?Redis如何实现的主从复制?哨兵模式如何实现?最后再来说说复制的原理以及他的缺点,如果还没安装Redis的同学可以先去看一下 《手把手教你在Linux环境下安装Redis》 这篇文章,本篇主从复制的教程是在此基础上完成的

主从复制

是什么

Master-Slave replication是一种数据处理(备份)机制,主机更新数据后根据配置的策略自动同步给从机(备份机),通常情况下Master写为主、Slave读为主。如下图所示:

image.png

能干嘛

  1. 读写分离,常用读多写少的场景,例如电商平台
  2. 容灾备份/数据恢复

如何实现

修改配置文件

配置文件 redis.conf 中需要修改的地方如下:

# 1. 修改端口号,一主多从模式,此教程中我默认是以6379为主,63806381为从
port 6379

# 2.开启守护进程模式运行,默认是no
daemonize yes

# 3. 修改pid文件名,我是以端口来区分的
pidfile "/var/run/redis_6379.pid"

# 4.log文件名,以端口命名,放在log目录下
logfile "./log/6379.log"

# 5. dump.rdb文件名,存储内存中的快照
dbfilename "dump_6379.rdb"
# dump文件的目录
dir "/usr/local/bin/redis/dump"

# 6.拷贝多个 redis.conf 配置文件,并按照以上步骤修改配置文件

我是把多个配置文件放在了 /etc/redis/m_s/ 目录下(存储位置自己随意),如下图:

image.png

建立主从关系

我这里演示的是 一主二仆 即一个作为主机,两个作为从机。首先启动 master 节点,这个环节肯定少不了服务端 redis-server (注意:我这里是从redis解压后的src目录复制过来的)

image.png

启动端口号6379 没有设置密码

image.png

查看主从复制配置信息

image.png

以上操作的命令:

# 指定配置文件启动redis服务
# ./redis-server /etc/redis/m_s/redis-6379.conf

# 检查是否启动成功
# ps -ef|grep redis

# 客户端指定端口连接服务端
# ./redis-cli -p 6379

# INFO命令查看主从复制配置信息
# info replication

# 剩下的63806381按照以上操作一次启动

启动端口号6380

image.png

启动端口号6381

image.png

查看启动日志

image.png

从上面截图可以看出,redis启动后复制机制的角色初始都是master,那么如何建立主从关系呢?

本教程中我使用 slaveof <masterhost> <masterport> 命令,当然你也可在配置文件中配置,这样重启后就不会失效了。

# 63806381都配置从属到6379
slaveof 127.0.0.1 6379

image.png

6381 按照同样的操作与 6379 建立主从关系,你可以使用 info replication 命令来查看是否建立成功,此时你再回到 6379 查看他是否已经有两台从机与他关联上了,显示以下结果表示你成功了

image.png

验证主从复制

建立好主从关系之后,开始验证在 master 中写数据是否会同步到从机中,验证结果如下:

image.png

此时你可以查看一下存储快照的目录,是否为你生成了三个dump文件

image.png

从上面的验证结果可以看出在 主机6379 中写数据会自动同步到 从机6380、6381 中,这里抛出一个问题:如果在连接到从机的应用有写的操作,结果会怎样?如下图所示:

image.png

从结果来看,从机是不能进行写操作的,在 redis.conf 中从机默认配置了只读以及对此配置的相关说明:官方解释是为了保证(提高)只读从机的安全性,配置文件的内容如下(贴心的我做了一下翻译):

image.png

这里再抛出一个问题:如果redis的主机节点挂了,结果会怎样? 接下来我手动模拟master节点宕机了,看看另外两个slave节点会怎样?如下图所示:

image.png

image.png

63806381 来看,主机down了之后,从机不会有任何操作,而是等待主机恢复后再次重连。如下图所示:

image.png

从上面的结果来看,master(主)作为写数据的节点,如果在线上宕机了,在此期间应用就会无法写入数据,这种现象发生在线上环境是很 “危险” 的,那有没有一种方式能监控master节点,发现master节点宕机了之后立即将现有从节点升级为主节点呢?

答案肯定是有的,这个开发Redis的大佬们已经替我们想好了,接下来有请哨兵出场…

哨兵模式

你可以理解为是一个监控,哨兵巡逻监控你的master节点,如果发现master挂了,则会在存活的从机中通过投票选主的方式选出一个从机来作为新的master节点。

如何开启哨兵

在看完我的教程之后,建议你去看一下redis解压目录下在 src 目录中的 sentinel.conf 文件

# 创建一个sentinel.conf文件
# touch sentinel.conf

# sentinel.conf配置文件的内容如下:
port 26379
dir "/usr/local/bin/redis"
logfile "./log/sentinel.log"

# 以上几项都可以不写,启动哨兵后会自动生成的,主要是下面这段配置
sentinel monitor redis6379 127.0.0.1 6381 1

# 特别说明:
# redis6379表示hostname,你可以自己随意取名
# 最后的数字1表示当主机挂了之后,在从机中进行投票选主,票数大于1的晋升为主机

# 设置为守护进程模式,为了更好的看哨兵的效果,你可以先注释他,看看投票选主的过程
daemonize yes

image.png

这里我将 sentinel.conf 哨兵配置文件跟 redis.conf 放在了一起(位置随意,只要你启动哨兵服务指向该配置文件就行)

image.png

启动哨兵,使用到的 redis-sentinel 也是从 src 目录中复制过来的。过程如下图所示:

image.png

哨兵扫描到6379有两个从节点6380和6390

image.png

接下来你就可以模拟master宕机的情况,使用 shutdown 命令关掉 6379 看看哨兵是如何运行的。验证结果如下图所示:

image.png

# 投票选主的过程

# +sdown master redis6379 127.0.0.1 6379
# +odown master redis6379 127.0.0.1 6379 #quorum 1/1
# +new-epoch 1
# +try-failover master redis6379 127.0.0.1 6379
# +vote-for-leader eebe0e6a1e41fb71f8ee121df2ae0854f97c175c 1
# +elected-leader master redis6379 127.0.0.1 6379
# +failover-state-select-slave master redis6379 127.0.0.1 6379
# +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ redis6379 127.0.0.1 6379
* +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ redis6379 127.0.0.1 6379
* +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ redis6379 127.0.0.1 6379
# +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ redis6379 127.0.0.1 6379
# +failover-state-reconf-slaves master redis6379 127.0.0.1 6379
* +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ redis6379 127.0.0.1 6379
* +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ redis6379 127.0.0.1 6379
* +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ redis6379 127.0.0.1 6379
# +failover-end master redis6379 127.0.0.1 6379
# +switch-master redis6379 127.0.0.1 6379 127.0.0.1 6380
* +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ redis6379 127.0.0.1 6380
* +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ redis6379 127.0.0.1 6380
# +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ redis6379 127.0.0.1 6380

验证 6380 是否为上升为master,然后 6381 还会原地等待 6379 吗?验证结果如下图所示:

image.png

如果 6379 后面人为将其恢复正常后,他将扮演什么角色呢? 看到这里的同学自己验证一下吧,结果如何在评论区见~

总结

主从复制的原理

  1. slave启动成功连接到master后发送一个sync命令
  2. master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步
  3. 全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中
  4. 增量复制:master继续将新的所有收集到的修改命令依次传给slave,完成同步
  5. 但是只要是重新链接master,一次完全同步(全量复制)将被自动执行

主从复制的缺点

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

写在最后

此教程亲测有效,如果中间有问题或遗漏,欢迎来评论区吐槽~

如果对你所有帮助,记得点赞收藏哦~(哈哈哈,时间久了忘了怎么装就回来看看)

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐