Redis 主从复制详解:原理、配置与主从切换实战

Redis 主从复制详解:原理、配置与主从切换实战

在高并发场景下,单一 Redis 节点往往难以承受大量的读写请求。为了提高 Redis 的可用性和读写性能,主从复制(Master/Slave)架构成为了常用的解决方案。本文将详细介绍 Redis 主从复制的原理、配置方法以及主从切换的实战操作。

一、Redis 主从复制原理

Redis 主从复制是指将一台 Redis 服务器(主节点,Master)的数据复制到其他 Redis 服务器(从节点,Slave),数据复制是单向的,只能从主节点到从节点。

在实际应用中,通常使用一个 Master 节点处理写操作,多个 Slave 节点处理读操作,同时可以选择一个 Slave 节点进行数据备份,这样能最大程度发挥 Redis 的性能。需要注意的是,Master 和 Slave 的数据并非实时同步,但最终会达到一致,这就是最终一致性。

1.1 全量同步

全量同步是指从节点第一次连接主节点时,完整复制主节点所有数据的过程,具体步骤如下:

  1. Slave 发送 Sync 命令到 Master
  2. Master 启动后台进程,将 Redis 中的数据快照保存到文件中
  3. Master 将保存数据快照期间接收到的写命令缓存起来
  4. Master 完成文件写入后,将该文件发送给 Slave
  5. Slave 使用新接收的 RDB 或 AOF 文件替换旧文件

1.2 增量同步

增量同步用于网络中断等情况后的复制,只将中断期间主节点执行的写命令发送给从节点,比全量复制更高效。其实现依赖于三个重要概念:

(1)复制偏移量

主节点和从节点分别维护一个复制偏移量(offset),代表主节点向从节点传递的字节数。主节点每次向从节点传播 N 个字节数据时,自身 offset 增加 N;从节点每次收到 N 个字节数据时,自身 offset 也增加 N。通过比较两者的 offset,可以判断主从节点的数据是否一致。

(2)复制积压缓冲区

由主节点维护的固定长度 FIFO 队列,默认大小 1MB,当主节点有从节点时创建,用于备份主节点最近发送给从节点的数据。

在命令传播阶段,主节点会将写命令同时发送给从节点和复制积压缓冲区。由于缓冲区长度固定,当主从节点 offset 差距超过缓冲区长度时,将无法执行增量复制,只能执行全量复制。

可以通过配置repl-backlog-size增大缓冲区大小,计算公式参考:网络中断平均时间 × 主节点每秒产生的写命令字节数 × 2(保险起见)。

(3)服务器运行 ID(runid)

每个 Redis 节点启动时会生成一个唯一的 40 位十六进制随机 ID,用于唯一识别节点。主从初次复制时,主节点将自己的 runid 发送给从节点,从节点保存该 runid。

当断线重连时,从节点将保存的 runid 发送给主节点:

  • 如果 runid 相同,说明之前同步过,尝试进行增量复制
  • 如果 runid 不同,说明从节点之前同步的不是当前主节点,只能进行全量复制

二、配置主从同步

2.1 环境说明

主机名 IP 地址 角色
redis-master 192.168.2.20/24 master
redis-slave1 192.168.2.21/24 slave1
redis-slave2 192.168.2.22/24 slave2

2.2 配置 Master 节点

  • 关闭防火墙和 SELinux
bash 复制代码
[root@redis-master ~]# systemctl disable --now firewalld
[root@redis-master ~]# setenforce 0
  • 安装 Redis 并修改配置文件
bash 复制代码
[root@redis-master ~]# yum install redis -y
[root@redis-master ~]# vim /etc/redis/redis.conf
bind 0.0.0.0
protected-mode no
daemonize no  #非后台运行
  • 启动 Redis 并验证角色
bash 复制代码
[root@redis-master ~]# systemctl start redis
[root@redis-master ~]# redis-cli -p 6379
127.0.0.1:6379> info replication
role:master #当前角色为主
connected_slaves:0
master_failover_state:no-failover
master_replid:b765b9a92e508c2b912f56d2f496e34d1431818f
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

2.3 配置 Slave 节点

以 slave1 为例,slave2 配置类似:

  1. 关闭防火墙和 SELinux(同上)
  2. 安装 Redis 并修改配置文件
