第六章:主从复制
深入了解 Redis 的主从复制机制、配置方法和故障切换。
最后更新: 2024-01-15
页面目录
Redis 主从复制
主从复制是 Redis 实现高可用和数据冗余的基础机制。本章详细介绍复制的工作原理、配置方法和运维实践。
复制概述
┌─────────────────────────────────────────────────────────────────┐
│ Redis 主从复制架构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ │
│ │ Master │ │
│ │ (主节点) │ │
│ │ 写操作 │ │
│ └────────┬────────┘ │
│ │ │
│ ┌──────────────────┼──────────────────┐ │
│ ↓ ↓ ↓ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ Replica 1 │ │ Replica 2 │ │ Replica 3 │ │
│ │ (从节点) │ │ (从节点) │ │ (从节点) │ │
│ │ 读操作 │ │ 读操作 │ │ 读操作 │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
复制的作用
| 作用 | 说明 |
|---|---|
| 数据冗余 | 实时备份数据,防范数据丢失 |
| 读写分离 | 从节点处理读请求,减轻主节点压力 |
| 故障恢复 | 主节点故障时,可手动升级从节点 |
| 地理分布 | 在不同机房部署,提高可用性 |
| 水平扩展 | 增加从节点提升读取能力 |
工作原理
复制流程
┌─────────────────────────────────────────────────────────────────┐
│ 复制流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 从节点 主节点 │
│ │ │ │
│ │ ── PSYNC ? ─────────────────►│ │
│ │ │ │
│ │ ◄── FULLRESYNC ─────────────│ 全量同步 │
│ │ │ │
│ │ ── RDB 传输 ─────────────────►│ │
│ │ │ │
│ │ ◄─ +更多命令 ─────────────────│ 命令传播 │
│ │ │ │
│ │ ◄─ +更多命令 ─────────────────│ │
│ │ │ │
│ │
└─────────────────────────────────────────────────────────────────┘
PSYNC 命令
Redis 使用 PSYNC 命令实现增量复制:
# 完整同步
PSYNC ? -1
# 增量同步
PSYNC <runid> <offset>
复制相关变量
| 变量 | 说明 |
|---|---|
| master_replid | 主节点 Run ID |
| master_repl_offset | 主节点复制偏移量 |
| second_repl_offset | 从节点已接收的最大偏移量 |
配置方法
方式一:配置文件配置
# 主节点配置(redis.conf)
bind 0.0.0.0
port 6379
requirepass your_password
# 从节点配置
replicaof 192.168.1.100 6379
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-ping-replica-period 10
repl-timeout 60
repl-backlog-size 64mb
repl-backlog-ttl 3600
方式二:命令行配置
# 配置从节点
redis-cli replicaof 192.168.1.100 6379
# 取消复制(变为主节点)
redis-cli replicaof no one
方式三:Docker 配置
# docker-compose.yml
version: '3.8'
services:
master:
image: redis:7-alpine
container_name: redis-master
ports:
- "6379:6379"
command: redis-server --requirepass master_password
replica1:
image: redis:7-alpine
container_name: redis-replica1
ports:
- "6380:6379"
command: redis-server --replicaof redis-master 6379 --requirepass replica_password --masterauth master_password
replica2:
image: redis:7-alpine
container_name: redis-replica2
ports:
- "6381:6379"
command: redis-server --replicaof redis-master 6379 --requirepass replica_password --masterauth master_password
复制安全
主节点认证
# 主节点设置密码
requirepass master_password
# 从节点配置认证密码
masterauth master_password
# 从节点连接
redis-cli -h 192.168.1.100 -a master_password
读写分离配置
# 从节点只读
replica-read-only yes
# 从节点可写(不推荐)
replica-read-only no
复制状态
查看复制状态
# 查看主节点信息
INFO replication
# 查看从节点状态
INFO replication
# role:master
# connected_slaves:2
# slave0:ip=192.168.1.101,port=6379,state=online,offset=12345,lag=0
# slave1:ip=192.168.1.102,port=6379,state=online,offset=12345,lag=1
从节点查看主节点
# 查看主节点连接
INFO replication
# role:slave
# master_host:192.168.1.100
# master_port:6379
# master_link_status:up
# master_last_io_seconds_ago:1
# master_sync_offset:12345
查看所有从节点
# 主节点查看所有从节点
CLIENT LIST | grep addr
# 或使用 REPLCONF
REPLCONF LISTENING-PORT 6379
REPLCONF IP-ADDRESS 192.168.1.101
复制偏移量
数据同步原理
主节点 从节点
────────────────────────────────────────────
offset: 10000 offset: 9000
│ │
│ 发送 offset 10001-10000 │
│ ─────────────────────────►│
│ │
│ │ offset: 10001
增量同步
# 主节点记录所有写命令到复制积压缓冲区
# 配置复制积压缓冲区大小
repl-backlog-size 64mb
# 查看积压缓冲区
INFO replication
# repl_backlog_active:1
# repl_backlog_size:67108864
# repl_backlog_first_byte_offset:1
# repl_backlog_histlen:67108864
故障处理
主节点故障
# 1. 检查从节点状态
redis-cli -h replica1 INFO replication
# 2. 停止从节点复制
redis-cli -h replica1 REPLICAOF NO ONE
# 3. 将其他从节点指向新的主节点
redis-cli -h replica2 REPLICAOF new_master_ip 6379
# 4. 如果主节点有密码
redis-cli -h new_master CONFIG SET masterauth password
网络中断处理
# 网络恢复后自动重连
# Redis 会尝试增量同步
# 强制全量同步
redis-cli REPLICAOF master_ip 6379
数据不一致处理
# 从节点执行全量同步
redis-cli DEBUG RELOAD
# 或重新复制
redis-cli REPLICAOF NO ONE
redis-cli REPLICAOF master_ip 6379
哨兵模式(自动故障转移)
┌─────────────────────────────────────────────────────────────────┐
│ 哨兵模式架构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Sentinel 集群 │ │
│ │ (Sentinel 1) (Sentinel 2) (Sentinel 3) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Master │ │
│ │ (主节点) │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────┴────────┐ │
│ │ Replica │ │
│ │ (从节点) │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
详见下一章 哨兵模式
只读副本
用途
- 读写分离
- 数据分析
- 报表生成
- 异地访问
配置
replica-read-only yes
注意事项
# 从节点写入会导致数据不一致
redis-cli -h replica SET key value # 会被拒绝(replica-read-only yes)
# 可以临时启用写入
redis-cli CONFIG SET replica-read-only no
复制拓扑
一主一从
Master → Replica
适用场景:小规模部署、简单备份
一主多从
→ Replica1
/
Master ───→ Replica2
\
→ Replica3
适用场景:读写分离、读取压力大的场景
链式复制
Master → Replica1 → Replica2
适用场景:多级复制,减少主节点压力
树形复制
Master
/ \
Replica1 Replica2
|
Replica3
适用场景:大规模部署
复制优化
配置优化
# 启用无盘复制(网络传输更快)
repl-diskless-sync yes
repl-diskless-sync-delay 5
# 调整超时时间
repl-ping-replica-period 10
repl-timeout 60
# 复制积压缓冲区
repl-backlog-size 128mb
repl-backlog-ttl 7200
网络优化
- 使用千兆网络
- 减少网络延迟
- 主从同地域部署
常见问题
1. 从节点一直连接不上
# 检查网络连通性
ping master_ip
# 检查密码
redis-cli -h master INFO replication | grep masterauth
# 检查端口
nc -zv master_ip 6379
2. 复制积压缓冲区不足
# 增加缓冲区大小
repl-backlog-size 256mb
3. 从节点数据不一致
# 重置从节点
redis-cli REPLICAOF NO ONE
redis-cli FLUSHDB
redis-cli REPLICAOF master_ip 6379
4. 复制延迟
# 监控延迟
redis-cli INFO replication | grep lag
# lag=0 表示正常
# lag>0 表示有延迟
下一步
接下来让我们学习 Redis Cluster 集群模式。