Redis主从模式是一种基本的高可用配置,由一个主节点(Master)和一个或多个从节点(Replica/Slave)组成。主节点处理写操作并将数据变更同步到从节点,从节点主要处理读操作。
主从模式特点
- 数据冗余,提高数据安全性
- 读写分离,提高读取性能
- 主节点仍存在单点故障风险
- 不提供自动故障转移功能
主从模式架构

主从复制工作原理

主从复制是怎么工作的
Redis怎么管理复制状态
简单来说,Redis需要记住很多信息来保证主从复制正常工作。就像你要记住朋友的电话号码一样,Redis也要记住主节点在哪里、连接状态如何等等。
主要记录的信息
连接相关的信息:
masterhost
和masterport
:主节点的地址,就像朋友的家庭住址master
:跟主节点的连接,可以理解为一条电话线repl_state
:当前在做什么,比如正在连接、正在同步数据等
数据传输相关的信息:
repl_transfer_size
:要传输的数据总量,就像下载文件时显示的总大小repl_transfer_read
:已经传输了多少,类似下载进度repl_transfer_fd
:传输数据用的通道
复制积压缓冲区: 这个很重要!可以把它想象成一个录音机,主节点把所有的操作都"录"下来。如果从节点断开了一会儿,重连后可以"回放"这段时间错过的操作,而不用重新传输所有数据。
复制ID和偏移量:
replid
:给每次复制起个名字,就像给聊天记录起个标题master_repl_offset
:记录处理到第几条命令了,类似聊天记录的行号- 这样就能知道从哪里开始补数据
从节点是怎么连接主节点的
从节点连接主节点就像两个人第一次见面,需要经过好几个步骤才能开始正常交流:
第一步:建立连接
- 准备连接:从节点决定要连接主节点了
- 正在连接:就像拨电话号码,等待接通
- 测试连接:发个"喂"(PING)看看能不能听到
第二步:身份验证
- 发送密码:如果主节点设了密码,就要先验证身份
- 等待确认:主节点检查密码对不对
第三步:互相介绍
- 告诉端口:从节点说"我在这个端口监听"
- 告诉IP:从节点说"我的IP地址是这个"
- 说明能力:从节点说"我支持这些功能"
第四步:开始同步
- 请求同步:从节点说"请给我数据"
- 等待回复:主节点决定怎么给数据
- 传输数据:开始接收数据或命令
- 完成连接:一切就绪,开始正常工作
这样设计的好处:
- 不容易出错:每一步都很清楚,出问题容易发现
- 容易监控:可以知道卡在哪一步了
- 容易扩展:以后要加新功能很方便
主从复制的核心机制
主节点怎么处理同步请求
当从节点说"我要同步数据"时,主节点要做个重要决定:是给全部数据,还是只给缺失的部分?
处理流程很简单
1. 先看看是谁在请求 主节点会检查:这个从节点是不是已经在我的列表里了?避免重复处理。
2. 看看能不能只给一部分 如果从节点发的是PSYNC命令,主节点会想:
- 这个从节点之前跟我同步过吗?(检查复制ID)
- 它缺失的数据我还有备份吗?(检查积压缓冲区)
- 如果都满足,就只给缺失的部分
3. 不行就给全部 如果上面的条件不满足,那就只能:
- 把从节点加到等待列表
- 开始生成完整的数据快照(BGSAVE)
- 准备传输所有数据
部分重同步是个好东西
这个功能很厉害!想象一下,你在看电影时网络断了一会儿,重连后不用从头开始看,而是从断开的地方继续。
三个关键组件
1. 积压缓冲区(像个录音机)
- 主节点把所有操作都"录"下来,默认能录1MB的内容
- 是个圆形的录音带,录满了就覆盖最老的内容
- 每个操作都有个编号,方便找到位置
2. 复制ID(像个身份证)
- 每次开始复制都有个唯一的ID
- 主节点换了或重启了,ID就变了
- 还有个备用ID,用于特殊情况
3. 偏移量(像个进度条)
- 主节点记录发送了多少数据
- 从节点记录接收了多少数据
- 对比一下就知道缺了什么
判断能不能部分同步
主节点会按顺序检查:
-
身份证对不对:
- 从节点的复制ID跟我的一样吗?
- 或者跟我的备用ID一样吗?
- 不一样就得全量同步
-
缺失的数据还在不在:
- 从节点要的数据在我的"录音带"里吗?
- 太老的可能被覆盖了,太新的还没有
- 在范围内就能部分同步
-
开始补数据:
- 告诉从节点"可以继续"
- 把缺失的部分发过去
- 完成同步
命令是怎么传播的
主节点执行了写操作后,要告诉所有从节点"你们也这样做"。
传播过程
1. 格式化命令
- 把命令转换成标准格式
- 如果涉及不同数据库,先发个切换命令
- 同时写到"录音带"里备份
2. 选择接收者 不是所有从节点都能立即接收:
- 正在等待数据的从节点先不发
- 只给已经在线的从节点发
- 断开的从节点重连后会补上
3. 异步发送
- 主节点不等从节点回复就继续干活
- 从节点慢慢处理接收到的命令
- 如果从节点太慢,可能会被踢掉
一些优化技巧
1. 打包发送 把多个小命令打包成一个大包发送,减少网络开销。
2. 独立缓冲区 每个从节点都有自己的缓冲区,慢的不会影响快的。
3. 流量控制 如果从节点的缓冲区太满,主节点会断开连接保护自己。
主从模式启动流程

