redis系列(五):主从同步

就是从库和主库的数据要保持一致,主库的数据同步到从库的过程。

现有两个redis

  • 127.0.0.1:6379
  • 127.0.0.1:12345
127.0.0.1:12345 > slaveof 127.0.0.1:6379

这个时候,12345就是6379的从库了。

复制分为全量复制和增量复制。
全部复制触发在从库初始化的时候。
其他情况都是走的增量复制。增量就是主库每次修改的数据。

2.8之前的复制功能

redis复制功能分为同步(sync)和命令传播(command propagate)

  • 同步操作用于将从服务器,更新至与主服务器一致
  • 命令传播则用于,在主服务器被修改,导致主从不一致的时候,让主从重新回到一致的动作。

同步

当从服务器知道自己是从服务器,并初始化的时候,开始执行同步。
过程:

  1. 从服务器想主服务器发送SYNC命令
  2. 收到SYNC命令的主服务器,执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令。
  3. 当主服务的BGSAVE命令执行完毕时,主服务器会将刚生成的RDB文件发送给从服务器。从服务器接收并载入这个RDB文件,将自己的数据更新至与主服务器执行BGSAVE命令时的状态。
  4. 主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些命令,将自己的数据库状态更新至主服务器当前所处的状态。
初始化同步过程.png
时间 主服务器 从服务器
T0 服务器启动 服务器启动
T1 执行 set k1 v1
T2 执行 set k2 v2
T3 执行 set k3 v3
T4 向主服务器发送SYNC命令
T5 接收到从服务器的SYNC命令,执行BGSAVE命令,创建包含k1、k2、k3的RDB文件,并使用缓冲区记录接下来执行的所有写命令
T6 执行 set k4 v4,并将这个命令记录到缓冲区
T7 执行 set k5 v5,并将这个命令记录到缓冲区
T8 BGSAVE命令执行完毕,向从服务器发送RDB文件
T9 接收并载入主服务器发来的RDB文件,获得k1,k2,k3三个键
T10 向从服务器发送缓冲分区保存的写命令set k4 v4和set k5 v5
T11 接收并执行主服务器发来的两个set命令,得到k4,k5两个键
T12 同步完成,现在主从服务器两者的数据库都包含了键k1,k2,k3,k4,k5 同步完成,现在主从服务器两者的数据库都包含了键k1,k2,k3,k4,k5

命令传播

当复制执行完了,以后主库的修改怎么做到的主从一致呢,这就要用到命令传播了。

当主库删除了k3,让从库也得删除k3。就要把del k3这个命令发送给从服务器。从服务器收到后,执行,这样就又一致了。完事。

老版本的缺陷

  • 初次同步。从服务器以前没有复制过任何主服务器,或者从服务器当前要复制的主服务器和上一次复制的主服务器不同。
  • 断线后再次同步。处于命令传播阶段的主从服务器因为网络原因而中断了复制,从服务器通过自动重连,重新连上了主服务器,这时候开始继续复制主服务器。

初次复制。没有问题。问题出在了断线后再次复制。看下过程:

时间 主服务器 从服务器
T0 主从服务器完成同步 主从服务器完成同步
T1 执行 set k1 v1 执行主服务器传来的 set k1 v1
T2 执行 set k2 v2 执行主服务器传来的 set k2 v2
... ... ...
T10085 执行并传播set k10086 v10086 执行主服务器传来的 set k10085 v10085
T10086 执行并传播set k10086 v10086 执行主服务器传来的 set k10086 v10086
T10087 主从服务断开连接 主从服务断开连接
T10088 执行set k10087 v10087 断线中,尝试重新连接主服务器
T10089 执行set k10088 v10088 断线中,尝试重新连接主服务器
T10090 执行set k10089 v10089 断线中,尝试重新连接主服务器
T10091 主从服务器重新连接 主从服务器重新连接
T10092 向主服务器发送SYNC命令
T10093 收到从服务器发来的SYNC命令,执行BGSAVE命令,创建包含k1值k10089的RDB文件,并使用缓冲区记录接下来执行的所有写命令
T10094 BGSAVE执行完毕,向从服务器发送RDB文件
T10095 接收并载入主服务器发来的RDB文件,获得k1至k10089
T10096 因为BGSAVE命令执行期间,主服务器没有执行写命令,所以不会发送缓冲区的写命令
T10097 主从服务器再次完成同步 主从服务器再次完成同步

问题就在T10093。他把所有的数据都放RDB传给从服务器了。从服务器k1至k10086都是有的。不用在来一遍。所以新版本复制功能就出来的,主要原则是引入了offset。

2.8之后的复制功能

2.8之后的同步命令不是SYNC了,而是PSYNC。

