redis主从复制

本文详细介绍了Redis的主从复制配置,包括配置文件设置、如何加入主从结构、查看主从状态以及断开连接的方法。重点讲解了工作原理,如全量复制、部分复制、复制积压缓冲区、主节点运行ID、Psync命令和复制偏移量等关键概念,并描述了全量复制流程,强调从节点在同步前会清除原有数据。此外,还提到了心跳检测和缓冲大小的调整策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

1.机器故障。 我们部署到一台 Redis 服务器, 当发生机器故障时, 需要迁移到另外一台服务器并且要保证数据是同步的。 而数据是最重要的, 如果你不在乎, 基本上也就不会使用 Redis 了。
2.要实现分布式数据库的更大的存储容量和承受高并发访问量, 我们会将原来集中式数据库的数据分别存储到其他多个网络节点上。
3.Redis 为了解决这个单一节点的问题, 也会把数据复制多个副本部署到其他节点上进行复制, 实现 Redis的高可用, 实现对数据的冗余备份, 从而保证数据和服务 的高可用

配置文件

1.bind 0.0.0.0 //主允许其他地方进行请求,可改指定ip,主节点配置
slaveof <masterip> <masterport>    //从节点配置该主节点ip和端口号
masterauth auth ;//auth为主节点授权密码,从节点配置
requirepass  selfauth;//selfauth为自己定义当前授权密码,主节点配置
daemonize yes;//yes为后台启动,也可设置no
protected-mode no//保护模式关闭,可允许主从复制

其他配置

slave-read-only yes 
默认为只读 由于复制只能从主节点到从节点, 对于从节点的任何修改主节点都无法感知, 修改从节点会造成主从数据不一致。 因此没必要就不要动这个配置。

repl-disable-tcp-nodelay no
主从节点一般部署在不同机器上, 复制时的网络延迟就成为需要考虑的问题, Redis 为我们提供了repl-disable-tcp-nodelay参数用于控制是否关闭TCP NODELAY,默认关闭, 说明如下
* 当关闭时, 主节点产生的命令数据无论大小都会及时地发送给从节点, 这样主从之间延迟会变小, 但增加了网络带宽的消耗。 适用于主从之间的网络环境
良好的场景, 如同机架或同机房部署。
* 当开启时, 主节点会合并较小的TCP数据包从而节省带宽。 默认发送时间间隔取决于Linux的内核, - -般默认为40毫秒。 这种配置节省了带宽但增大主从
之间的延迟。 适用于主从网络环境复杂或带宽紧张的场景, 如跨机房部署。

# logfile "" redis日志
logfile "/redis/log/redis.log
# dir ./ 数据保存目录
dir "/redis/data"

如何加入

1. 在配置文件中加入 slaveof {masterHost} {masterPort} 随redis启动生效
2. 在redis-server启动命令后加入 --slaveof {masterHost} {masterPort} 生效
3. 直接使用命令: slaveof {masterHost} {masterPort}

查看主从信息

/bin/redis-cli 
#info replication

断开主从服务

slaveof no one

工作原理

1. 保存主节点(master)
 执行slaveof后从节点只保存主节点的地址信息便直接返回, 这时建立复制流程还没有开始
从节点保存主节点的ip:port, 状态是上线状态。 我们也可以参考redis的日志查看到复制信息,如果你开启了redis日志文件的话是可以看到redis的主从连接记录的信息
114:S 28 Apr 2020 18:57:33.459 * Connecting to MASTER 192.160.1.150:6379
114:S 28 Apr 2020 18:57:33.460 * MASTER <-> REPLICA sync started
114:S 28 Apr 2020 18:57:33.460 * Non blocking connect for SYNC fired the event.
114:S 28 Apr 2020 18:57:33.460 * Master replied to PING, replication can continue...
114:S 28 Apr 2020 18:57:33.461 * Trying a partial resynchronization (request 04aa4df6b19fbd0ea4aea54ca856ed91bf6c861c:17027).
114:S 28 Apr 2020 18:57:33.464 * Full resync from master: 0deae7db14cf069bf86408b8abecedf08952c0a8:0
114:S 28 Apr 2020 18:57:33.464 * Discarding previously cached master state.
114:S 28 Apr 2020 18:57:33.537 * MASTER <-> REPLICA sync: receiving 210 bytes from master
114:S 28 Apr 2020 18:57:33.537 * MASTER <-> REPLICA sync: Flushing old data
114:S 28 Apr 2020 18:57:33.537 * MASTER <-> REPLICA sync: Loading DB in memory
114:S 28 Apr 2020 18:57:33.537 * MASTER <-> REPLICA sync: Finished with success
114:S 28 Apr 2020 18:58:31.326 * REPLICAOF would result into synchronization with the master we are already connected with. No operation
performed.


