单台Redis虽然有持久化策略,但是万一磁盘坏了怎么办?Redis官方提供主从同步的方式。不仅解决了单点问题,而且从库可以分担主库的读压力。 主从复制会有3种场景存在
-
从库首次同步主库数据(全量复制) -
网络正常场景下的主从同步(基于长连接的命令传播) -
网络断联恢复后的主从同步(增量复制)
#Redis5.0之前
slaveof <主库ip> <主库port>
#Redis5.0之后
replicaof <主库ip> <主库port>
从库首次同步主库数据(全量复制)
第一阶段-建立连接,协商同步:从库发送 psync ?-1
命令给主库。主库响应FULLRESYNC {主库runID} {offset}
给从库第二阶段-主库同步数据给从库:主库通过bgsave生成RDB文件,传给从库。从库清空所有数据后加载主库给的RDB文件 第三阶段-主库发送新写命令给从库:在主从库通过RDB同步数据期间,主库一些新的命令同步给从库。
-
psync ? -1
psync <主库的runID> <从库的复制进度> 由于从库首次和主库进行同步,从库不知道主库的runID,所以第一参数赋值为?。从库首次同步自然没有赋值进度,所以第二哥参数为**-1。**
-
FULLSYNC {主库runID} {offset}
主库响应
FULLSYNC命令
,目的是告诉从库首次同步是全量复制。并返回主库自己的runID信息
主库从此刻开始通过bgsave方式生成RDB文件。在生成RDB文件过程产生的新写命令记录到replication buffer中。offset应该就是主库当前最后一条写命令的偏移量(告诉从库我现在最大偏移量是offset,后面的RDB就包含到offset位置为止的命令)
-
首次同步,从库通过RDB文件+replication buffer完成了数据的全量复制
网络正常场景下的主从同步(基于长连接的命令传播)

这里就用小林老师的图了。主从双方建立长连接,每个写命令通过长连接进行传输 这里主库的写命令应该也是先进入repl_buffer中然后通过TCP传输
网络断联恢复后的主从同步(增量复制)
网络的断联是很正常的事情。那么主从之间断开了一段时间又恢复的话,主从之间如何展开同步?
Redis2.8之前:断联后再恢复需要重新全量复制 Redis2.8之后:允许增量同步,从断开的时间点开始同步

主从之间断开连接后,主库的写命令同时记录到repl_buffer和repl_backlog_buffer中 恢复连接后,从库发送之前的主库runID和同步到的位置offset(slave_repl_offset)给主库** ** 主库的master_repl_offset记录repl_backlog_buffer目前已经写到的位置。主库将repl_backlog_buffer中master_repl_offset和slave_repl_offset之间的命令通过repl_buffer传给从库,实现增量同步
-
repl_backlog_buffer是个环形缓冲区

-
如果断联太久或者期间有太多命令。repl_backlog_buffer环形缓冲区无法存下,命令会被覆盖。此时就无法完成断联后的增量复制,而是改用全量复制。 -
通过repl_backlog_size可以调整repl_backlog_buffer环形缓冲区的大小
参考文档
-
极客时间《Redis核心技术与实战》 -
https://xiaolincoding.com/redis/cluster/master_slave_replication.html
原文始发于微信公众号(溪溪技术笔记):Redis主从复制原理
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/207068.html