当前位置: 首页 > news >正文

12.Redis 主从复制

Redis 主从复制

  • Redis 主从复制
    • 1. Redis 主从复制架构
    • 2. 主从复制实现
      • 2.1 主从命令配置
        • 2.1.1 启用主从同步
        • 2.1.2 查看日志观察同步状态
        • 2.1.3 修改 Slave 节点配置文件
        • 2.1.4 删除主从同步
    • 3. 主从复制故障恢复
      • 3.1 Slave 节点故障和恢复
      • 3.2 Master 节点故障和恢复
      • 3.3 常见主从复制故障
    • 4. 主从复制优化
      • 4.1 避免全量复制
      • 4.2 避免复制风暴
      • 4.3 性能相关配置

Redis 主从复制

Redis单机服务存在数据和服务的单点问题,而且单机性能也存在着上限,可以利用Redis的集群相关技术来解决这些问题

1. Redis 主从复制架构

Redis和MySQL的主从模式类似,也支持主从模式(master/slave),可以实现Redis数据的跨主机的远程备份

常见客户端连接主从的架构:

程序APP先连接到高可用性 LB 集群提供的虚拟IP,再由LB调度将用户的请求至后端Redis 服务器来真正提供服务

主从复制特点

  • 一个master可以有多个slave
  • 一个slave只能有一个master
  • 数据流向是从master到slave单向的
  • master 可读可写 slave 只读

2. 主从复制实现

当master出现故障后,可以自动提升一个slave节点变成新的Mster,因此Redis Slave 需要设置和master相同的连接密码

此外当一个Slave提升为新的master时需要通过持久化实现数据的恢复

当配置Redis复制功能时,强烈建议打开主服务器的持久化功能。否则的话,由于延迟等问题,部署的主节点Redis服务应该要避免自动启动

导致主从服务器数据全部丢失

  • 假设节点A为主服务器,并且关闭了持久化。并且节点B和节点C从节点A复制数据
  • 节点A崩溃,然后由自动拉起服务重启了节点A,由于节点A的持久化被关闭了,所以重启之后没有任何数据
  • 节点B和节点C将从节点A复制数据,但是A的数据是空的,于是就把自身保存的数据副本删除。

在关闭主服务器上的持久化,并同时开启自动拉起进程的情况下,即便使用Sentinel来实现Redis的高可用性,也是非常危险的。因为主服务器可能拉起得非常快,以至于Sentinel在配置的心跳时间间隔内没有检测到主服务器已被重启,然后还是会发生上面描述的情况,导致数据丢失

无论何时,数据安全都是极其重要的,所以应该禁止主服务器关闭持久化的同时自动启动

主从复制过程

Redis主从复制分为全量同步和增量同步

Redis 的主从同步是非阻塞的,即同步过程不会影响主服务器的正常访问

注意:主节点重启会导致全量同步,从节点重启只会导致增量同步

全量复制过程 Full resync

  • 主从节点建立连接,验证身份后,从节点向主节点发送PSYNC(2.8版本之前是SYNC)命令
  • 主节点向从节点发送FULLRESYNC命令,包括master_replid(runID)和offset
  • 从节点保存主节点信息
  • 主节点执行BGSAVE保存RDB文件,同时记录新的记录到buffer中
  • 主节点发送RDB文件给从节点
  • 主节点将新收到buffer中的记录发送至从节点
  • 从节点删除本机的旧数据
  • 从节点加载RDB
  • 从节点同步主节点的buffer信息

全量复制发生在下面情况

  • 从节点首次连接主节点(无master_replid/run_id)
  • 从节点的复制偏移量不在复制积压缓冲区内
  • 从节点无法连接主节点超过一定的时间

增量复制过程

在主从复制首次完成全量同步之后再次需要同步时,从服务器只要发送当前的offset位置(类似于MySQL的 binlog的位置)给主服务器,然后主服务器根据相应的位置将之后的数据(包括写在缓冲区的积压数据)发送给从服务器,再次将其保存到从节点内存即可。 即首次全量复制,之后的复制基本增量复制实现。

