雙向pos機,差點栽在Redis手上……

 新聞資訊2  |   2023-05-25 14:14  |  投稿人:pos機之家

網(wǎng)上有很多關(guān)于雙向pos機,差點栽在Redis手上……的知識,也有很多人為大家解答關(guān)于雙向pos機的問題,今天pos機之家(www.dsth100338.com)為大家整理了關(guān)于這方面的知識,讓我們一起來看下吧!

本文目錄一覽:

1、雙向pos機

雙向pos機

一、背景

公司基于業(yè)務(wù)發(fā)展以及戰(zhàn)略部署,需要實現(xiàn)在多個數(shù)據(jù)中心單元化部署,一方面可以實現(xiàn)多數(shù)據(jù)中心容災(zāi),另外可以提升用戶請求訪問速度。需要保證多數(shù)據(jù)中心容災(zāi)或者實現(xiàn)用戶就近訪問的話,需要各個數(shù)據(jù)中心擁有一致的全量數(shù)據(jù),如果真正實現(xiàn)用戶就近讀寫,也就是實現(xiàn)真正的業(yè)務(wù)異地多活,數(shù)據(jù)同步是異地多活的基礎(chǔ),這就需要多數(shù)據(jù)中心間數(shù)據(jù)能夠雙向同步。

二、原生redis遇到的問題

1、不支持雙主同步

原生redis并沒有提供跨機房的主主同步機制,僅支持主從同步;如果僅利用redis的主從數(shù)據(jù)同步機制,只能將主節(jié)點與從節(jié)點部署在不同的機房。當(dāng)主節(jié)點所在機房出現(xiàn)故障時,從節(jié)點可以升級為主節(jié)點,應(yīng)用可以持續(xù)對外提供服務(wù)。但這種模式下,若要寫數(shù)據(jù),則只能通過主節(jié)點寫,異地機房無法實現(xiàn)就近寫入,所以不能做到真正的異地多活,只能做到備份容災(zāi)。而且機房故障切換時,需要運維手動介入。

因此,想要實現(xiàn)主主同步機制,需要同步工具模擬從節(jié)點方式,將本地機房中數(shù)據(jù)同步到其他機房,其他機房亦如此。同時,使用同步工具實現(xiàn)跨數(shù)據(jù)中心數(shù)據(jù)同步,會遇到以下一些問題。

1)數(shù)據(jù)回環(huán)

數(shù)據(jù)回環(huán)的意思是,A機房就近寫入的數(shù)據(jù),通過同步工具同步到B機房后,然后又通過B機房同步工具同步回A機房了。所以在同步的過程中需要識別本地就近寫入的數(shù)據(jù)還是其他數(shù)據(jù)中心同步過來的數(shù)據(jù),只有本地就近寫入的數(shù)據(jù)需要同步到其他數(shù)據(jù)中心。

2)冪等性

同步過程中的命令可能因斷點續(xù)傳等原因?qū)е轮貜?fù)同步了,此時需要保證同一命令多次執(zhí)行保證冪等。

3)多寫沖突

以雙寫沖突為例,如下圖所示:

DC1寫入set a 1,同時DC2寫入set a 2,當(dāng)這兩條命令通過同步工具同步到對方機房時,導(dǎo)致最終DC1中保存的a為2,DC2中保存的a為1,也就是說兩個機房最終數(shù)據(jù)不一致。

2、斷點續(xù)傳

針對瞬時的斷開重連、從節(jié)點重啟等場景,redis為了提高該場景下的主從同步效率,在主節(jié)點中增加了環(huán)形復(fù)制緩沖區(qū),主節(jié)點往從節(jié)點寫數(shù)據(jù)的同時也往復(fù)制緩沖區(qū)中也寫入一份數(shù)據(jù),當(dāng)從節(jié)點斷開重連時,則只需要通過復(fù)制緩沖區(qū)把斷開期間新增的增量數(shù)據(jù)發(fā)送給從節(jié)點即可,避免了全量同步,提升了這些場景下的同步效率。

