最近我們的一個(gè)服務(wù)要解決一個(gè)主節(jié)點(diǎn)向從節(jié)點(diǎn)同步數(shù)據(jù)的問(wèn)題旺芽,就來(lái)翻了翻書(shū),研究了下redis是怎么實(shí)現(xiàn)主從同步的擅这,來(lái)總結(jié)一下
今天先來(lái)說(shuō)一下2.8版本之前是如何實(shí)現(xiàn)的
redis中澈魄,實(shí)現(xiàn)主從復(fù)制的方式主要有兩種
1.配置文件中設(shè)置slaveof選項(xiàng)
配置文件地方
- 在從服務(wù)器的配置文件配置slaveof選項(xiàng)
- 配置如下:
slaveof <masterip> <masterport>
- masterip 為redis主服務(wù)器的ip
- masterport 為redis主服務(wù)的redis服務(wù)端口
2.從服務(wù)器上使用客戶(hù)端發(fā)送slaveof命令
從服務(wù)上發(fā)送命令
- 使用客戶(hù)端,連接到從服務(wù)器上
- 在從服務(wù)器上發(fā)送slaveof命令
- 命令如下:
slaveof masterip masterport
- masterip 為redis主服務(wù)器的ip
- masterport 為redis主服務(wù)的redis服務(wù)端口
redis主從同步功能的原理
- redis的主從同步功能主要分為兩個(gè)操作
- 同步(sync)操作
- 命令傳播(command propagate)兩個(gè)操作
- 同步(sync)操作主要作用是將當(dāng)前從服務(wù)器的狀態(tài)更新至主服務(wù)器的狀態(tài)仲翎,也就是把當(dāng)前主服務(wù)器中的所有數(shù)據(jù)同步至從服務(wù)中
- 命令傳播(command propagate) 使用同步(sync)操作完成后痹扇,主服務(wù)器會(huì)把所有執(zhí)行的命令傳遞到從服務(wù)器,讓主從保持一致
先說(shuō)說(shuō)同步(sync)操作
- 當(dāng)從服務(wù)器向主服務(wù)器發(fā)送slaveof命令時(shí)溯香,要求同步主服務(wù)事鲫构,會(huì)先執(zhí)行同步(sync)操作,主要作用是將當(dāng)前從服務(wù)器的狀態(tài)更新至主服務(wù)器的狀態(tài)玫坛,也就是把當(dāng)前主服務(wù)器中的所有數(shù)據(jù)同步至從服務(wù)中
- 同步(sync)操作的流程如下
同步(sync)操作的流程
同步(sync)操作的流程
- 1.從服務(wù)器向主服務(wù)器發(fā)送slaveof命令
- 2.主服務(wù)器接受到slaveof命令后
- 3.開(kāi)始執(zhí)行BGSAVE命令
- 4.在后臺(tái)生成一個(gè)RDB文件
- 5.并使用一個(gè)緩沖區(qū)記錄從開(kāi)始執(zhí)行的所有命令
- 6.主服務(wù)器BGSAVE命令執(zhí)行完畢
- 7.主服務(wù)器將BGSAVE命令生成的RDB文件發(fā)送至從服務(wù)器
- 8.從服務(wù)器接受RDB文件并且載入
- 9.將自己的數(shù)據(jù)庫(kù)狀態(tài)更新至主服務(wù)器執(zhí)行BGSAVE命令時(shí)的數(shù)據(jù)庫(kù)狀態(tài)
- 10.主服務(wù)器將記錄在緩沖區(qū)中里所有的寫(xiě)命令發(fā)送給從服務(wù)器
- 11.從服務(wù)器執(zhí)行這些命令完成整個(gè)同步過(guò)程
再說(shuō)說(shuō)命令傳播(command propagate) 操作
- 當(dāng)同步(sync)操作執(zhí)行完畢后结笨,此時(shí),主從服務(wù)器的數(shù)據(jù)庫(kù)狀態(tài)達(dá)到了一致?tīng)顟B(tài)
- 然后主服務(wù)器會(huì)將自己執(zhí)行的寫(xiě)命令發(fā)送給從服務(wù)器,從服務(wù)器會(huì)執(zhí)行主服務(wù)器發(fā)過(guò)來(lái)的命令炕吸,來(lái)實(shí)現(xiàn)同步伐憾,就是傳播(command propagate) 操作
借用書(shū)上圖舉個(gè)整體流程的例子
時(shí)間 | 主服務(wù)器 | 從服務(wù)器 |
---|---|---|
T0 | 執(zhí)行 SET K1 V1 命令 | |
T1 | 執(zhí)行 SET K2 V2 命令 | |
T2 | 向主服務(wù)器發(fā)送slaveof命令 | |
T3 | 1.主服務(wù)器接受到slaveof命令后 2.開(kāi)始執(zhí)行BGSAVE命令 3.在后臺(tái)生成一個(gè)RDB文件,包含K1赫模、K2 4.并使用一個(gè)緩沖區(qū)記錄從開(kāi)始執(zhí)行的所有命令 | |
T4 | SET K3 V3,并把命令寫(xiě)入緩沖區(qū) | |
T5 | SET K4 V4,并把命令寫(xiě)入緩沖區(qū) | |
T6 | BGSAVE命令執(zhí)行完畢树肃,向從服務(wù)器發(fā)送RDB文件 | |
T7 | 接收并載入主服務(wù)器發(fā)來(lái)的RDB文件, 獲得K1瀑罗、K2數(shù)據(jù) | |
T8 | 向從服務(wù)器發(fā)送緩沖區(qū)中的SET K3 V3胸嘴、 SET K4 V4 | |
T9 | 接收并執(zhí)行主服務(wù)器發(fā)來(lái)的兩個(gè)命令, 執(zhí)行了SET K3 V3斩祭、SET K4 V4命令 | |
T10 | 同步(sync操作完成)劣像,此時(shí)主服務(wù)器中有K1、K2停忿、K3驾讲、K4 四個(gè)key | 同步(sync操作完成),此時(shí)主服務(wù)器中有K1席赂、 K2、K3时迫、K4 四個(gè)key,數(shù)據(jù)庫(kù)狀態(tài)同步一致 |
T11 | 執(zhí)行 SET K5 V5 命令颅停,并且命令傳播(command propagate) 把命令傳遞給從服務(wù) | 執(zhí)行主服務(wù)器傳遞過(guò)來(lái)的 SET K5 V5 命令 |
T12 | 執(zhí)行 SET K6 V6 命令,并且命令傳播 (command propagate) 把命令傳遞給從服務(wù) | 執(zhí)行主服務(wù)器傳遞過(guò)來(lái)的 SET K6 V6 命令 |
T13 | 主從服務(wù)器斷開(kāi)連接掠拳,并重連成功 | 主從服務(wù)器斷開(kāi)連接癞揉,并重連成功 |
T14 | 重新開(kāi)始同步(sync)操作,重復(fù)上述流程 |
2.8版本之前主從同步的缺陷
- 2.8版本之前主從同步存在一些缺陷
- 按照上面的表格
- 如果是初次主從同步溺欧,是沒(méi)有問(wèn)題的
- 如果同步(sync)操作完成后喊熟,同步了K1、K2數(shù)據(jù)姐刁,此時(shí)芥牌,主從服務(wù)器之間處于命令傳播 (command propagate) 階段,傳遞了K3聂使、K4命令壁拉,然后主從服務(wù)器之間斷開(kāi)連接
- 當(dāng)主從服務(wù)器重新建立連接后,主從服務(wù)器之間又開(kāi)始執(zhí)行同步(sync)操作
- 此時(shí)的同步(sync)操作柏靶,主服務(wù)器生成RDB文件弃理,RDB文件包含的key是從第一次同步中的K1開(kāi)始,包含K1屎蜓、K2痘昌、K3、K4
- 雖然還是可以完成同步(sync)操作,但是其實(shí)有很多key是沒(méi)有必要再次同步的
- 因?yàn)橥剑╯ync)操作中辆苔,需要主服務(wù)器生成RDB文件笔诵,這個(gè)操作會(huì)占用服務(wù)器的大量的資源:CPU、內(nèi)存姑子、IO
- 而主從服務(wù)器之間傳遞RDB文件會(huì)占用服務(wù)器帶寬
- 從服務(wù)器加載RDB文件時(shí)乎婿,同樣會(huì)占用服務(wù)器的大量的資源:CPU、內(nèi)存街佑、IO
- 所以沒(méi)有沒(méi)有必要的同步(sync)操作會(huì)損耗服務(wù)器資源谢翎,降低服務(wù)的性能
今天講了redis的主從同步中的2.8版本以前的方式,最后說(shuō)了2.8版本以前的方式中的一些缺陷沐旨,下次再來(lái)講講2.8版本以后的方式森逮,歡迎大家來(lái)交流,指出文中一些說(shuō)錯(cuò)的地方磁携,讓我加深認(rèn)識(shí)褒侧,愿大家沒(méi)有bug,謝謝谊迄!