主从同步完整过程

  • slave发起连接master,验证通过后,发送PSYNC命令
  • master接收到PSYNC命令后,执行BGSAVE命令将全部数据保存至RDB文件中,并将后续发生的写操作记录至buffer中
  • master向所有slave发送RDB文件
  • master向所有slave发送后续记录在buffer中写操作
  • slave收到快照文件后丢弃所有旧数据
  • slave加载收到的RDB到内存
  • slave 执行来自master接收到的buffer写操作
  • 当slave完成全量复制后,后续master只会先发送slave_repl_offset信息
  • 以后slave比较自身和master的差异,只会进行增量复制的数据即可

注意:Redis 重启服务后,master_replid(runID)会发生变化。

复制缓冲区(环形队列)配置参数

#master的写入数据缓冲区,用于记录自上一次同步后到下一次同步过程中间的写入命令,计算公式:repl-backlog-size = 允许从节点最大中断时长 * 主实例offset每秒写入量,比如:master每秒最大写入64mb,最大允许60秒,那么就要设置为64mb*60秒=3840MB(3.8G),建议此值是设置的足够大,默认值为1M
repl-backlog-size 1mb #如果一段时间后没有slave连接到master,则backlog size的内存将会被释放。如果值为0则表示永远不释放这部份内存。 
repl-backlog-ttl 3600

2.1 主从命令配置

2.1.1 启用主从同步

Redis Server 默认为 master节点,如果要配置为从节点,需要指定master服务器的IP,端口及连接密码

在从节点执行 REPLICAOF MASTER_IP PORT 指令可以启用主从同步复制功能,早期版本使用 SLAVEOF 指令

127.0.0.1:6379> REPLICAOF MASTER_IP  PORT #新版推荐使用
127.0.0.1:6379> SLAVEOF MasterIP  Port    #旧版使用,将被淘汰
127.0.0.1:6379> CONFIG SET masterauth <masterpass>

先通过一键编译脚本在三台主机上安装好redis,搭建一主两从

主机IP节点
10.0.0.100
10.0.0.101
10.0.0.102

准备阶段:

# 在mater上设置一些key方便观察
[root@ubuntu2204 ~]#redis-cli -a 123456 info keyspace
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Keyspace
db0:keys=1000,expires=0,avg_ttl=0# 两个从节点目前没有key
[root@ubuntu2204 ~]#redis-cli -a 123456 info keyspace
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Keyspace# 三个节点默认都是master
[root@ubuntu2204 ~]#redis-cli -a 123456 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:b60b6478f2bb8d8a2e356b9d3c8540492e828708
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

具体搭建步骤:

# 两个从节点都执行
[root@ubuntu2204 ~]#redis-cli -a 123456
# 在slave上设置master的IP和端口
127.0.0.1:6379> replicaof 10.0.0.100 6379
OK# 在slave上设置master的密码,才可以同步
127.0.0.1:6379> config set masterauth 123456
OK# 查看是否成为slave
127.0.0.1:6379> info replication# 查看是否同步成功
127.0.0.1:6379> info keyspace
# Keyspace
db0:keys=1000,expires=0,avg_ttl=0# 主节点上查看 
# 在master上可以看到所有slave信息
127.0.0.1:6379> info replication
2.1.2 查看日志观察同步状态
# 主从节点分别在同步之前打开日志观察
[root@ubuntu2204 ~]#tail -f /apps/redis/log/redis_6379.log
2.1.3 修改 Slave 节点配置文件
[root@ubuntu2204 ~]#vim /apps/redis/etc/redis.conf(大约在533、540行附近)
replicaof 10.0.0.100 6379
masterauth 123456注意:requirepass 123456 的密码要和masterauth保持一致,用于将来从节点提升主后使用。# 重启redis服务
[root@ubuntu2204 ~]#systemctl restart redis# Master和Slave查看状态
[root@ubuntu2204 ~]#redis-cli -a 123456
127.0.0.1:6379> info replication注意:
master_link_status:up
master_last_io_seconds_ago:6   # 如果主从复制通信正常,每10秒重新从0计数,此值无法修改,如果无法通信,当计数到60时,master_link_status显示为down
master_sync_in_progress:0      # 0表示同步完成,1表示正在同步# 查看是否同步成功
127.0.0.1:6379> info keyspace
# Keyspace
db0:keys=1000,expires=0,avg_ttl=0# Slave 只读状态
127.0.0.1:6379> set key1 v1
(error) READONLY You can't write against a read only replica.
2.1.4 删除主从同步