PSYNC分两种:

  • 完成重同步。和旧版本SYNC一样,也是全量RDB发送给从库。
  • 部分重同步。这就不一样了。只把断线重连这段时间的写命令发送给从服务器,从服务器接收到这些命令,主从就一致了。
时间 主服务器 从服务器
T0 主从服务器完成同步 主从服务器完成同步
T1 执行 set k1 v1 执行主服务器传来的 set k1 v1
T2 执行 set k2 v2 执行主服务器传来的 set k2 v2
... ... ...
T10085 执行并传播set k10086 v10086 执行主服务器传来的 set k10085 v10085
T10086 执行并传播set k10086 v10086 执行主服务器传来的 set k10086 v10086
T10087 主从服务断开连接 主从服务断开连接
T10088 执行set k10087 v10087 断线中,尝试重新连接主服务器
T10089 执行set k10088 v10088 断线中,尝试重新连接主服务器
T10090 执行set k10089 v10089 断线中,尝试重新连接主服务器
T10091 主从服务器重新连接 主从服务器重新连接
T10092 向主服务器发送PSYNC命令
T10093 向从服务器返回+continue回复,表示执行部分重同步
T10094 接收+continue回复,准备执行部分重同步
T10095 向从服务器发送set k10087 v10087、set k10088 v10088、set k10089 v10089三个命令
T10096 接收并执行主服务器传来的三个set命令
T10097 主从服务器再次完成同步 主从服务器再次完成同步

部分重同步由三个部分构成

  • 主服务和复制偏移量和从服务器的复制偏移量
  • 主服务器的复制积压缓冲区
  • 服务器运行的ID(run ID)

复制偏移量

一张图你就明白了


初始化状态.png
正常情况.png
A掉线了.png

复制积压缓冲区

复制积压缓冲区是一个由主服务器维护的一个固定长度,先进先出队列。默认大小1MB。

在命令传播过程中,主库的过程:


命令传播.png

当从服务器连接上主服务器时,从服务器会通过PSYNC命令将自己的复制偏移量offset发送给主服务器,主服务器会根据这个复制偏移量来决定对服务器进行何种同步操作:

  • 如果offset偏移量之后的数据,仍然存在于复制积压缓冲区里面,那么主服务器将对从服务器执行部分重同步。

  • 相反,offset之后的数据,不在复制积压缓冲区中(两种情况,1.掉线时间太长。2.换了新的主),那么进行完整重同步。

回到刚刚断线重连表格的那个例子:

  1. 当从服务器A重连后,向主服务器发送PSYNC命令,报告自己的复制偏移量为10086

  2. 主服务器收到从服务器的PSYNC命令以及10086偏移量之后,主服务器将检查偏移量之后的数据是否还存在与复制积压缓冲区中,结果发现仍然存在,于是想从服务器发送+continue回复,表示以部分同步模式来进行。

  3. 接着主服务器会将复制积压缓冲区10086偏移量之后的所有数据(10087至10119)都要发送发给给从服务器。

  4. 从服务器接收到这33字节的缺失数据,就可以回到与主服务器一致的状态。

服务器运行ID

不管主从,服务器启动时,都会生成一个ID。

当主从初次复制的时候,从库会保存自己主库的ID。

当从断线并重新连上一个主服务器,从服务器会把上次复制的主服务器ID,发送给当前的主库。主库收到之后会判断:

  • 和自己一样。说明之前就是我的从,可能就会执行部分重同步。(缓冲区没有了就完成重同步了)。

  • 和自己不一样。说明之前是别人的从,第一次成为我的从,必然会执行完整重同步。

如果在传输过程中,数据丢了怎么办

主库给从库发送10087至10119这段偏移量的所有数据,但网络问题丢了。在从库想主库每秒发送心跳的时候,心跳包中会包含从库的offset,如果不一样,把差掉的补发。(2.8之前没有这个功能)。

知识点

当从库接收主库的全量RDB文件。在载入RDB文件的时候,从库是不可用的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicat...
    施智沂阅读 323评论 0 0
  • 概念 持久化保证了即使 redis 服务重启也会丢失数据,因为 redis 服务重启后会将硬盘上持久化的数据恢复到...
    CryFace阅读 158评论 0 1
  • Redis主从复制 一.主从复制介绍 1.Redis复制功能介绍 1)Redis 使用异步复制。从 Redis2....
    唯爱熊阅读 169评论 0 0
  • 在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicat...
    tracy_668阅读 509评论 0 4
  • Redis作为一个分布式的存储服务,集群的工作模式几乎是标配,Redis目前的主从模式也是大多人使用的模型,那Re...
    雨生_阅读 4,723评论 0 1