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