📝本文首发于 栏轩·阁
欢迎访问阅读原文,获取更好的阅读体验。
什么是主从复制?
主从复制(Master-Slave Replication)是 Redis 高可用的基石。一个主库(Master)负责写入,多个从库(Replica)实时同步主库数据并提供读服务。
主要作用:
- 读写分离:主库写,从库读,分摊读压力
- 数据热备份:从库拥有主库的完整副本,主库宕机时数据不丢
- 高可用基础:配合哨兵(Sentinel)可实现自动故障转移
环境准备
- 操作系统:WSL2(Windows Subsystem for Linux)
- 容器环境:Docker + Docker Compose
目录结构与配置文件
准备挂载的数据卷
mkdir-predis-master-slave/{config,data/master,data/replica1,data/replica2}cdredis-master-slave主库配置(config/master.conf)
# 允许所有IP连接(Docker容器间通信必须)bind0.0.0.0# 监听端口port6379# 开启AOF持久化(便于观察数据落地)appendonlyyes# 规定日志级别,方便查错loglevel notice# 设定密码(为了安全,但主从都必须配一致;这里先留空方便入门)# requirepass 123456# 数据库数量保持默认databases16从库1配置(config/replica1.conf)
bind0.0.0.0 port6380appendonlyyesloglevel notice# ****** 核心主从指令 ******# 声明我跟随谁(注意:这里填的是Docker Compose里的服务名 "master",而不是IP!)replicaof master6379# 如果主库有密码,需开启下面这行(目前没设密码,注释掉)# masterauth 123456从库2配置(config/replica2.conf)
bind0.0.0.0 port6381appendonlyyesloglevel notice# 同样跟随主库replicaof master6379Docker Compose编排
使用 Docker Compose 将三个 Redis 实例编排在同一个自定义网络中,通过服务名互相通信。
version:'3.8'services:# ---------- 主节点 ----------master:image:redis:7.2.4container_name:redis-masterrestart:alwaysports:-"6379:6379"volumes:-./config/master.conf:/usr/local/etc/redis/redis.conf-./data/master:/datacommand:redis-server /usr/local/etc/redis/redis.confnetworks:-redis-net# ---------- 从节点 1 ----------replica1:image:redis:7.2.4container_name:redis-replica-1restart:alwaysports:-"6380:6380"volumes:-./config/replica1.conf:/usr/local/etc/redis/redis.conf-./data/replica1:/datacommand:redis-server /usr/local/etc/redis/redis.confdepends_on:-masternetworks:-redis-net# ---------- 从节点 2 ----------replica2:image:redis:7.2.4container_name:redis-replica-2restart:alwaysports:-"6381:6381"volumes:-./config/replica2.conf:/usr/local/etc/redis/redis.conf-./data/replica2:/datacommand:redis-server /usr/local/etc/redis/redis.confdepends_on:-masternetworks:-redis-netnetworks:redis-net:driver:bridge启动集群
docker-composeup-d验证主从状态
查看主库状态
进入 master 容器并执行INFO replication:
redis-cli-p6379INFO replication输出如下即表示两个从库已成功连接:
# Replication role:master connected_slaves:2 slave0:ip=172.23.0.3,port=6381,state=online,offset=252,lag=1 slave1:ip=172.23.0.4,port=6380,state=online,offset=252,lag=1 master_failover_state:no-failover master_replid:7be3860eae78aa0c884546e40d444ba5708ca4c5 master_repl_offset:252 ...观察偏移量变化
master_repl_offset是主库当前的复制偏移量,表示已复制数据流的字节数。当主库写入数据时,该值会增长。
在主库写入数据:
setname"DockerMaster"INFO replication可以看到master_repl_offset从 252 增长到 499,从库同步该数据后也维持相同的偏移量。
验证从库数据
分别进入从库查看 name 字段,会发现数据已自动同步完成。
断线重连机制
操作场景:暂停一个从库容器 → 在主库写入新数据 → 重新启动该从库
重启后从库会增量同步而不是全量同步。这是因为 Redis 的主从复制采用带有部分重同步(PSYNC)的复制协议:
- 主库维护一个replication backlog(环形缓冲区,默认 1MB)
- 从库断线后重连时,将自己的
replid和偏移量发给主库 - 主库检查该偏移量是否仍在 backlog 中:
- 在 backlog 内→ 部分重同步,只发送断线期间缺失的数据
- 超出 backlog→ 全量重同步,重新发送 RDB 快照
这就是高可用的一大保障:短暂的网络抖动不会触发昂贵的全量重同步。
读写分离验证
主库负责写入,从库只读。在从库执行写入命令会被拒绝:
>settest"test"READONLY You can'twriteagainst areadonly replica.这一特性确保了集群数据的一致性流向:所有写入必须经过主库,从库只负责复制和应用。
总结
本文从零搭建了一套 Redis 一主两从集群,涵盖了:
| 知识点 | 说明 |
|---|---|
| 主从配置 | replicaof指令指定主库 |
| Docker Compose 编排 | 自定义网络、服务名通信、数据卷挂载 |
| 复制原理 | INFO replication中的关键指标解读 |
| 偏移量 | master_repl_offset标记复制进度 |
| 断线重连 | PSYNC 协议支持增量同步(部分重同步) |
| 读写分离 | 从库只读保障数据一致性 |
以上是 Redis 主从复制的完整动手实践。理解这部分后,可以继续学习**哨兵模式(Sentinel)实现自动故障转移,或集群模式(Cluster)**实现数据分片与高可用。