但是,該內(nèi)存復(fù)制緩沖區(qū)一般來說不會太大,生產(chǎn)目前默認(rèn)設(shè)置為64M,跨數(shù)據(jù)中心同步場景下,網(wǎng)絡(luò)環(huán)境復(fù)雜,斷線的頻率和時長可能比同機房更頻繁和更長;同時,跨數(shù)據(jù)中心同步數(shù)據(jù)也是為了機房級故障容災(zāi),所以要求能夠支持更長時間的斷點續(xù)傳,無限增大內(nèi)存復(fù)制緩沖區(qū)大小顯然不是一個好主意。

下面來看看我們支持redis跨數(shù)據(jù)中心同步的優(yōu)化工作。

三、redis節(jié)點改造

為了支持異地多活場景,我們對原生redis代碼進行了優(yōu)化改造,主要包括以下幾個方面:

1、對RESP協(xié)議進行擴展

為了支持更高效的斷點續(xù)傳,以及為了解決數(shù)據(jù)回環(huán)問題,我們在redis主節(jié)點中對每條需要同步給從節(jié)點的命令(大部分為寫命令)增加了id,并且擴展了RESP協(xié)議,在每條相關(guān)命令的頭部增加了形如#{id}\\形式的協(xié)議。

本地業(yè)務(wù)客戶端寫入的數(shù)據(jù)依然遵循原生RESP協(xié)議,主節(jié)點執(zhí)行完命令后,同步到從節(jié)點的寫命令在同步前會進行協(xié)議擴展,增加頭部id協(xié)議;非本地業(yè)務(wù)客戶端(即來自其他數(shù)據(jù)中心同步)寫入的數(shù)據(jù)均使用擴展的RESP協(xié)議。

2、寫命令實時寫日志

為了支持更長時間的斷點續(xù)傳,容忍長時間的機房級故障,本地業(yè)務(wù)客戶端寫入的寫命令在進行協(xié)議擴展后,會順序?qū)懭肴罩疚募?,同時生成對應(yīng)的索引文件;為了減少日志文件大小,以及提高通過日志文件斷點續(xù)傳的效率,來自其他數(shù)據(jù)中心同步過來的數(shù)據(jù)不寫入日志文件中。

3、同步流程改造

原生redis數(shù)據(jù)同步分為全量同步和部分同步,并且每個主節(jié)點有一個內(nèi)存環(huán)形復(fù)制緩沖區(qū);初次同步使用全量同步,斷點續(xù)傳時使用部分同步,即先嘗試從主節(jié)點環(huán)形復(fù)制緩沖區(qū)中進行同步,同步成功的話則同步完緩沖區(qū)中的數(shù)據(jù)后即可進行增量數(shù)據(jù)同步,如果不成功,則仍然需要先進行全量同步再增量同步。

由于全量同步需要生成一個子進程,并且在子進程中生成一個RDB文件,所以對主節(jié)點性能影響比較大,我們應(yīng)該盡量減少全量同步的次數(shù)。

為了減少全量同步的次數(shù),我們對redis同步流程進行改造,當(dāng)部分同步中無法使用環(huán)形復(fù)制緩沖區(qū)完成同步時,增加先嘗試使用日志rlog進行同步,如果同步成功,則同步完日志中數(shù)據(jù)后即可進行增量同步,否則需要先進行全量同步。

四、rLog日志設(shè)計

分為索引文件與日志文件,均采用順序?qū)懙姆绞?,提高性能,?jīng)測試與原生redis開啟aof持久化性能一致;但是rlog會定期刪除,原生redis為了防止aof文件無限膨脹,會定期通過子進程執(zhí)行aof文件重寫,這個對主節(jié)點性能比較大,所以實質(zhì)上rlog對redis的性能相對于aof會更小。

索引文件和日志文件文件名均為文件中保存的第一條命令的id。