在从节点执行 REPLICAOF NO ONE 或 SLAVEOF NO ONE 指令可以取消主从复制

取消复制会断开和master的连接而不再有主从复制关联, 但不会清除slave上已有的数据

# 新版
127.0.0.1:6379> REPLICAOF NO ONE# 旧版
127.0.0.1:6379> SLAVEOF NO ONE

3. 主从复制故障恢复

3.1 Slave 节点故障和恢复

当 slave 节点故障时,将Redis Client指向另一个 slave 节点即可,并及时修复故障从节点

3.2 Master 节点故障和恢复

当 master 节点故障时,需要提升slave为新的master

master故障后,当前还只能手动提升一个slave为新master,不能自动切换。

之后将其它的slave节点重新指定新的master为master节点

Master的切换会导致master_replid发生变化,slave之前的master_replid就和当前master不一致从而会引发所有 slave的全量同步。

具体操作步骤:

1.查看当前节点的状态为是否为slave,master指向是否是故障的master节点
2.停止slave同步并提升为新的master 使用命令 REPLICAOF NO ONE ,配置文件也要修改
3.修改所有slave 指向新的master节点使用命令 replicaof 新masterIP地址 6379 ,配置文件也要修改
4.在新master节点上查看状态

3.3 常见主从复制故障

主从硬件和软件配置不一致

主从节点的maxmemory不一致,主节点内存大于从节点内存,主从复制可能丢失数据

rename-command 命令不一致,如在主节点启用flushdb,从节点禁用此命令,结果在master节点执行 flushdb后,导致slave节点不同步

Master 节点密码错误

如果slave节点配置的master密码错误,导致验证不通过,自然将无法建立主从同步关系。

Redis 版本不一致

不同的redis 版本之间尤其是大版本间可能会存在兼容性问题,如:Redis 3,4,5,6之间

因此主从复制的所有节点应该使用相同的版本

安全模式下无法远程连接

如果开启了安全模式,并且没有设置bind地址和密码,会导致无法远程连接

4. 主从复制优化

4.1 避免全量复制

  • 第一次全量复制不可避免,后续的全量复制可以利用小主节点(内存小),业务低峰时进行全量
  • 节点RUN_ID不匹配:主节点重启会导致RUN_ID变化,可能会触发全量复制,可以利用config命令动态修改配置,故障转移例如哨兵或集群选举新的主节点也不会全量复制,而从节点重启动,不会导致全量复制,只会增量复制
  • 复制积压缓冲区不足: 当主节点生成的新数据大于缓冲区大小,从节点恢复和主节点连接后,会导致全量复制 解决方法将repl-backlog-size 调大

4.2 避免复制风暴

单主节点复制风暴

当主节点重启,多从节点复制

解决方法:更换复制拓扑(级联复制)

单机器多实例复制风暴

机器宕机后,大量全量复制

解决方法:主节点分散多机器

4.3 性能相关配置

Redis在2.8版本之前没有提供增量部分复制的功能,当网络闪断或者slave Redis重启之后会导致主从之间的全量同步,即从2.8版本开始增加了部分复制的功能。

