當(dāng)前位置:
首頁(yè) >
springboot redis 断线重连_Redis复制:部分同步PSYNC详解
發(fā)布時(shí)間:2025/3/20
58
豆豆
生活随笔
收集整理的這篇文章主要介紹了
springboot redis 断线重连_Redis复制:部分同步PSYNC详解
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
概述
- 在Redis2.8之前,如果從服務(wù)器在主從復(fù)制的過(guò)程中,出現(xiàn)了斷線,重連之后需要全量同步一次主服務(wù)器上面的數(shù)據(jù),即從服務(wù)器發(fā)送SYNC命令給主服務(wù)器,請(qǐng)求進(jìn)行全量同步,但是斷線重連之后,從服務(wù)器只是可能落后主服務(wù)器斷線期間的寫入或者如果斷線時(shí)間非常短,主從之間數(shù)據(jù)還是一致的,故如果簡(jiǎn)單地進(jìn)行全量同步,則會(huì)造成主從服務(wù)器之間CPU,內(nèi)存,網(wǎng)絡(luò)帶寬方面的浪費(fèi)。
- 故在Redis2.8及其之后版本,對(duì)于從服務(wù)器斷線重連主服務(wù)器這種情景,使用的是部分同步PSYNC來(lái)實(shí)現(xiàn)。即從服務(wù)器重連之后,發(fā)送PSYNC命令給主服務(wù)器,主服務(wù)器根據(jù)該從服務(wù)器的同步情況,決定是只需將斷線期間的寫入同步給該從服務(wù)器,還是需要進(jìn)行一次全量同步。
核心設(shè)計(jì)
- 在PSYNC中,由于在主從之間只需要同步從服務(wù)器落后的部分?jǐn)?shù)據(jù),故在主從服務(wù)器中,均需要維護(hù)同步狀態(tài)相關(guān)的數(shù)據(jù)。
- PSYNC部分主從同步實(shí)現(xiàn)的必要組件,即同步狀態(tài)數(shù)據(jù):
- 主從服務(wù)器的復(fù)制偏移量;
- 主服務(wù)器的復(fù)制積壓緩沖區(qū);
- 主從服務(wù)器運(yùn)行ID。
復(fù)制偏移量
- 主服務(wù)器和從服務(wù)器都維護(hù)了一個(gè)復(fù)制偏移量,對(duì)應(yīng)主服務(wù)器來(lái)說(shuō),是記錄主服務(wù)器同步了多少數(shù)據(jù)給從服務(wù)器,即主服務(wù)器每進(jìn)行一次寫操作,如SET key “helloworld”,都會(huì)將該寫命令同步給從服務(wù)器,而在主服務(wù)器中會(huì)計(jì)算這個(gè)命令的字節(jié)數(shù),假如為N個(gè),則主服務(wù)器的復(fù)制偏移量將會(huì)遞增N。
- 從服務(wù)器的復(fù)制偏移量則記錄了從服務(wù)器從主服務(wù)器同步了多少字節(jié)的數(shù)據(jù),如當(dāng)接收到主服務(wù)器的以上寫命令時(shí),從服務(wù)器也會(huì)將自身復(fù)制偏移量遞增N。
- 所以如果主從服務(wù)器之間的復(fù)制偏移量是相等的,表示主從服務(wù)器之間數(shù)據(jù)一致;如果從服務(wù)器的小于主服務(wù)器的,則表示從服務(wù)器落后主服務(wù)器,這種情況在從服務(wù)器斷線重連之后可能會(huì)發(fā)生。具體過(guò)程如以下示意圖:(圖片均引自黃建宏的《Redis設(shè)計(jì)與實(shí)現(xiàn)》)
1.主服務(wù)器同步前:
2.主服務(wù)器同步后:
復(fù)制積壓緩沖區(qū)
- 復(fù)制積壓緩沖區(qū)主要用于緩存主服務(wù)器發(fā)送給從服務(wù)器的數(shù)據(jù),在從服務(wù)器斷線重連后,從該緩沖區(qū)查找從服務(wù)器斷線期間,主服務(wù)器的寫命令數(shù)據(jù),從而主服務(wù)器可以從該緩沖區(qū)獲取從服務(wù)器落后的數(shù)據(jù),發(fā)送給從服務(wù)器,實(shí)現(xiàn)部分同步。
- 數(shù)據(jù)結(jié)構(gòu):復(fù)制積壓緩沖區(qū)是在主服務(wù)器維護(hù)的一個(gè)大小固定的FIFO的隊(duì)列,默認(rèn)大小為1M。即如果超過(guò)1M,則主服務(wù)器會(huì)將隊(duì)列頭部數(shù)據(jù)出隊(duì)刪除,其中頭部數(shù)據(jù)為最先入隊(duì)數(shù)據(jù),即最早的寫入命令數(shù)據(jù)。具體大小可以通過(guò)在配置文件redis.conf中的repl-backlog-size來(lái)修改。
- 合適大小:復(fù)制積壓緩沖區(qū)的合適大小可以根據(jù):seconds * write_size_per_seconds來(lái)計(jì)算,其中seconds為從服務(wù)器斷開連接的平均時(shí)長(zhǎng),write_size_per_seconds為每秒寫(寫命令+寫的數(shù)據(jù))的平均大小。為了安全期間通常為2 * seconds * write_size_per_seconds。
- 緩沖區(qū)的更新:主服務(wù)器的復(fù)制偏移量和復(fù)制積壓緩沖區(qū)的更新是在主服務(wù)器在每次向從服務(wù)器傳播了N個(gè)字節(jié),則將自身的復(fù)制偏移量加上N。其中該N個(gè)字節(jié)的數(shù)據(jù)是一個(gè)寫命令(即寫命令+寫數(shù)據(jù))。同時(shí)將該次的寫命令寫入復(fù)制積壓緩沖區(qū)中,寫命令的每個(gè)字節(jié)在復(fù)制積壓緩沖區(qū)都對(duì)應(yīng)一個(gè)偏移量,如圖:
主從服務(wù)器運(yùn)行ID
- 在主從同步當(dāng)中,主從服務(wù)器都有自己的運(yùn)行ID,運(yùn)行ID是在服務(wù)器啟動(dòng)時(shí)自動(dòng)生成的,由40個(gè)隨機(jī)生成的16進(jìn)制的字符組成。
- 服務(wù)器運(yùn)行ID的主要作用是:
基于PSYNC的主從同步
- 主從服務(wù)器直接進(jìn)行PSYNC部分同步通常發(fā)送在從服務(wù)器斷線重連的時(shí)候,此時(shí)由從服務(wù)器發(fā)起。除此之外,在心跳檢測(cè)發(fā)現(xiàn)命令丟失時(shí),主服務(wù)器也會(huì)主動(dòng)發(fā)起一次PSYNC。主從同步示意圖如下:
斷線重連導(dǎo)致的PSYNC
- 當(dāng)從服務(wù)器斷線重連之后,發(fā)送PSYNC命令、自身的復(fù)制偏移量和斷線前所同步的主服務(wù)器運(yùn)行ID給主服務(wù)器,即:
- 主服務(wù)器根據(jù)該從服務(wù)器的復(fù)制偏移量offset和主服務(wù)器的復(fù)制積壓緩沖區(qū)是否存在該偏移量對(duì)應(yīng)的數(shù)據(jù),如果該從服務(wù)器偏移量之后(即offset+1)的數(shù)據(jù)還在該緩沖區(qū)中,則執(zhí)行部分同步,將隊(duì)列中從offset+1到隊(duì)列尾的數(shù)據(jù)發(fā)送給從服務(wù)器;
- 否則如果從服務(wù)器數(shù)據(jù)落后太多,如該1M的復(fù)制積壓緩沖區(qū)的頭部的偏移量都大于該從服務(wù)器復(fù)制偏移量(即offset+1),則執(zhí)行全量同步。
- 對(duì)從服務(wù)器而言,發(fā)送完P(guān)SYNC命令之后,如果主服務(wù)器返回+CONTINUE的回復(fù),則說(shuō)明可以進(jìn)行部分同步,從服務(wù)等待主服務(wù)器同步落后的數(shù)據(jù)過(guò)來(lái),主服務(wù)器將復(fù)制積壓緩沖區(qū)中該從服務(wù)器落后的這部分?jǐn)?shù)據(jù)發(fā)送過(guò)來(lái)。如果返回+FULLRESYNCH ,則進(jìn)行全量同步。如果返回-ERROR,則說(shuō)明主服務(wù)器版本低于2.8,不支持部分同步,此時(shí)從服務(wù)發(fā)送SYNC執(zhí)行全量同步。
心跳檢測(cè)導(dǎo)致的PSYNC
- 在進(jìn)入主從同步,主服務(wù)器和從服務(wù)器建立socket連接之后,從服務(wù)器以每秒一次的頻率向主服務(wù)器發(fā)送心跳包,即發(fā)送命令:
- 其中replication_offset為從服務(wù)器當(dāng)前的復(fù)制偏移量,作用包括:
總結(jié)
以上是生活随笔為你收集整理的springboot redis 断线重连_Redis复制:部分同步PSYNC详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python爬虫简单示例_最简单爬虫示例
- 下一篇: oracle 判断如果有符合条件的记录则