本發(fā)明涉及電子計(jì)算機(jī)數(shù)據(jù)存儲(chǔ)領(lǐng)域,具體涉及一種Redis中主從節(jié)點(diǎn)數(shù)據(jù)同步方法。
背景技術(shù):
近年來(lái),計(jì)算機(jī)系統(tǒng)的發(fā)展日新月異,對(duì)數(shù)據(jù)存儲(chǔ)載體的要求也越來(lái)越高,特別是互聯(lián)網(wǎng)的興起,由于其服務(wù)的用戶(hù)眾多,對(duì)數(shù)據(jù)存儲(chǔ)性能的要求非常高,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)很難滿(mǎn)足要求,因此,眾多的互聯(lián)網(wǎng)企業(yè)在面向最終用戶(hù)的服務(wù)上放棄使用傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù),而使用了性能更好的KV(鍵值)數(shù)據(jù)庫(kù)存儲(chǔ),開(kāi)源產(chǎn)品Redis(REmoteDIctionary Server)就是其中之一。
Redis是一個(gè)性能極高、數(shù)據(jù)類(lèi)型豐富、功能全面的KV(鍵,值)數(shù)據(jù)庫(kù)。根據(jù)其官網(wǎng)描述在50個(gè)并發(fā)的情況下寫(xiě)入速度是11萬(wàn)次/秒,讀出速度8.1萬(wàn)次/秒。數(shù)據(jù)類(lèi)型除了基本的string數(shù)據(jù)類(lèi)型外還有hash,list,set,sorted set等數(shù)據(jù)結(jié)構(gòu)類(lèi)型。Redis在集群部署中提供了數(shù)據(jù)的主從節(jié)點(diǎn)復(fù)制功能。
互聯(lián)網(wǎng)業(yè)務(wù)應(yīng)用系統(tǒng)因其提供的服務(wù)在性能和實(shí)時(shí)性響應(yīng)上的特殊要求大量使用Redis作為數(shù)據(jù)存儲(chǔ)載體,集群部署中也使用了Redis的主從復(fù)制功能,出現(xiàn)了主從復(fù)制鏈、主從復(fù)制樹(shù)形結(jié)構(gòu)(復(fù)制鏈的增強(qiáng)版),如圖1所示,每個(gè)Redis節(jié)點(diǎn)都是數(shù)據(jù)的全量,使用上基本是Redis的“主”節(jié)點(diǎn)接受數(shù)據(jù)寫(xiě)入,數(shù)據(jù)由“主”節(jié)點(diǎn)復(fù)制到“從”節(jié)點(diǎn),應(yīng)用程序在“從”節(jié)點(diǎn)讀取數(shù)據(jù)的方式。
在業(yè)務(wù)系統(tǒng)使用過(guò)程中,Redis的這種部署方式對(duì)數(shù)據(jù)一致性、實(shí)時(shí)性和擴(kuò)展性上面都給了業(yè)務(wù)系統(tǒng)不錯(cuò)的支撐。數(shù)據(jù)實(shí)時(shí)性、一致性在Redis高效的主從復(fù)制上的到了很好的保證。集群擴(kuò)展性上,擴(kuò)展集群只是意味著增加復(fù)制鏈(樹(shù))型結(jié)構(gòu)的節(jié)點(diǎn)即可,十分簡(jiǎn)單。但是在使用Redis中 仍然碰到了一些問(wèn)題。
首先,“主”節(jié)點(diǎn)存在“單點(diǎn)”問(wèn)題,一旦“主”節(jié)點(diǎn)所在服務(wù)器硬件故障或者網(wǎng)絡(luò)分區(qū)導(dǎo)致“主”節(jié)點(diǎn)相對(duì)“從”節(jié)點(diǎn)或應(yīng)用服務(wù)器不可訪(fǎng)問(wèn)就會(huì)導(dǎo)致數(shù)據(jù)無(wú)法寫(xiě)入問(wèn)題,此時(shí)必須更換“主”節(jié)點(diǎn)進(jìn)行數(shù)據(jù)寫(xiě)入,并且“原主”節(jié)點(diǎn)所有的“從”節(jié)點(diǎn)也要進(jìn)行主從節(jié)點(diǎn)的變更,使其從于“新主”節(jié)點(diǎn)接受數(shù)據(jù)更新,如圖2所示,換主期間左右兩個(gè)Redis子樹(shù)的數(shù)據(jù)會(huì)被“新主節(jié)點(diǎn)”全量覆蓋,在數(shù)據(jù)同步的過(guò)程中服務(wù)不可用。
其次,在使用過(guò)程中會(huì)有同城不同機(jī)房間的機(jī)器調(diào)整,此過(guò)程中會(huì)有手工的“摘掉”節(jié)點(diǎn)、“掛”新節(jié)點(diǎn)的動(dòng)作,如圖3所示,整個(gè)過(guò)程數(shù)據(jù)全量復(fù)制一次時(shí)間比較長(zhǎng),期間數(shù)據(jù)全量復(fù)制,被調(diào)整節(jié)點(diǎn)的服務(wù)不可用。
再次,如果有異地機(jī)房之間的數(shù)據(jù)需要復(fù)制,問(wèn)題將會(huì)更加嚴(yán)重,如圖4,一旦全量復(fù)制數(shù)據(jù),數(shù)據(jù)同步期間服務(wù)不可用。
以上幾種情況將會(huì)出現(xiàn)一個(gè)共同的問(wèn)題,主從節(jié)點(diǎn)之間數(shù)據(jù)全量復(fù)制,并且在全量復(fù)制期間不能提供服務(wù),如果節(jié)點(diǎn)數(shù)據(jù)量比較大、復(fù)制時(shí)間長(zhǎng)問(wèn)題將會(huì)加劇。原生態(tài)的Redis在主從復(fù)制的實(shí)現(xiàn)上有全量復(fù)制和增量復(fù)制兩種方式,全量復(fù)制由于復(fù)制數(shù)據(jù)量大需要較長(zhǎng)的時(shí)間才能完成,因此Redis2.8版本后出現(xiàn)了增量復(fù)制,但是增量復(fù)制只適用于主從節(jié)點(diǎn)短時(shí)間鏈接斷開(kāi),數(shù)據(jù)更新量不是很大(沒(méi)有超過(guò)主節(jié)點(diǎn)日志范圍)的情況。全量復(fù)制由于其耗時(shí)較長(zhǎng)(復(fù)制期間會(huì)出現(xiàn)服務(wù)不可用)應(yīng)該被盡量的避免,而在上述示例的幾種情況下都會(huì)出的全量復(fù)制,如果網(wǎng)絡(luò)環(huán)境不好導(dǎo)致復(fù)制時(shí)間較長(zhǎng)的話(huà)這一缺點(diǎn)將更加突出。實(shí)際上在“復(fù)制樹(shù)”結(jié)構(gòu)中由于Redis的主從復(fù)制機(jī)制,各個(gè)節(jié)點(diǎn)數(shù)據(jù)更新相差不大,在調(diào)整結(jié)構(gòu)過(guò)程中即便不是直接的主從節(jié)點(diǎn)關(guān)系,理論上也可以通過(guò)拷貝差異數(shù)據(jù)來(lái)實(shí)現(xiàn)增量復(fù)制。
技術(shù)實(shí)現(xiàn)要素:
(一)要解決的技術(shù)問(wèn)題
鑒于上述問(wèn)題,本發(fā)明的目的在于,提供一種Redis中主從節(jié)點(diǎn)數(shù)據(jù)同步方法,解決現(xiàn)有Redis主從節(jié)點(diǎn)之間所提供的數(shù)據(jù)同步方式的低效問(wèn)題,最大限度的減少了服務(wù)不可用的時(shí)間和由此帶來(lái)的運(yùn)維不便。
(二)技術(shù)方案
本發(fā)明提供一種Redis中主從節(jié)點(diǎn)數(shù)據(jù)同步方法,用于將Redis樹(shù)型結(jié)構(gòu)中主節(jié)點(diǎn)和從節(jié)點(diǎn)的數(shù)據(jù)進(jìn)行同步,同一樹(shù)型結(jié)構(gòu)中的節(jié)點(diǎn)具有相同的基因ID,不同樹(shù)型結(jié)構(gòu)間的節(jié)點(diǎn)具有不同的基因ID,方法包括:
S1,從節(jié)點(diǎn)向主節(jié)點(diǎn)發(fā)送數(shù)據(jù)同步請(qǐng)求,其中,該數(shù)據(jù)同步請(qǐng)求包含有從節(jié)點(diǎn)的基因ID;
S2,主節(jié)點(diǎn)接收到該數(shù)據(jù)同步請(qǐng)求后,判斷從節(jié)點(diǎn)的基因ID與主節(jié)點(diǎn)的基因ID是否一致,若一致,則通過(guò)增量復(fù)制的方式將主節(jié)點(diǎn)上的數(shù)據(jù)復(fù)制到所述從節(jié)點(diǎn),否則,通過(guò)全量復(fù)制的方式將主節(jié)點(diǎn)上的數(shù)據(jù)復(fù)制到所述從節(jié)點(diǎn)。
(三)有益效果
本發(fā)明提供的Redis中主從節(jié)點(diǎn)數(shù)據(jù)同步方法,在同一顆樹(shù)中,將數(shù)據(jù)相差不大的主從節(jié)點(diǎn)進(jìn)行增量同步,解決現(xiàn)有Redis主從節(jié)點(diǎn)之間所提供的數(shù)據(jù)同步方式的低效問(wèn)題,使得業(yè)務(wù)應(yīng)用客戶(hù)端在數(shù)據(jù)存儲(chǔ)故障或手工數(shù)據(jù)遷移過(guò)程中最大限度的減少了服務(wù)不可用的時(shí)間,帶來(lái)了較好的用戶(hù)體驗(yàn)。
附圖說(shuō)明
圖1-圖4是現(xiàn)有技術(shù)Redis中主從復(fù)制樹(shù)形結(jié)構(gòu)的示意圖。
圖5是本發(fā)明實(shí)施例提供的Redis節(jié)點(diǎn)復(fù)制樹(shù)型結(jié)構(gòu)。
圖6是本發(fā)明實(shí)施例提供的主從節(jié)點(diǎn)進(jìn)行增量復(fù)制的判定示意圖。
圖7是現(xiàn)有技術(shù)和本發(fā)明實(shí)施例提供的主從節(jié)點(diǎn)斷開(kāi)重連時(shí)進(jìn)行數(shù)據(jù)同步的示意圖。
圖8是本發(fā)明實(shí)施例提供的主從節(jié)點(diǎn)斷開(kāi)后命令執(zhí)行的示意圖。
圖9是現(xiàn)有技術(shù)和本實(shí)施例的寫(xiě)性能壓力測(cè)試的對(duì)比圖。
圖10是現(xiàn)有技術(shù)和本實(shí)施例的讀性能壓力測(cè)試的對(duì)比圖。
具體實(shí)施方式
本發(fā)明提供一種Redis中主從節(jié)點(diǎn)數(shù)據(jù)同步方法,通過(guò)主從節(jié)點(diǎn)基因ID,判斷其是否處于同一顆樹(shù)上,若是,則進(jìn)行數(shù)據(jù)增量復(fù)制;另外,主 從節(jié)點(diǎn)建立連接并進(jìn)行全量同步數(shù)據(jù)時(shí),主節(jié)點(diǎn)將基準(zhǔn)偏移量傳遞給從節(jié)點(diǎn),保證主從節(jié)點(diǎn)斷開(kāi)重連后對(duì)應(yīng)的命令保持一致;再者,在從節(jié)點(diǎn)連接新主節(jié)點(diǎn)時(shí),先斷開(kāi)連接,再在從節(jié)點(diǎn)中增加標(biāo)志位,避免從節(jié)點(diǎn)自動(dòng)重新跟原主節(jié)點(diǎn)建立連接,解決了主從日志數(shù)據(jù)順序不一致的問(wèn)題。
根據(jù)本發(fā)明的一種實(shí)施方式,Redis中主從節(jié)點(diǎn)數(shù)據(jù)同步方法包括:
S1,從節(jié)點(diǎn)向主節(jié)點(diǎn)發(fā)送數(shù)據(jù)同步請(qǐng)求,其中,該數(shù)據(jù)同步請(qǐng)求包含有從節(jié)點(diǎn)的基因ID,所述基因ID是標(biāo)識(shí)不同Redis樹(shù)型結(jié)構(gòu)的ID;
S2,主節(jié)點(diǎn)接收到該數(shù)據(jù)同步請(qǐng)求后,判斷從節(jié)點(diǎn)的基因ID與主節(jié)點(diǎn)的基因ID是否一致,若一致,則通過(guò)增量復(fù)制的方式將主節(jié)點(diǎn)上的數(shù)據(jù)復(fù)制到所述從節(jié)點(diǎn),否則,通過(guò)全量復(fù)制的方式將主節(jié)點(diǎn)上的數(shù)據(jù)復(fù)制到所述從節(jié)點(diǎn)。
根據(jù)本發(fā)明的一種實(shí)施方式,主從節(jié)點(diǎn)采用環(huán)形隊(duì)列存儲(chǔ)日志,并且,數(shù)據(jù)同步請(qǐng)求包括從節(jié)點(diǎn)的偏移量,其中,在步驟S2中,若從節(jié)點(diǎn)的基因ID與主節(jié)點(diǎn)的基因ID一致,則判斷偏移量是否存在于所述日志,若是,則通過(guò)增量復(fù)制的方式將主節(jié)點(diǎn)上的數(shù)據(jù)復(fù)制到所述從節(jié)點(diǎn),否則,通過(guò)全量復(fù)制的方式將主節(jié)點(diǎn)上的數(shù)據(jù)復(fù)制到從節(jié)點(diǎn)。
根據(jù)本發(fā)明的一種實(shí)施方式,通過(guò)全量復(fù)制的方式將主節(jié)點(diǎn)上的數(shù)據(jù)復(fù)制到從節(jié)點(diǎn)時(shí),將主節(jié)點(diǎn)的基準(zhǔn)偏移量傳遞給從節(jié)點(diǎn),以使得主從節(jié)點(diǎn)中日志對(duì)應(yīng)的命令相同。
根據(jù)本發(fā)明的一種實(shí)施方式,在數(shù)據(jù)同步期間,禁止ping命令寫(xiě)入日志。
根據(jù)本發(fā)明的一種實(shí)施方式,當(dāng)從節(jié)點(diǎn)欲與新主節(jié)點(diǎn)連接時(shí),首先斷開(kāi)從節(jié)點(diǎn)與原主節(jié)點(diǎn)的連接,然后在從節(jié)點(diǎn)中增加標(biāo)志位,以避免從節(jié)點(diǎn)自動(dòng)重新與所述原主節(jié)點(diǎn)建立連接。
為使本發(fā)明的目的、技術(shù)方案和優(yōu)點(diǎn)更加清楚明白,以下結(jié)合具體實(shí)施例,并參照附圖,對(duì)本發(fā)明進(jìn)一步詳細(xì)說(shuō)明。
圖5是本發(fā)明實(shí)施例提供的Redis節(jié)點(diǎn)復(fù)制樹(shù)型結(jié)構(gòu),如圖5所示,同一棵Redis復(fù)制樹(shù)型結(jié)構(gòu)上的所有節(jié)點(diǎn)如同一個(gè)家族的成員,節(jié)點(diǎn)(父子節(jié)點(diǎn),兄弟姐妹節(jié)點(diǎn))之間是有血緣關(guān)系的或者說(shuō)是有相同的“基因”的。具有相同“基因”的節(jié)點(diǎn)時(shí)能夠進(jìn)行增量復(fù)制的前提,因此,在本實(shí)施例 中,每個(gè)節(jié)點(diǎn)都會(huì)繼承父節(jié)點(diǎn)的“基因ID”,凡是具有“血緣”關(guān)系或說(shuō)有相同“基因ID”的節(jié)點(diǎn)之間原則上都可以做增量同步。因此在從節(jié)點(diǎn)通過(guò)psync(partial sync)命令向主節(jié)點(diǎn)進(jìn)行數(shù)據(jù)同步時(shí)應(yīng)先檢查是否有相同的“基因ID”,具有相同”基因ID“的節(jié)點(diǎn)可以接受增量復(fù)制的請(qǐng)求。
圖6是本發(fā)明實(shí)施例提供的主從節(jié)點(diǎn)進(jìn)行增量復(fù)制的判定示意圖,如圖6所示,Redis數(shù)據(jù)存儲(chǔ)上使用了一種環(huán)形隊(duì)列的結(jié)構(gòu)來(lái)存儲(chǔ)日志(backlog),環(huán)形隊(duì)列大小可以通過(guò)配置項(xiàng)來(lái)定制,從節(jié)點(diǎn)向主節(jié)點(diǎn)請(qǐng)求同步數(shù)據(jù)的時(shí)候會(huì)傳入“基因ID”和偏移量(offset)。主節(jié)點(diǎn)接收到請(qǐng)求的時(shí)候會(huì)首先判斷是否來(lái)自相同復(fù)制樹(shù)型結(jié)構(gòu)進(jìn)而判斷是否支持增量同步方式。
圖7是現(xiàn)有技術(shù)和本發(fā)明實(shí)施例提供的主從節(jié)點(diǎn)斷開(kāi)重連時(shí)進(jìn)行數(shù)據(jù)同步的示意圖,Redis中的Backlog用來(lái)緩存主節(jié)點(diǎn)傳遞給從節(jié)點(diǎn)的Redis命令,如果主從節(jié)點(diǎn)之間出現(xiàn)斷開(kāi)重連的情況,主節(jié)點(diǎn)通過(guò)傳遞給從節(jié)點(diǎn)缺少的命令來(lái)實(shí)現(xiàn)部分同步。而偏移量就是用來(lái)確定傳遞命令的范圍的。從節(jié)點(diǎn)在給主節(jié)點(diǎn)發(fā)送psync命令時(shí)傳遞的偏移量是從主節(jié)點(diǎn)接收到的最新命令對(duì)應(yīng)在主節(jié)點(diǎn)Backlog的偏移量。由于Backlog的大小固定并且是滾動(dòng)使用的,所以偏移量實(shí)際上是所有寫(xiě)入過(guò)Backlog的命令的累加值。當(dāng)從節(jié)點(diǎn)創(chuàng)建Backlog時(shí),偏移量從0開(kāi)始計(jì)算,如圖7中左圖所示,雖然數(shù)據(jù)Backlog最后一條命令是相同的,但是對(duì)應(yīng)的偏移量不一致。為了支持同一復(fù)制樹(shù)內(nèi)任意兩個(gè)節(jié)點(diǎn)的部分同步,需要通過(guò)傳遞基準(zhǔn)偏移量(base offset)來(lái)保證相同的偏移量在復(fù)制樹(shù)內(nèi)任意節(jié)點(diǎn)所對(duì)應(yīng)的命令相同,如圖7中右圖所示。因此,本實(shí)施例主從節(jié)點(diǎn)建立連接首次全量同步數(shù)據(jù)時(shí),將基準(zhǔn)偏移量傳遞給從節(jié)點(diǎn),這樣在復(fù)制樹(shù)內(nèi)同一偏移量在任意兩個(gè)節(jié)點(diǎn)所對(duì)應(yīng)的命令就能保持一致了。
此外,為了保持backlog數(shù)據(jù)的一致性,對(duì)一些Redis命令還需要做一些特殊處理。例如,Redis會(huì)根據(jù)配置文件周期性的向backlog內(nèi)寫(xiě)入ping命令并傳遞給所有從節(jié)點(diǎn),為了保持?jǐn)?shù)據(jù)一致性我們將禁止ping命令寫(xiě)入backlog。
從節(jié)點(diǎn)連接新主節(jié)點(diǎn)的過(guò)程中應(yīng)該避免接收到原主節(jié)點(diǎn)的數(shù)據(jù)。雖然Redis的slaveof no one可以實(shí)現(xiàn)類(lèi)似的功能,但是如果從節(jié)點(diǎn)有當(dāng)前包含 標(biāo)記為expire但還沒(méi)有釋放的數(shù)據(jù),一旦expire時(shí)間到達(dá)會(huì)在從節(jié)點(diǎn)觸發(fā)del命令同時(shí)將del命令寫(xiě)入backlog。這種從節(jié)點(diǎn)自發(fā)修改(不是由主節(jié)點(diǎn)觸發(fā))backlog的行為,會(huì)產(chǎn)生主從backlog數(shù)據(jù)順序不一致的問(wèn)題。如圖8所示,主從斷開(kāi)前有“EXPIRE a 60”執(zhí)行,代表60秒后a將被清除(主節(jié)點(diǎn)60秒后自動(dòng)調(diào)用DEL),如果清除前主從斷開(kāi)(通過(guò)從節(jié)點(diǎn)執(zhí)行slaveof no one命令),同時(shí)主節(jié)點(diǎn)有新數(shù)據(jù)寫(xiě)入“SET b 2”,60秒后斷開(kāi)的主從會(huì)分別執(zhí)行DEL命令,這就導(dǎo)致主從相同的offset對(duì)應(yīng)的命令不同。
為了避免這類(lèi)問(wèn)題,本實(shí)施例采用“暫停主從同步”的Redis命令,該命令首先斷開(kāi)主從連接阻止主從數(shù)據(jù)復(fù)制,然后增加標(biāo)志位避免從節(jié)點(diǎn)自動(dòng)重新跟主節(jié)點(diǎn)建立連接。
圖9是現(xiàn)有技術(shù)和本實(shí)施例的寫(xiě)性能壓力測(cè)試的對(duì)比圖。相比現(xiàn)有技術(shù),本實(shí)施例的Redis從節(jié)點(diǎn)在作為葉子時(shí)也需要?jiǎng)?chuàng)建并維護(hù)backlog,所以在寫(xiě)入的最大TPS要低,但由于差異比例小,對(duì)實(shí)際性能影響不大。
圖10是現(xiàn)有技術(shù)和本實(shí)施例的讀性能壓力測(cè)試的對(duì)比圖。相比現(xiàn)有技術(shù),本實(shí)施例的Redis從節(jié)點(diǎn)需要對(duì)一些影響backlog offset的命令進(jìn)行過(guò)濾,所以最大TPS略低。但由于差異比例小,對(duì)性能影響不大。
綜上所述,本發(fā)明通過(guò)主從節(jié)點(diǎn)基因ID,判斷其是否處于同一顆樹(shù)上,若是,則進(jìn)行數(shù)據(jù)增量復(fù)制;另外,主從節(jié)點(diǎn)建立連接并進(jìn)行全量同步數(shù)據(jù)時(shí),主節(jié)點(diǎn)將基準(zhǔn)偏移量傳遞給從節(jié)點(diǎn),保證主從節(jié)點(diǎn)斷開(kāi)重連后對(duì)應(yīng)的命令保持一致;再者,在從節(jié)點(diǎn)連接新主節(jié)點(diǎn)時(shí),先斷開(kāi)連接,再在從節(jié)點(diǎn)中增加標(biāo)志位,避免從節(jié)點(diǎn)自動(dòng)重新跟原主節(jié)點(diǎn)建立連接,解決了主從日志數(shù)據(jù)順序不一致的問(wèn)題,提高了數(shù)據(jù)同步效率,基本消除了暫停服務(wù),方便了對(duì)Redis集群的運(yùn)維。
以上所述的具體實(shí)施例,對(duì)本發(fā)明的目的、技術(shù)方案和有益效果進(jìn)行了進(jìn)一步詳細(xì)說(shuō)明,所應(yīng)理解的是,以上所述僅為本發(fā)明的具體實(shí)施例而已,并不用于限制本發(fā)明,凡在本發(fā)明的精神和原則之內(nèi),所做的任何修改、等同替換、改進(jìn)等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。