8.4.1 复制机制与读写分离设计

复制机制与读写分离设计#

Redis 复制采用异步主从架构,主节点负责写入并将命令传播至从节点。从节点可用于读请求分担,提高吞吐与可用性。本节给出复制流程、读写分离设计、安装配置、常用命令、排错与练习。

原理草图:主从复制与读写分离

文章图片

复制机制关键流程
- 建立复制链路:从节点向主节点发起 PSYNC,若历史数据可用则部分重同步,否则进行全量同步。
- 全量同步:主节点生成 RDB 快照并发送给从节点;同步完成后进入命令传播阶段。
- 增量同步:主节点将写命令追加至复制积压缓冲区,从节点通过偏移量追赶。
- 心跳与状态:主从维持 REPLCONF ACK 心跳,记录复制偏移与延迟。

安装与基础配置示例(单机两实例)

# 1) 安装 Redis(以 Debian/Ubuntu 为例)
sudo apt-get update
sudo apt-get install -y redis-server

# 2) 准备主从配置目录
sudo mkdir -p /etc/redis/master /etc/redis/slave
sudo cp /etc/redis/redis.conf /etc/redis/master/redis.conf
sudo cp /etc/redis/redis.conf /etc/redis/slave/redis.conf

# 3) 修改主节点配置
sudo sed -i 's/^port .*/port 6379/' /etc/redis/master/redis.conf
sudo sed -i 's/^# requirepass.*/requirepass "pass123"/' /etc/redis/master/redis.conf
sudo sed -i 's/^# masterauth.*/masterauth "pass123"/' /etc/redis/master/redis.conf
sudo sed -i 's/^# repl-backlog-size.*/repl-backlog-size 64mb/' /etc/redis/master/redis.conf
sudo sed -i 's/^# repl-diskless-sync.*/repl-diskless-sync yes/' /etc/redis/master/redis.conf

# 4) 修改从节点配置
sudo sed -i 's/^port .*/port 6380/' /etc/redis/slave/redis.conf
sudo sed -i 's/^# requirepass.*/requirepass "pass123"/' /etc/redis/slave/redis.conf
sudo sed -i 's/^# masterauth.*/masterauth "pass123"/' /etc/redis/slave/redis.conf
sudo sed -i 's/^# replicaof.*/replicaof 127.0.0.1 6379/' /etc/redis/slave/redis.conf

# 5) 启动两个实例
redis-server /etc/redis/master/redis.conf
redis-server /etc/redis/slave/redis.conf

# 6) 验证复制状态
redis-cli -p 6379 -a pass123 INFO replication
redis-cli -p 6380 -a pass123 INFO replication

关键命令与输出解读

# 查看主从复制状态
redis-cli -p 6379 -a pass123 INFO replication
# 关注: role:master, connected_slaves, master_repl_offset

# 从节点查看复制偏移
redis-cli -p 6380 -a pass123 INFO replication
# 关注: role:slave, master_link_status:up, slave_repl_offset

# 测试写入与读写分离
redis-cli -p 6379 -a pass123 SET order:1 "created"
redis-cli -p 6380 -a pass123 GET order:1

读写分离设计要点(含策略示例)
- 业务层路由:写请求固定打到主节点,读请求分发至从节点;需支持主从变更后的动态刷新。
- 一致性策略:读从可能存在延迟,关键读需走主或引入读后写一致性策略。

# 示例:写后短时间内强制读主(伪代码逻辑)
# 写成功后在 1~2 秒内读主,超过则读从
  • 容量规划:读请求占比高时可增加从节点;注意主节点带宽与复制开销。
  • 故障与降级:从节点延迟过大或不可用时自动回退读主。

复制参数与优化建议(带解释)

# /etc/redis/master/redis.conf
repl-backlog-size 64mb          # 复制积压缓冲区,避免频繁全量同步
client-output-buffer-limit slave 256mb 64mb 60
# 从节点消费慢时限制输出缓存,避免主节点内存被占满

repl-diskless-sync yes           # 无盘复制,减少磁盘IO
min-replicas-to-write 1          # 至少有1个从节点可用才允许写
min-replicas-max-lag 10          # 从节点最大延迟阈值(秒)

排错与故障处理

# 1) 复制断开或重连频繁
redis-cli -p 6380 -a pass123 INFO replication | grep -E "master_link_status|master_last_io_seconds_ago"

# 2) 复制积压不足导致频繁全量同步
redis-cli -p 6379 -a pass123 INFO replication | grep backlog

# 3) 查看主节点慢命令
redis-cli -p 6379 -a pass123 SLOWLOG GET 10

# 4) 从节点延迟过高
redis-cli -p 6380 -a pass123 INFO replication | grep lag

# 5) 临时切换从节点为主(演练用)
redis-cli -p 6380 -a pass123 REPLICAOF NO ONE
# 恢复为从
redis-cli -p 6380 -a pass123 REPLICAOF 127.0.0.1 6379

读写分离落地示例:应用层主从路由(伪配置)

# app.conf(示意)
redis.master=10.0.0.10:6379
redis.slaves=10.0.0.11:6379,10.0.0.12:6379
redis.read.preference=slave    # 优先读从
redis.read.fallback=master     # 从不可用读主
redis.read.after.write.ms=1500 # 写后1.5s强制读主

练习
1. 使用两实例完成主从复制,写入 1000 条数据,验证从节点读取一致性。
2. 人为降低从节点性能(如 DEBUG SLEEP 1),观察 lag 与复制偏移变化。
3. 调整 repl-backlog-size 为 8mb 与 64mb,模拟网络抖动断连,比较重同步行为。
4. 启用 min-replicas-to-write 1,断开从节点,验证主节点写入被限制的现象。