索引文件與日志文件均先寫內(nèi)存緩沖區(qū),然后批量寫入操作系統(tǒng)緩沖區(qū),并每秒定期刷新操作系統(tǒng)緩沖區(qū)真正落入磁盤文件中。相比較于aof文件緩沖區(qū),我們對rlog緩沖區(qū)進行了預(yù)分配優(yōu)化,達到提升性能目的。

1、索引文件格式

索引文件格式如下所示,每條命令對應(yīng)的索引數(shù)據(jù)包含三部分:

pos:該條命令第一個字節(jié)在對應(yīng)的日志文件中相對于該日志文件起始位置的偏移len:該條命令的長度offset:該條命令第一個字節(jié)在主節(jié)點復(fù)制緩沖區(qū)中累積的偏移

2、日志文件拆分

為了防止單個文件無限膨脹,redis在寫文件時會定期對文件進行拆分,拆分依據(jù)兩個維度,分別是文件大小和時間。

默認(rèn)拆分閾值分別為,當(dāng)日志文件大小達到128M或者每隔一小時同時并且日志條目數(shù)大于10w時,寫新的日志文件和索引文件。

在每次循環(huán)處理中,當(dāng)內(nèi)存緩沖區(qū)的數(shù)據(jù)全部寫入文件時,判斷是否滿足日志文件拆分條件,如果滿足,加上一個日志文件拆分標(biāo)志,下一次循環(huán)處理中,將內(nèi)存緩沖區(qū)數(shù)據(jù)寫入文件之前,先關(guān)閉當(dāng)前的索引文件和日志,同時新建索引文件和日志文件。

3、日志文件刪除

為了防止日志文件數(shù)量無限增長并且消耗磁盤存儲空間,以及由于未做日志重寫、通過過多的文件進行斷點續(xù)傳效率低下、意義不大,所以redis定期對日志文件和相應(yīng)的索引文件進行刪除。

默認(rèn)日志文件最多保留一天,redis定期刪除一天以前的日志文件和索引文件,也就是最多容忍一天時間的機房級故障,否則需要進行機房間數(shù)據(jù)全量同步。

在斷點續(xù)傳時,如果需要從日志文件中同步數(shù)據(jù),在同步開始前會臨時禁止日志文件刪除邏輯,待同步完成后恢復(fù)正常,避免出現(xiàn)在同步的數(shù)據(jù)被刪除的情況。

五、redis數(shù)據(jù)同步

1、斷點續(xù)傳

如前所述,為了容忍更長時間的機房級故障,提高跨數(shù)據(jù)中心容災(zāi)能力,提升機房間故障恢復(fù)效率,我們對redis同步流程進行改造,當(dāng)部分同步中無法使用環(huán)形復(fù)制緩沖區(qū)完成同步時,增加先嘗試使用日志rlog進行同步,流程圖如下所示:

首先,同步工具連接上主節(jié)點后,除了發(fā)送認(rèn)證外,需要先通過replconf capa命令告知主節(jié)點具備通過rlog斷點續(xù)傳的能力。

從節(jié)點先發(fā)送psync runId offset,如果是第一次啟動,則先發(fā)送psync ? -1,主節(jié)點會返回一個runId和offset如果能夠通過復(fù)制緩沖區(qū)同步,主節(jié)點給從節(jié)點返回 +CONTINUE runId如果不能夠通過復(fù)制緩沖區(qū)同步,主節(jié)點給從節(jié)點返回 +LPSYNC如果從節(jié)點收到+CONTINUE,則繼續(xù)接收增量數(shù)據(jù)即可,并繼續(xù)更新offset和命令id如果從節(jié)點收到+LPSYNC,則從節(jié)點繼續(xù)給主節(jié)點發(fā)送 LPSYNC runId id主節(jié)點收到LPSYNC命令后,如果能夠通過rlog繼續(xù)同步數(shù)據(jù),則給從節(jié)點發(fā)送 +LCONTINUE runId;從節(jié)點收到+LCONTINUE后,可以把offset設(shè)置為LONG_LONG_MIN,或者后續(xù)數(shù)據(jù)不更新offset;繼續(xù)接收通過rlog同步的增量數(shù)據(jù)即可;通過rlog同步的增量數(shù)據(jù)傳輸完畢后,主節(jié)點會給從節(jié)點發(fā)送 lcommit offset命令;從節(jié)點在解析數(shù)據(jù)的過程中,收到lcommit命令時,更新本地offset,后續(xù)的增量數(shù)據(jù)繼續(xù)增加offset,同時lcommit命令無需同步到對端(通過id<0識別即可,所有id<0的命令均無需同步到對端)如果不能,此時主節(jié)點給從節(jié)點返回 +FULLRESYNC runId offset;后續(xù)進行全量同步;

