【redis】全量复制

1.全量复制  

全量复制是redis最早支持的复制方式,也是主从第一次建立复制时必须经历的阶段。
触发全量复制的命令是sync和psync.

全量复制流程 
(1)发送psync命令进行数据同步,由于是第一次进行复制,从节点没有复制偏移量
和主节点的运行ID,所以发送psync ? -1 
(2)主节点根据 psync ?-1 解析出当前为全量复制,回复 +FULLRESYNC响应。
(3)从节点接收主节点的响应数据保存运行ID和偏移量offset。
(4)主节点执行bgsave保存RDB文件到本地;

redis3.0之后再输出的日志开头会有M,S,C等标识,对应的含义是:M=当前为主节点 
日志,S=当前为从节点日志,C=子进程日志,我们可以根据日志标识快速识别出
每行日志的角色信息。

35666:M 23 Jun 15:54:50.893 * Partial resynchronization not accepted: Replication ID mismatch (Slave asked for 'f9e5f6404b89a627e3fcc4cbd2abf0bff4872779', my replication IDs are 'd5f497283e3ace692a09a985207d8e7d143cf9a5' and '0000000000000000000000000000000000000000')
35666:M 23 Jun 15:54:50.894 * Starting BGSAVE for SYNC with target: disk
35666:M 23 Jun 15:54:50.894 * Background saving started by pid 35670
35670:C 23 Jun 15:54:50.899 * DB saved on disk
35670:C 23 Jun 15:54:50.899 * RDB: 6 MB of memory used by copy-on-write
35666:M 23 Jun 15:54:50.904 * Background saving terminated with success
35666:M 23 Jun 15:54:50.904 * Synchronization with slave 192.168.1.7:6380 succeeded
35666:M 23 Jun 16:01:48.420 * DB saved on disk
35666:M 23 Jun 16:01:48.420 # DB reloaded by DEBUG RELOAD
35666:M 23 Jun 16:16:47.269 # Connection with slave 192.168.1.7:6380 lost.
35666:M 23 Jun 16:17:27.737 * Slave 192.168.1.7:6380 asks for synchronization
35666:M 23 Jun 16:17:27.737 * Partial resynchronization request from 192.168.1.7:6380 accepted. Sending 812 bytes of backlog starting from offset 1079.
35666:M 23 Jun 17:59:35.864 # Connection with slave 192.168.1.7:6380 lost.

(5)主节点发送RDB文件给从节点,从节点把接收的RDB文件保存在本地并直接作为
从节点的数据文件,接收完RDB后从节点打印日志。

35940:S 23 Jun 18:20:27.354 * Before turning into a slave, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
35940:S 23 Jun 18:20:27.354 * SLAVE OF 192.168.1.7:6379 enabled (user request from 'id=9 addr=192.168.1.7:54384 fd=8 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=slaveof')
35940:S 23 Jun 18:20:27.671 * Connecting to MASTER 192.168.1.7:6379
35940:S 23 Jun 18:20:27.671 * MASTER <-> SLAVE sync started
35940:S 23 Jun 18:20:27.671 * Non blocking connect for SYNC fired the event.
35940:S 23 Jun 18:20:27.672 * Master replied to PING, replication can continue...
35940:S 23 Jun 18:20:27.672 * Trying a partial resynchronization (request 64f24af81f3f8d26eb4b7be0e9df4392542a7a6a:11039).
35940:S 23 Jun 18:20:27.675 * Full resync from master: 9519648e753dfb37dda6b58f118a04edd4bd13fb:10658
35940:S 23 Jun 18:20:27.675 * Discarding previously cached master state.
35940:S 23 Jun 18:20:27.772 * MASTER <-> SLAVE sync: receiving 405 bytes from master
35940:S 23 Jun 18:20:27.772 * MASTER <-> SLAVE sync: Flushing old data
35940:S 23 Jun 18:20:27.772 * MASTER <-> SLAVE sync: Loading DB in memory
35940:S 23 Jun 18:20:27.773 * MASTER <-> SLAVE sync: Finished with success

