第六章:主从复制

深入了解 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 集群模式。

👉 Redis Cluster 集群