2、冪等性

遷移工具為了提高性能,并不是實時往zk保存同步偏移offset和id,而是定期(默認(rèn)每秒)向zk進行同步,所以當(dāng)斷點續(xù)傳時,遷移工具從zk獲取斷線前同步的偏移,嘗試向主節(jié)點繼續(xù)同步數(shù)據(jù),這中間可能會有部分?jǐn)?shù)據(jù)重復(fù)發(fā)送,所以為了保證數(shù)據(jù)一致性,需要保證命令多次執(zhí)行具備冪等性。

為了保證redis命令具備冪等性,對redis中部分非冪等性命令進行了改造,具體設(shè)計改造的命令如下所示:

注:list類型命令暫未改造,不具備冪等性

3、數(shù)據(jù)回環(huán)處理

數(shù)據(jù)回環(huán)主要是指,當(dāng)同步工具從A機房redis讀取的數(shù)據(jù),通過MQ同步到B機房寫入后,B機房的同步工具又獲取到,再次同步到A機房,導(dǎo)致數(shù)據(jù)循環(huán)復(fù)制問題。

對于同步到從節(jié)點以及遷移工具的數(shù)據(jù),會在頭部添加id字段,針對不同來源的數(shù)據(jù)或者無需同步到遠(yuǎn)端的數(shù)據(jù)通過id來標(biāo)識區(qū)分;本地業(yè)務(wù)客戶端寫入的數(shù)據(jù)需要同步到遠(yuǎn)端數(shù)據(jù)中心,分配id大于0;來源于其他數(shù)據(jù)中心的數(shù)據(jù)分配id小于0;一些僅用于主從心跳交互的命令數(shù)據(jù)分配id也小于0。

同步工具解析完數(shù)據(jù)后,過濾掉id小于0的命令,只需要向遠(yuǎn)端寫入id大于0的數(shù)據(jù),即本地業(yè)務(wù)客戶端寫入的數(shù)據(jù)。來源于其他數(shù)據(jù)中心的數(shù)據(jù)均不回寫到遠(yuǎn)端數(shù)據(jù)中心。

4、過期與淘汰數(shù)據(jù)

目前過期與淘汰均由各數(shù)據(jù)中心redis節(jié)點分別獨立處理,由過期與淘汰刪除的數(shù)據(jù)不進行同步;即由過期與淘汰產(chǎn)生的刪除命令其id分配為小于0,并由同步工具過濾掉。

1)同步產(chǎn)生的問題

為什么不同步過去?因為在內(nèi)存中hash表里面保存的數(shù)據(jù)沒有標(biāo)記數(shù)據(jù)中心來源,過期與淘汰的數(shù)據(jù)有可能來自于其他數(shù)據(jù)中心,如果來自于其他數(shù)據(jù)中心的數(shù)據(jù)被過期或淘汰并且又同步到遠(yuǎn)端其他數(shù)據(jù)中心,就會出現(xiàn)數(shù)據(jù)雙寫沖突的場景。雙寫沖突可能會導(dǎo)致數(shù)據(jù)不一致。

2)不同步產(chǎn)生的問題

對于過期數(shù)據(jù)來說,不同步刪除可能會導(dǎo)致不同數(shù)據(jù)中心數(shù)據(jù)顯示不一致,但是一定會最終一致,且不會出現(xiàn)臟讀;