Redis怎么维护主从复制
定时检查很重要
Redis每秒都会做一次"体检",检查主从复制是不是健康。就像你每天要量体温一样。
主要检查什么
1. 连接还好吗
- 握手会不会卡住:如果从节点连接时卡住了,就重新来
- 数据传输会不会断:如果传输RDB文件时太久没动静,就断开重连
- 心跳还在跳吗:如果主从节点太久没说话,就断开连接
2. 从节点管理
- 从节点还活着吗:检查从节点有没有按时发心跳
- 更新状态信息:记录从节点的最新状态
- 清理坏掉的连接:把超时或出问题的从节点踢掉
3. 节省资源
- 没从节点时释放内存:如果没有从节点了,就把"录音带"删掉省内存
- 等等再开始传输:无盘复制时可以等一会儿,看看有没有更多从节点要连接
积压缓冲区的秘密
这个"录音带"设计得很巧妙,是部分重同步的核心。
它是怎么工作的
1. 基本设计
- 固定大小:默认1MB,就像一盘固定长度的录音带
- 圆形录音带:录满了就从头开始覆盖,永远在转圈
- 每个位置都有编号:方便找到具体位置
2. 重要的几个指标
repl_backlog_size
:录音带总长度repl_backlog_idx
:现在录到哪里了repl_backlog_off
:最老的数据在哪里repl_backlog_histlen
:有效数据有多长
3. 怎么写入数据 主节点每次执行写操作时:
- 把命令转换成标准格式
- 写到录音带的当前位置
- 移动写入位置
- 如果录音带满了,就覆盖最老的数据
怎么读取数据
当从节点要补数据时:
1. 先检查能不能补
- 要的数据还在录音带上吗?
- 太老的可能被覆盖了,太新的还没录
- 不在范围内就没法部分同步
2. 找到数据位置
- 根据从节点要的位置,在录音带上找到对应地方
- 因为是圆形的,可能要从两段读取
3. 发送数据
- 从找到的位置开始,一直发到最新位置
- 按照标准格式发给从节点
怎么优化使用
1. 大小要合适
- 太小:经常部分同步失败,要全量同步
- 太大:浪费内存,特别是没从节点时
- 建议:根据网络断开时间和写入速度来算
2. 生命周期管理
- 有从节点时保持录音带
- 没从节点时可以设置超时自动删除
- 有新从节点时重新创建
3. 监控内存使用
- 录音带占用的内存算在Redis总内存里
- 可以用INFO命令查看使用情况
- 内存紧张时考虑调小一点
主从模式交互时序图