2.从节点(slave) 内部通过每秒运行的定时任务维护复制相关逻辑, 当定时任务发现存在新的主节点后, 会尝试与节点该建立网络连接
从节点会建立一个 socket 套接字, 从节点建立了一个端口为 51234 的套接字, 专门用于接受主节点发送的复制命令。 从节点连接成功后打印如下日志
114:S 28 Apr 2020 18:57:33.460 * MASTER <-> REPLICA sync started
如果从节点无法建立连接, 定时任务会无限重试直到连接成功或者执行 slaveof no one 取消复制
关于连接失败, 可以在从节点执行 info replication 查看 master_link_down_since_seconds 指标, 它会记录与主节点连接失败的系统时间。 从节点连接主 节点失败
时也会每秒打印如下日志, 方便发现问题:Error condition on socket for SYNC: {socket_error_reason}

3.发送 ping 命令
接建立成功后从节点发送 ping 请求进行首次通信, ping 请求主要目的如下:
* 检测主从之间网络套接字是否可用。
* 检测主节点当前是否可接受处理命令。

如果发送ping 命令后, 从节点没有收到主节点的 pong 回复或者超时, 比如网络超时或者主节点正在阻塞无法响应命令, 从节点会断开复制连接, 下次定时任务会发起重连

4.权限验证
如果主节点设置了 requirepass 参数, 则需要密码验证, 从节点必须配置 masterauth 参数保证与主节点相同的密码才能通过验证; 如果验证失败复制将终 止, 从
节点重新发起复制流程。

5.同步数据集
主从复制连接正常通信后, 对于首次建立复制的场景, 主节点会把持有的数据全部发送给从节点, 这部分操作是耗时最长的步骤。

6.命令持续复制
当主节点把当前的数据同步给从节点后, 便完成了复制的建立流程。 接下来主节点会持续地把写命令发送给从节点, 保证主从数据一致性。
注意 主从在同步的过程当中, 会把原本的从节点的数据清空

数据同步
1.全量复制:从节点在载入主节点的数据之前要先将从节点老数据清除
2.部分复制

用于处理在主从复制中因网络闪断等原因造成的数据丢失场景, 当从节点再次连上主节点后, 如果(条件允许), 主节点会补发丢失数据给从节点。 因为补
发的数据远远小于全量数据, 可以有效避免全量复制的过高开销, 需要注意的是, 如果网络中断时间过长, 造成主节点没有能够完整地保存中断期间执行
的写命令, 则无法进行部分复制, 仍使用全量复制

从节点在接收到主节点发送的命令后, 也会累加记录自身的偏移量。 统计信息在 info relication 中的 slave_rep

3.复制积压缓冲区
在这里插入图片描述

复制积压缓冲区是保存在主节点上的一个固定长度的队列, 默认大小为1MB, 当主节点有连接的从节点(slave) 时被创建, 这时主节点(master) 响应写命令
时, 不但会把命令发送给从节点, 还会写入复制积压缓冲区

在命令传播阶段, 主节点除了将写命令发送给从节点, 还会发送一份给复制积压缓冲区, 作为写命令的备份; 除了存储写命令, 复制积压缓冲区中还存储了其中
的每个字节对应的复制偏移量(offset) 。 由于复制积压缓冲区定长且先进先出, 所以它保存的是主节点最近执行的写命令; 时间较早的写命令会被挤出缓冲区()。

4.主节点运行ID

每个Redis节点启动后都会动态分配一个40位的十六进制字符串作为运行ID。 运行ID的主要作用是用来唯一识别 Redis节点, 比如从节点保存主节点的运行ID识别自
己正在复制的是哪个主节点。 如果只使用ip+port的方式识别主节点, 那么主节点重启变更了整体数据集(如替换RDB/AOF文件), 从节点再基于偏移量复制数据将是
不安全的, 因此当运行ID变化后从节点将做全量复制。 可以运行info server命令查看当前节点的运行ID:
    run_id:868a5d49a276620b9f79788a1c894f07bd872f56
    
需要注意的是Redis关闭再启动, 运行的id会随之变化

5.Psync命令

从节点使用psync命令完成部分复制和全量复制功能 psync runid offset

1. 从节点(slave)发送psync命令给主节点, 参数runid是当前从节点保存的主节点运行id, 如果没有则默认值为 ? , 参数offset是当前从节点保存的复制偏移量, 如
果是第一次参与复制则默认值为-1
2. 主节点(master)根据psync参数和自身数据情况决定响应结果:
如果回复+FULLRESYNC {runid} {offset}, 那么从节点将全量复制流程。
如果回复+CONTINUE, 从节点将触发部分复制流程。
如果回复+ERR, 说明主节点版本低于Redis2.8

6.复制偏移量

参与复制的主从节点都会维护自身复制偏移量。 主节点(master) 在处理完写入命令后, 会把命令的字节长度做累加记录, 统计信息在 info relication 中的
master_repl_offset 指标中:
127.0.0.1:6379> info replication
# Replication
role:master
...
master_repl_offset:6104



