Redis可以实现单机模式下的数据持久化,但解决不了单点宕机问题,一旦单台Redis服务器本身出现系统故障、硬件故障等问题后,就会直接造成数据的丢失。
要解决此问题,我们可以部署Redis主从复制架构,Redis主从复制也是Redis集群最简单的实现方式,此篇就来看下如何部署Redis主从架构。
此次实验,笔者准备了3台Rocky主机,IP分别为10.0.0.{8,18,28},主机名分别为RedisServer、slave1和slave2。
- 脚本安装Redis
当前Linux系统中直接通过yum或者apt安装的Redis版本较老,笔者使用脚本进行Redis6.2.2版本的编译安装,脚本内容如下。
脚本执行完毕,检测下端口和Redis服务状态,确保是可用的。
- Redis主从复制
主从模式可以实现Redis数据的跨主机备份,在配置主从复制时,从节点也要开启数据持久化并设置和主节点同样的连接密码。
2.1 默认主从状态
默认情况下,三台主机都是单机模式下的master角色。
2.2 主从复制的实现
配置Redis主从复制有两种方式,一种是通过命令行,一种是修改配置文件。
2.2.1 命令行配置
2.2.1.1 主节点写入测试数据
为了测试同步功能,笔者先在主节点写入一些数据,用于后期查看主从同步功能。
2.2.1.2 启用主从同步
使用命令行配置主从同步时,需要在从节点上使用replicaof命令指向主节点的IP+端口,查看复制信息时,角色随便变成了slave,但主节点的连接状态确实down。
此时,需要设置主节点 的连接密码,即主节点在Redis配置文件中设置的requirepass的密码,即可实现主从复制,查看复制信息,主节点的连接状态已经变成了up,查看Redis数据库中的key信息,也已经从主节点同步过来数据。
另一个从节点slave2执行相同命令加入主从复制架构。
2.2.1.3 查看主从状态
主节点上查看复制信息时,已经可以看到自己是master角色,有2个从节点,并能显示从节点的相关信息。
2.2.1.4 查看日志
主节点或者从节点查看日志可以从节点添加完毕的数据同步过程。
2.2.1.5 测试主从同步
在主节点查看端口,可以看到Redis服务的6379与两个slave节点的端口进行了持续连接,即可以时刻保持数据同步。
此时,主节点写的数据,两个从节点是可以保持同步的。
2.2.1.6 从节点写入测试
在Redis主从复制中,只有主节点才能进行写操作,从节点无法进行写操作,只能进行读操作。
2.2.1.7 删除主从同步
从节点上执行replicaof no one命令即可取消主从同步,取消主从同步后,对应主机自动变动master角色,并且之前同步的数据不会丢失。
2.2.1.8 重启自动删除主从复制
由于是通过命令行添加的主从复制,从节点重启Redis服务后将自动删除之前通过命令行添加的主从复制,与命令行取消主从复制一样,也会保留之前同步过来的数据。
2.2.2 配置文件配置主从复制
要想做到主从复制关系的持久有效,需要从节点将命令行的内容添加到配置文件中。生产中建议命令行和配置文件同时修改,但不重启从节点Redis服务,等待其出现故障等情况自动重启读取配置文件。
利用配置文件来进行主从复制时,只是将各节点的主从关系持久保存下来,其他命令都是相同的,笔者就不重复演示。
- 主从复制故障与恢复
3.1 从节点故障与恢复
当从节点出现故障时,只需将Redis客户端指向其它的从节点即可,并不会对整体架构的读操作进行太大影响,即使所有的从节点都出现了故障,也可以直接在主节点进行读操作。当然从节点出现故障后,还是建议尽快进行修复,以减轻其他节点的工作压力。
3.2 主节点故障与恢复
3.2.1 模拟主节点故障
关掉主节点的Redis服务模拟主节点出现故障情况。
登录到从节点查看,主节点的连接状态已经变成了down,由于主从复制架构下,只有主节点才能进行写操作,如果主节点挂掉了,必然会对业务产生影响。
3.2.2 提升新的主节点
为了减少Redis主从复制架构下主节点故障带来的影响,需要提升某一个从节点为新的主节点。
3.2.2.1 取消主从同步
例如现在要将slave1提升为新的主节点,则先要在slave1上取消主从同步,此时slave1已经恢复单机状态下的master角色,并可进行写操作。
3.2.2.2 其它节点开启主从复制
slave2将主从复制架构下的主节点信息指向slave2,由于已经在配置文件中添加过masterauth信息,故执行单条命令即可完成主从复制,查看slave1之前写入的name5这个key,已经可以获取对应value值。
3.2.3 原主节点恢复正常
重启原主节点的Redis服务,模拟服务器故障处理完毕,此时登录Redis可以看到又恢复到单机状态,并且只有4个数据。
如果将原主节点变成现有主从架构下的从节点,则可从现主节点(即slave1)同步name5这个key;但如果要保持原主节点不变,则要将现在的主从架构各节点都指向原主节点,并且之前写入的name5这个key也将丢失。
以依旧保持RedisServer主机为主节点为例,从节点执行主从复制命令时的顺序带来的效果不同,如果先在slave2上执行命令,则slave2变成RedisServer的从节点;如果先在slave1上执行,则可完成级联复制,slave2无需执行任何命令,仍然是slave1的从节点,并可通过slave1来间接同步数据。
- 主从复制优化
4.1 主从复制过程
Redis主从复制分为全量复制同步和增量复制同步。
4.1.1 全量复制同步
Redis主从复制全量复制同步过程如下图所示:
首次进行主从同步使用的是全量同步,主从同步可以让从节点通过主节点进行数据同步,而且从节点还可以再有自己的从节点,即以上所提到的级联复制架构。
Redis的主从同步是非阻塞的,主节点在收到从节点的psync命令(2.8版本前为SYNC)后,会fork一个子进程在后台执行bgsave命令,并将新写入的数据暂时先写到缓冲区,bgsave完成后将生成的RDB文件发送给从节点,然后主节点再将缓冲区的内容以Redis协议格式再全部发送给从节点。
从节点先删除旧数据,将接收到的RDB文件载入内存,再加载所有收到缓冲区的内容,从而完成一次完整的数据同步。
Redis全量复制一般发生在从节点首次初始化阶段,这是从节点需要将主节点上的所有数据都复制一份。
4.1.2 增量复制同步
Redis主从复制增量复制同步过程如下图所示:
在全量同步完成之后,如果还需要进行数据的同步,从节点只要发送当前的offset位置(类似于MySQL二进制日志记录的位置)给主节点服务器,然后主节点根据相应的位置将之后的数据(包括写在缓冲区的挤压数据)发送给从节点,并再次将其保存至从节点内存即可。
4.1.3 Redis主从同步完整过程
①从节点连接主节点,发送PSYNC命令;
②主节点接收到PSYNC命令后,开始执行bgsave命令生成RDB文件,并使用缓冲区记录此后执行的所有写命令;
③主节点bgsave命令执行完毕,向所有的从节点发送RDB文件,并在发送期间继续记录被执行的写命令;
④从节点收到RDB文件后丢弃所有旧数据,载入收到的RDB文件至内存;
⑤主节点发送RDB文件后,开始向从节点发送缓冲区中的写命令;
⑥从节点完成对RDB文件的载入,开始接收命令请求,并执行来自主节点服务器缓冲区的写命令;
⑦从节点后期的同步会先发送自己offset位置,只同步新增的数据,不再做全量同步。
4.2 主从复制注意事项
4.2.1 避免全量复制
①第一次全量复制不可避免,后续的全量复制可以利用小主节点(内存小),在业务低峰时进行全量复制;
②主节点在重启后会导致RUNID发生变化,可能会触发全量复制,可以利用故障转移,例如哨兵或者集群;
③复制积压缓冲区不足时,如果主节点新生成的数据过大,在从节点恢复与主节点的连接后可能会导致全量复制,解决方法是将repl-backlog-size值调大。
4.2.2 避免复制风暴
①单主节点复制风暴:当主节点重启后,多个从节点会同时从主节点复制数据,带来复制风暴,解决方法是更换复制拓扑。
②单机多实例复制复制风暴:当服务器出现宕机,并修缮完毕后,会进行大量的全量复制,引发复制风暴,解决方法是主节点分散多机器。
- 常见主从复制故障
5.1 主节点密码不正确
即主节点在Redis配置文件中设置的requirepass部分,从节点在执行主从同步命令时或者修改配置文件时未添加正确,则会导致无法建立主从同步关系。
5.2 Redis版本不同
不同的Redis大版本之间会存在兼容性问题,例如不同节点有使用3版本的,有使用4版本的,各节点之间应尽量保持Redis版本的一致性。
5.3 无法远程连接
在开启了安全模式下,没有在配置文件中设置bind地址或者未设置密码,则会无法进行远程连接。
5.4 主从节点配置不一致
①主从节点的maxmemory设置不一致,主节点内存大于从节点内存,则可能会导致主从复制时的数据丢失现象;
②rename-command命令不一致,例如在主节点上定义了flushall或flushdb命令,而没有在从节点上进行相同的定义,则执行flushall或flushdb命令不能同步数据。