需要注意,对于数据量较大的主节点,比如生成的RDB文件超过6GB以上时要格外小心。
传输文件这一步操作非常耗时,速度取决于主从节点之间网络带宽,通过细致分析
Full resync 和 MASTER<->SLAVE 这两行日志的时间差,可以算出RDB文件从创建到
传输完毕消耗的总时间。如果总时间超过repl-timeout 所配置的值,从节点将放弃 
接受RDB文件并清理已经下载的临时文件,导致全量复制失败。
192.168.1.7:6380> config get repl-timeout 
1) "repl-timeout"
2) "60"

--针对数据量较大的节点,建议调大 repl-timeout 参数防止出现全量同步数据超时,
例如对于千兆网卡的机器,网卡带宽理论峰值大约每秒传输100MB,在不考虑其他进程
消耗带宽的情况下,6GB的RDB文件至少需要60s传输时间,默认配置极易出现主从数据
同步超时。
(6)对于从节点开始接收RDB快照到接收完成期间,主节点仍然响应读写命令,因此 
主节点会把这期间写命令数据保存在复制客户端缓冲区,当从节点加载完RDB文件后,
主节点再把缓冲区内的数据发送给从节点,保证主从之间数据一致性。如果主节点创建
和传输RDB的时间过长,对于高流量写入场景非常容易造成主节点复制客户端缓冲区
溢出。默认配置为 client-output-buffer-limit slave 256MB 64MB 60 ,
如果60秒内缓冲区消耗持续大于64MB或者直接超过256MB,主节点将直接关闭复制客户端
连接,造成全量同步失败。所以需要根据主节点数据量和写命令并发量调整。

对于主节点,当发送完所有的数据后就认为全量复制完成。打印日志:
Synchronization with slave 192.168.1.7:6380 succeeded
但是对于从节点全量复制依然没完成。
(7)从节点接收完主节点传送过来的全部数据后会清理自身旧数据。
* MASTER <-> SLAVE sync: Flushing old data
(8)从节点清空数据后开始加载RDB文件,对于较大的RDB文件,这一步操作依然比较耗时。
可以通过计算日志之间的时间差来判断加载RDB的中耗时。
35940:S 23 Jun 18:20:27.772 * MASTER <-> SLAVE sync: Loading DB in memory
35940:S 23 Jun 18:20:27.773 * MASTER <-> SLAVE sync: Finished with success

对于线上做读写分离的场景,从节点也负责响应读命令。如果此时从节点正处于全量 
复制阶段或者复制中断,那么从节点在响应读命令可能拿到过期或错误的数据。
对于这种场景,redis复制提供了slave-serve-stale-data 参数,默认开启状态。 
192.168.1.7:6380> config get slave-serve-stale-data
1) "slave-serve-stale-data"
2) "yes"
如果开启则从节点依然响应所有命令。对于无法容忍不一致的应用场景可以设置no来
关闭命令执行,此时从节点移除了 info 和slaveof 命令之外的所有命令,只返回:
"SYNC withh master in process" 

全量复制是个比较耗时的操作:
主节点bgsave时间 
RDB文件网络传输时间 
从节点清空数据时间 
从节点加载RDB时间 
可能的AOF重写时间 。

当线上数据量在6G左右的主节点,从节点发起全量复制的总耗时在2分钟左右。
因此当数据量达到一定规模之后,由于全量复制过程中将进行多次持久化相关操作
和网络数据传输,这期间会大量消耗主从节点所在服务器的CPU,内存,网络资源。
所以除了第一次全量复制难免以外,应该避免全量复制。redis实现了部分复制功能。

2.主从复制需要注意的参数:
repl-timeout 60
client-output-buffer-limit slave 256MB 64MB 60

特别针对数据量较大和高并发场景的复制。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值