从节点(slave) 每秒钟上报自身的复制偏移量给主节点, 因此主节点也会保存从节点的复制偏移量, 统计指标如下
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.160.1.140,port=6379,state=online,offset=6104,lag=1


从节点在接收到主节点发送的命令后, 也会累加记录自身的偏移量。 统计信息在 info relication 中的 slave_repl_offset 中
  1. 全量复制流程:注意: 从节点在载入主节点的数据之前要先将从节点老数据清除
1. 发送psync命令进行数据同步, 由于是第一次进行复制, 从节点没有复制偏移量和主节点的运行id, 所以发送psync ? -1
2. 主节点根据psync ? -1解析出当前为全量复制, 回复+FULLRESYNC响应(主机会向从机发送 runid 和 offset, 因为 slave 并没有对应的 offset, 所以是全量复制)
3. 从节点接收主节点的响应数据保存运行ID和偏移量offset(从机 slave 会保存 主机master 的基本信息 save masterInfo)
4. 主节点收到全量复制的命令后, 执行bgsave(异步执行) , 在后台生成RDB文件(快照) , 并使用一个缓冲区(称为复制缓冲区) 记录从现在开始执行 的所
有写命令
5. 主节点发送RDB文件给从节点, 从节点把接收到的RDB文件保存在本地并直接作为从节点的数据文件, 接收完RDB后从节点打印相关日志, 可以在日志中查看
主节点发送的数据量(主机send RDB 发送 RDB 文件给从机)
MASTER <-> REPLICA sync: Flushing old data
注意! 对于数据量较大的主节点, 比如生成的RDB文件超过6GB以上时要格外小心。 传输文件这一步操作非常耗时, 速度取决于主从节点之间网络带宽, 通过
细致分析Full resync和MASTER <-> SLAVE这两行日志的时间差, 可以算出RDB文件从创建到传输完毕消耗的总时间。 如果总时间超过repl-timeout所配置的值
(默认60秒), 从节点将放弃接受RDB文件并清理已经下载的临时文件, 导致全量复制失败;针对数据量较大的节点, 建议调大repl-timeout参数防止出现全量同步
数据超时;
例如对于千兆网卡的机器, 网卡带宽理论峰值大约每秒传输100MB,在不考虑其他进程消耗带宽的情况下, 6GB的RDB文件至少需要60秒传输时间, 默认配置
下, 极易出现主从数同步超时。
6. 对于从节点开始接收RDB快照到接收完成期间, 主节点仍然响应读写命令, 因此主节点会把这期间写命令数据保存在复制客户端缓冲区内, 当从节点加载完
RDB文件后, 主节点再把缓冲区内的数据发送给从节点, 保证主从之间数据致性。 (发送缓冲区数据)
7. 从节点接收顽主节点传送来的全部数据后会清空自身旧数据(刷新旧的数据, 从节点在载入主节点的数据之前要先将老数据清除)
8. 从节点清空数据后开始加载RDB文件, 对于较大的RDB文件, 这一步操作依然比较消耗时间, 可以通过计算日志之间的实际差来判断加载RDB的总消耗时间(加
载 RDB 文件将数据库状态更新至主节点执行bgsave时的数据库状态和缓冲区数据的加载。 )
114:S 28 Apr 2020 18:57:33.537 * MASTER <-> REPLICA sync: Loading DB in memory
114:S 28 Apr 2020 18:57:33.537 * MASTER <-> REPLICA sync: Finished with success

8.心跳

主节点在建立成功后会维护这长连接彼此发送心跳检测
1. 主从节点彼此都有心跳检测机制, 各自模拟成对方的客户端进行通信, 通过client list命令查看复制相关客户端信息, 主节点的连接状态为flags=M,从节点连接
状flags=S
2. 主节点默认每隔10秒对从节点发送ping命令, 判断从节点的存活性和连接状态。 可通过参数repl-ping-slave-period控制发送频率。
3. 从节点在主线程中每隔1秒发送replconf ack {offset} 命令, 给主节点上报自身当前的复制偏移量

9.缓冲大小调节

由于缓冲区长度固定且有限, 因此可以备份的写命令也有限, 当主从节点offset的差距过大超过缓冲区长度时, 将无法执行部分复制, 只能执行全量复制。 反过 来
说, 为了提高网络中断时部分复制执行的概率, 可以根据需要增大复制积压缓冲区的大小(通过配置repl-backlog-size)来设置; 例如 如果网络中断的平均时间是
60s, 而主节点平均每秒产生的写命令(特定协议格式)所占的字节数为100KB, 则复制积压缓冲区的平均需求为6MB, 保险起见, 可以设置为12MB, 来保证绝大多
数断线情况都可以使用部分复制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值