bash 复制代码
[root@redis-slave1 ~]# yum install redis -y
[root@redis-slave1 ~]# vim /etc/redis/redis.conf
bind 0.0.0.0
protected-mode no
daemonize no  
replicaof 192.168.2.20 6379  #指定主节点地址和端口
  1. 临时配置主节点(无需重启 Redis,但重启后失效)
bash 复制代码
[root@redis-slave1 ~]# redis-cli -p 6379
127.0.0.1:6379> REPLICAOF 192.168.2.20 6379  #新版本
# 旧版本使用:slaveof 192.168.2.20 6379
OK
  1. 验证从节点配置
bash 复制代码
127.0.0.1:6379> info replication
# Replication
role:slave  #当前从的角色调整为slave
master_host:192.168.2.20
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_read_repl_offset:28
slave_repl_offset:28
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:80538ce104caeda1fc19a6e0f5292612e1805974
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:28
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:28

2.4 验证主从同步

  1. 在主节点添加数据
bash 复制代码
[root@redis-master ~]# redis-cli
127.0.0.1:6379> set master 192.168.2.20
OK
  1. 在从节点查看数据
bash 复制代码
[root@redis-slave1 ~]# redis-cli -p 6379
127.0.0.1:6379> get master
"192.168.2.20"
  1. 在主节点查看从节点连接情况
bash 复制代码
# 可以看到connected_slaves:2及两个从节点的信息
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.2.21,port=6379,state=online,offset=4421,lag=0
slave1:ip=192.168.2.22,port=6379,state=online,offset=4421,lag=0
master_failover_state:no-failover
master_replid:80538ce104caeda1fc19a6e0f5292612e1805974
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:4421
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:4421

三、主从切换实战

当主节点宕机后,需要将从节点提升为主节点,以保证服务继续运行。

3.1 模拟主节点宕机

bash 复制代码
[root@redis-master ~]# systemctl stop redis

3.2 将 slave1 提升为主节点

bash 复制代码
[root@redis-slave1 ~]# redis-cli
127.0.0.1:6379> REPLICAOF no one  #新版本
# 旧版本使用:slaveof no one
OK

# 验证角色已变为master
127.0.0.1:6379> info replication
# 可以看到role:master

3.3 将 slave2 重新指向新的主节点

bash 复制代码
[root@redis-slave2 ~]# redis-cli
127.0.0.1:6379> replicaof 192.168.2.21 6379  #新版本
# 旧版本使用:slaveof 192.168.2.21 6379
OK

# 验证数据已同步
127.0.0.1:6379> get master
"192.168.2.21"  #已更新为新主节点的数据

总结

Redis 主从复制通过将写操作集中在主节点,读操作分散到从节点,有效提高了 Redis 的并发处理能力。全量复制和增量复制机制保证了主从节点数据的最终一致性,而主从切换功能则提高了系统的可用性。

在实际生产环境中,除了手动进行主从切换,还可以结合 Redis Sentinel(哨兵)实现自动故障转移,进一步提高系统的稳定性和可靠性

相关推荐
程序员的世界你不懂4 小时前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
自学也学好编程4 小时前
【数据库】Redis详解:内存数据库与缓存之王
数据库·redis
JAVA不会写5 小时前
在Mybatis plus中如何使用自定义Sql
数据库·sql
IT 小阿姨(数据库)5 小时前
PgSQL监控死元组和自动清理状态的SQL语句执行报错ERROR: division by zero原因分析和解决方法
linux·运维·数据库·sql·postgresql·centos
ChinaRainbowSea5 小时前
7. LangChain4j + 记忆缓存详细说明
java·数据库·redis·后端·缓存·langchain·ai编程
猫头虎-前端技术6 小时前
浏览器兼容性问题全解:CSS 前缀、Grid/Flex 布局兼容方案与跨浏览器调试技巧
前端·css·node.js·bootstrap·ecmascript·css3·媒体
小马学嵌入式~7 小时前
嵌入式 SQLite 数据库开发笔记
linux·c语言·数据库·笔记·sql·学习·sqlite
Java小白程序员7 小时前
MyBatis基础到高级实践:全方位指南(中)
数据库·mybatis
Monly217 小时前
人大金仓:merge sql error, dbType null, druid-1.2.20
数据库·sql