對于淘汰數(shù)據(jù)來說,目前的不同步刪除的方案,假如出現(xiàn)淘汰,會導(dǎo)致不同數(shù)據(jù)中心數(shù)據(jù)不一致;目前只有通過運維手段,比如充足預(yù)分配、及時關(guān)注內(nèi)存使用率告警,來規(guī)避淘汰數(shù)據(jù)現(xiàn)象發(fā)生。

5、數(shù)據(jù)遷移

在redis集群模式中,一般是在發(fā)生橫向擴容增加集群主節(jié)點數(shù)時,需要進行槽以及數(shù)據(jù)的遷移。

redis集群中數(shù)據(jù)遷移以槽為維度進行遷移,將槽中所有數(shù)據(jù)從源節(jié)點遷移到目標(biāo)節(jié)點,然后將槽號標(biāo)記為由新的目標(biāo)節(jié)點負(fù)責(zé),同時每遷移完一個Key,會在源節(jié)點中進行刪除,將migrate命令替換為del命令;同時遷移數(shù)據(jù)是在源節(jié)點中給目標(biāo)節(jié)點發(fā)送restore命令實現(xiàn)。

我們數(shù)據(jù)遷移的策略依然是,各個數(shù)據(jù)中心獨立的完成擴容與數(shù)據(jù)遷移工作,遷移過程產(chǎn)生的del和restore命令不進行跨數(shù)據(jù)中心同步;把替換后的del命令和發(fā)送給目標(biāo)節(jié)點的restore命令都分配小于0的id,于是同步過程中會由同步工具進行過濾掉。

六、redis性能

經(jīng)測試,redis多活實例(默認(rèn)開啟rlog日志),相對于原生redis實例(開啟aof持久化)性能基本一致;如下圖所示:

注:以上圖表使用redis benchmark進行壓測,壓測時,客戶端和服務(wù)端在同一個機器上

七、待優(yōu)化項

1、多寫沖突

多個數(shù)據(jù)中心同時寫,key沖突問題暫未解決。

后續(xù)解決方案為使用CRDT協(xié)議;CRDT(Conflict-Free Replicated Data Type)是各種基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)最終一致算法的理論總結(jié),能根據(jù)一定的規(guī)則自動合并,解決沖突,達到強最終一致的效果。

目前解決方案為業(yè)務(wù)對寫入不同機房的數(shù)據(jù)進行拆分,以保證不會出現(xiàn)沖突。

2、list類型冪等性

五種基本類型里面,list類型大部分操作都是非冪等的,暫時未做冪等性改造優(yōu)化。不建議使用或者業(yè)務(wù)自身保證使用list的數(shù)據(jù)操作冪等。

3、過期與淘汰數(shù)據(jù)一致性問題

正如前文所述,淘汰數(shù)據(jù)不進行跨數(shù)據(jù)中心同步會導(dǎo)致數(shù)據(jù)不一致,如果同步數(shù)據(jù)可能會出現(xiàn)同一個Key多寫沖突,也可能出現(xiàn)數(shù)據(jù)不一致情況。

目前解決方案為業(yè)務(wù)盡量合理提前預(yù)估所需內(nèi)存容量、充足預(yù)分配、及時關(guān)注內(nèi)存使用率告警,來規(guī)避淘汰數(shù)據(jù)現(xiàn)象發(fā)生。

作者丨羅明

來源丨公眾號:京東科技技術(shù)說(ID:JDT-TechTalk)

dbaplus社群歡迎廣大技術(shù)人員投稿,投稿郵箱:editor@dbaplus.cn

關(guān)注公眾號【dbaplus社群】,獲取更多原創(chuàng)技術(shù)文章和精選工具下載

以上就是關(guān)于雙向pos機,差點栽在Redis手上……的知識,后面我們會繼續(xù)為大家整理關(guān)于雙向pos機的知識,希望能夠幫助到大家!

轉(zhuǎn)發(fā)請帶上網(wǎng)址:http://www.dsth100338.com/newsone/56832.html

你可能會喜歡:

版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 babsan@163.com 舉報,一經(jīng)查實,本站將立刻刪除。