repl-diskless-sync no # 是否使用无盘方式进行同步RDB文件,默认为no(编译安装默认为yes),no表示不使用无盘,需要将RDB文件保存到磁盘后再发送给slave,yes表示使用无盘,即RDB文件不需要保存至本地磁盘,而且直接通过网络发送给slaverepl-diskless-sync-delay 5 # 无盘时复制的服务器等待的延迟时间repl-ping-slave-period 10 # slave向master发送ping指令的时间间隔,默认为10srepl-timeout 60 # 指定ping连接超时时间,超过此值无法连接,master_link_status显示为down状态,并记录错误日志repl-disable-tcp-nodelay no # 是否启用TCP_NODELAY
# 设置成yes,则redis会合并多个小的TCP包成一个大包再发送,此方式可以节省带宽,但会造成同步延迟时长的增加,导致master与slave数据短期内不一致
# 设置成no,则master会立即同步数据repl-backlog-size 1mb # master的写入数据缓冲区,用于记录自上一次同步后到下一次同步前期间的写入命令,计算公式:repl-backlog-size = 允许slave最大中断时长 * master节点offset每秒写入量,如:master每秒最大写入量为32MB,最长允许中断60秒,就要至少设置为32*60=1920MB,建议此值是设置的足够大,如果此值太小,会造成全量复制repl-backlog-ttl 3600 # 指定多长时间后如果没有slave连接到master,则backlog的内存数据将会过期。如果值为0表示永远不过期。 slave-priority 100 # slave参与选举新的master的优先级,此整数值越小则优先级越高。当master故障时将会按照优先级来选择slave端进行选举新的master,如果值设置为0,则表示该slave节点永远不会被选为master节点。min-replicas-to-write 1 # 指定master的可用slave不能少于个数,如果少于此值,master将无法执行写操作,默认为0,生产建议设为1,min-slaves-max-lag 20 # 指定至少有min-replicas-to-write数量的slave延迟时间都大于此秒数时,master将不能执行写操作,默认为10s
http://www.dtcms.com/a/312867.html

相关文章:

  • deep research|从搜索引擎到搜索助手的实践(一)
  • 企业自动化交互体系的技术架构与实现:从智能回复到自动评论—仙盟创梦IDE
  • 三、驱动篇-HDF驱动介绍1
  • 语义分割--Fcn
  • 回顾MDP的概念
  • RabbitMQ面试精讲 Day 8:死信队列与延迟队列实现
  • dbdiagram:一款简洁高效的免费数据库设计工具
  • 二叉树算法之【前序遍历】
  • 三生原理的“范畴语法”如何启发AI推理?
  • Spring Boot 整合 Minio 实现高效文件存储解决方案(本地和线上)
  • 个人项目介绍:语音识别小助手
  • Spring AI的英语实例
  • Nginux Rewte 相关功能
  • 基于Python实现生产者—消费者分布式消息队列:构建高可用异步通信系统
  • Rustdesk中继服务器搭建(windows 服务器)
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-56,(知识点:电源模块,DCDC电源,LDO电源,原理及其特点)
  • Java(HashMap和HashTable和Properties)
  • kafka 是一个怎样的系统?是消息队列(MQ)还是一个分布式流处理平台?
  • 哔哩哔哩招游戏内容产品运营
  • Ubuntu22.4部署大模型前置安装
  • 零确认双花攻击
  • 智变时代:AI 如何重构工作边界与行业生态?
  • 【软考中级网络工程师】知识点之 IS-IS 协议
  • 百度招黑产溯源安全工程师
  • Spring AOP_2
  • CPA全国青少年编程能力等级测评试卷及答案 Python编程(一级)
  • 【代码详解】Triplane Meets Gaussian Splatting中triplane部分解析
  • 【代码随想录|454.四数相加、383.赎金信、15.三数之和、18.四数之和】
  • 模拟-6.N字形变换-力扣(LeetCode)
  • GPIO交换矩阵和IO_MUX