从节点怎么连接主节点
连接过程就像交朋友
从节点连接主节点就像两个人第一次见面交朋友,需要好几个步骤。
先建立联系
1. 拨通电话
- 从节点先尝试连接主节点,就像拨电话号码
- 用的是非阻塞方式,不会卡住Redis
- 连不上就记录错误,过会儿再试
2. 记录连接信息 连接过程中要记住几个重要信息:
repl_transfer_s
:这条连接线repl_transfer_lastio
:最后一次通话时间repl_state
:现在在做什么
握手过程很详细
就像两个人见面要互相介绍一样,从节点和主节点也要经过详细的握手。
先验证身份
1. 打个招呼 (PING测试)
- 从节点先发个"喂"(PING)
- 主节点回个"嗯"(PONG)表示听到了
- 如果主节点说需要密码,那就要验证身份
2. 验证身份 (AUTH)
- 如果主节点设了密码,从节点就要报密码
- 主节点检查密码对不对
- 密码错了就断开连接
互相介绍信息
3. 告诉端口号 从节点说:"我在这个端口监听"
- 主节点记下这个信息
- 以后可能会用到(比如监控)
- 支持NAT环境的特殊配置
4. 告诉IP地址 从节点说:"我的IP地址是这个"
- 主节点记录完整的网络地址
- 用于管理和监控从节点
- 支持复杂网络环境
5. 说明自己的能力 从节点说:"我支持这些功能"
eof
:我支持无盘复制psync2
:我支持更强的部分重同步- 主节点根据这些能力选择最好的策略
开始请求数据
6. 发送同步请求 (PSYNC) 从节点说:"请给我数据"
- 第一次连接:
PSYNC ? -1
(我要全部数据) - 重新连接:
PSYNC <replid> <offset>
(我要从这里开始的数据)
7. 等待主节点回复 主节点会回复:
+FULLRESYNC
:你需要全部数据+CONTINUE
:我给你缺失的部分就行+NOMASTERLINK
:我也是从节点,没法给你数据
接收RDB数据
如果需要全量同步,从节点要接收主节点的完整数据。
怎么接收文件
1. 创建临时文件
- 从节点创建一个临时文件来接收数据
- 文件名包含时间戳,避免冲突
- 接收完成后改名为正式文件
2. 流式接收
- 边接收边写到磁盘,不占用太多内存
- 记录接收进度,可以看到传输状态
- 支持传输过程的监控
3. 检查完整性
- 通过文件大小检查是否传输完整
- 出错了可以重新传输
- 失败时清理临时文件
怎么加载数据
1. 清空旧数据 加载新数据前要:
- 把现有的所有数据都删掉
- 重置统计信息
- 通知其他模块数据要变了
2. 加载RDB文件
- 用专门的方式加载RDB文件
- 加载时不让客户端访问
- 加载失败就取消这次同步
3. 完成连接 数据加载完成后:
- 创建跟主节点的正式连接
- 状态变为已连接
- 开始接收实时命令
出错了怎么办
1. 超时处理
- 每个步骤都有时间限制
- 超时了就重新开始
- 记录详细日志方便排查
2. 网络错误
- 网络断了立即停止握手
- 断开后会自动重试
- 重试间隔会逐渐增加
3. 状态恢复
- 失败后清理所有中间状态
- 重置到初始状态
- 释放占用的资源
主从模式的优缺点
优点
- 读写分离:提高系统读取性能
- 数据冗余:多个副本提高数据安全性
- 高可用基础:为Sentinel和集群模式提供基础
缺点
- 主节点单点故障:主节点故障时无法自动切换
- 写性能瓶颈:所有写操作都集中在主节点
- 全量复制开销:新从节点加入或断开重连时可能需要全量复制
- 复制延迟:从节点数据可能落后于主节点
两种数据传输方式
Redis有两种传输RDB数据的方式,就像快递有陆运和空运一样。
磁盘复制:传统但稳定
这是Redis最早的传输方式,就像先把东西打包好,再寄快递。
怎么工作的
1. 先生成文件 需要全量同步时:
- 主节点开个后台进程生成RDB文件
- 就像拍照一样,把当前数据状态保存下来
- 主进程继续干活,不会被影响
2. 准备传输 文件生成好后:
- 主节点打开文件准备读取
- 给每个等待的从节点准备传输
- 设置从节点状态为"正在接收数据"
3. 开始传输
- 主节点一块一块地读取文件
- 通过网络发送给从节点
- 从节点接收后写到临时文件
优缺点很明显
好处:
- 很稳定:用了很多年,很可靠
- 省内存:主进程不用占用太多内存
- 能复用:一个文件可以发给多个从节点
坏处:
- 磁盘忙:要额外读写磁盘
- 占空间:需要额外的磁盘空间
- 有延迟:要等文件生成完才能传输
无盘复制:新技术更快
这是新功能,就像直接从工厂发货,不用经过仓库。
工作原理
1. 直接传输
- 子进程直接把数据写到网络连接
- 不用经过磁盘文件这个中间步骤
- 边生成边传输,更快
2. 一对多传输
- 可以同时给多个从节点发送
- 用特殊的技术同时写多个连接
- 一次生成,多个从节点都能收到
3. 等等再开始
- 可以等一会儿看看有没有更多从节点要连接
- 这样可以一起传输,更高效
- 减少主节点的负担
什么时候用哪种
适合无盘复制:
- 磁盘很慢的时候
- 磁盘空间不够的时候
- 网络很快的时候
- 从节点很多的时候
不适合无盘复制:
- 网络不稳定的时候
- 从节点连接时间差很大
- 对可靠性要求特别高的时候
Redis怎么选择传输方式
Redis会自动选择用哪种方式:
1. 看配置
repl-diskless-sync
:是否开启无盘复制repl-diskless-sync-delay
:无盘复制等待时间
2. 看从节点能力
- 从节点必须支持EOF功能才能用无盘复制
- 通过握手时的能力协商确定
3. 自动决定
- 如果配置允许且从节点支持,就用无盘复制
- 否则用传统的磁盘复制
心跳机制保持联系
主从节点要定期"通电话",确保彼此都还在线。
ACK命令的作用
1. 从节点报告进度 从节点定期发送ACK:
- 格式:
REPLCONF ACK <offset>
- 告诉主节点自己处理到哪里了
- 主节点用这个跟踪同步进度
2. 主节点处理ACK 主节点收到ACK后:
- 更新从节点的最后联系时间
- 记录从节点的进度
- 计算从节点的延迟情况
心跳检测
1. 超时检测
- 主节点检查从节点多久没发ACK了
- 超时就断开连接
- 防止僵尸连接浪费资源
2. 延迟监控
- 通过ACK的进度计算延迟
- 延迟太大的从节点可能有问题
- 用于负载均衡和故障检测
REPLCONF命令很有用
这个命令有很多功能:
1. 交换信息
listening-port
:从节点的端口ip-address
:从节点的IPcapa
:从节点支持的功能
2. 状态同步
ack
:从节点确认收到的数据量getack
:主节点要求从节点发ACK
3. 能力协商
eof
:支持无盘复制psync2
:支持增强的部分重同步
这些机制一起工作,让Redis主从复制既可靠又高效。
主从模式配置示例
主节点配置 (redis-master.conf)
bash
port 6379
bind 0.0.0.0
daemonize yes
pidfile /var/run/redis_6379.pid
logfile /var/log/redis/redis_6379.log
dir /var/lib/redis
dbfilename dump_6379.rdb
appendonly yes
appendfilename "appendonly_6379.aof"
从节点配置 (redis-replica.conf)
bash
port 6380
bind 0.0.0.0
daemonize yes
pidfile /var/run/redis_6380.pid
logfile /var/log/redis/redis_6380.log
dir /var/lib/redis
dbfilename dump_6380.rdb
appendonly yes
appendfilename "appendonly_6380.aof"
replicaof 127.0.0.1 6379 # 指定主节点
replica-read-only yes # 从节点只读
主从复制架构总结
核心组件交互关系
Redis主从复制涉及多个核心组件的协调工作,形成了一个完整的数据同步生态系统。
主要组件说明
1. 复制管理器 负责整个复制过程的协调和管理:
- 维护从节点列表和状态信息
- 处理复制命令和状态转换
- 管理复制积压缓冲区的生命周期
2. 连接管理器 处理主从节点之间的网络连接:
- 建立和维护TCP连接
- 处理连接超时和错误恢复
- 管理连接的读写事件
3. 数据传输器 负责实际的数据传输工作:
- RDB文件的生成和传输
- 实时命令的传播
- 传输进度的监控和控制
4. 状态同步器 维护主从节点的状态一致性:
- 复制偏移量的同步
- 心跳检测和ACK确认
- 故障检测和恢复
Redis主从复制通过精心设计的架构和算法,在保证数据一致性的同时,实现了高性能和高可用性,为Redis的广泛应用奠定了坚实的基础。