携程开源Redis多数据中心解决方案-XPipe
https://zhuanlan.zhihu.com/p/27125444
Redis在攜程內(nèi)部得到了廣泛的使用,根據(jù)客戶端數(shù)據(jù)統(tǒng)計(jì),整個(gè)攜程全部Redis的讀寫請求在每秒200W,其中寫請求約每秒10W,很多業(yè)務(wù)甚至?xí)edis當(dāng)成內(nèi)存數(shù)據(jù)庫使用。
這樣,就對Redis多數(shù)據(jù)中心提出了很大的需求,一是為了提升可用性,解決數(shù)據(jù)中心DR(DisasterRecovery)問題;二是提升訪問性能,每個(gè)數(shù)據(jù)中心可以讀取當(dāng)前數(shù)據(jù)中心的數(shù)據(jù),無需跨機(jī)房讀數(shù)據(jù)。在這樣的需求下,XPipe應(yīng)運(yùn)而生 。
從實(shí)現(xiàn)的角度來說,XPipe主要需要解決三個(gè)方面的問題,一是數(shù)據(jù)復(fù)制,同時(shí)在復(fù)制的過程中保證數(shù)據(jù)的一致性;二是高可用,xpipe本身的高可用和Redis系統(tǒng)的高可用;三是如何在機(jī)房異常時(shí),進(jìn)行DR切換。
下文將會從這三個(gè)方面對問題進(jìn)行詳細(xì)闡述。最后,將會對測試結(jié)果和系統(tǒng)在生產(chǎn)環(huán)境運(yùn)行情況進(jìn)行說明。
為了方便描述,后面的行文中用DC代表數(shù)據(jù)中心(Data Center)。
一、數(shù)據(jù)復(fù)制問題
多數(shù)據(jù)中心首先要解決的是數(shù)據(jù)復(fù)制問題,即數(shù)據(jù)如何從一個(gè)DC傳輸?shù)搅硗庖粋€(gè)DC,通常有如下方案:
客戶端雙寫
從客戶端的角度來解決問題,單個(gè)客戶端雙寫兩個(gè)DC的服務(wù)器。初看沒有什么問題。但是深入看下去,如果寫入一個(gè)IDC成功,另外一個(gè)IDC失敗,那數(shù)據(jù)可能會不一致,為了保證一致,可能需要先寫入一個(gè)隊(duì)列,然后再將隊(duì)列的數(shù)據(jù)發(fā)送到兩個(gè)IDC。 如果隊(duì)列是本地隊(duì)列,那當(dāng)前服務(wù)器掛掉,數(shù)據(jù)可能會丟失;如果隊(duì)列是遠(yuǎn)程隊(duì)列,又給整體的方案帶來了很大的復(fù)雜度。
目前的應(yīng)用一般都是集群部署,會有多個(gè)客戶端同時(shí)操作。在多個(gè)客戶端的前提下,又帶來了新的問題。比如兩個(gè)客戶端ClientA和ClientB:
ClientA: set key value1
ClientB: set key value2
由于兩個(gè)客戶端獨(dú)立操作,到達(dá)服務(wù)器的順序不可控,所以可能會導(dǎo)致兩個(gè)DC的服務(wù)器對于同一個(gè)key,value不一致,如下:
Server1: setkey value1; set key value2;
Server2: setkey value2; set key value1;
在Server1,最終值為value2,在Server2,最終值為value1。
服務(wù)器代理
?
proxy模式解決了多客戶端寫可能會導(dǎo)致數(shù)據(jù)不一致的問題。proxy類似于一個(gè)client,和單個(gè)client雙寫的問題類似,需要一個(gè)數(shù)據(jù)隊(duì)列保數(shù)據(jù)一致性。
?
為了提升系統(tǒng)的利用率,單個(gè)proxy往往需要代理多個(gè)Redis server,如果proxy出問題,會導(dǎo)致大面積的系統(tǒng)故障。這樣,就對系統(tǒng)的性能和可用性提出了極大的挑戰(zhàn),帶來實(shí)現(xiàn)的復(fù)雜度。
此外,在特殊的情況下,仍然會可能帶來數(shù)據(jù)的不一致,比如value和時(shí)間相關(guān),或者是隨機(jī)數(shù),兩個(gè)Redis服務(wù)器所在系統(tǒng)的不一致帶來了數(shù)據(jù)的不一致。
考慮到以上情況,為了解決復(fù)制問題,我們決定采用偽slave的方案,即實(shí)現(xiàn)Redis協(xié)議,偽裝成為Redis slave,讓Redis master推送數(shù)據(jù)至偽slave。這個(gè)偽slave,我們把它稱為keeper,如下圖所示:
?
有了keeper之后,多數(shù)據(jù)中心之間的數(shù)據(jù)傳輸,可以通過keeper進(jìn)行。keeper將Redis日志數(shù)據(jù)緩存到磁盤,這樣,可以緩存大量的日志數(shù)據(jù)(Redis將數(shù)據(jù)緩存到內(nèi)存ring buffer,容量有限),當(dāng)數(shù)據(jù)中心之間的網(wǎng)絡(luò)出現(xiàn)較長時(shí)間異常時(shí)仍然可以續(xù)傳日志數(shù)據(jù)。
?
Redis協(xié)議不可更改,而keeper之間的數(shù)據(jù)傳輸協(xié)議卻可以自定義。這樣就可以進(jìn)行壓縮,以提升系統(tǒng)性能,節(jié)約傳輸成本;多個(gè)機(jī)房之間的數(shù)據(jù)傳輸往往需要通過公網(wǎng)進(jìn)行,這樣數(shù)據(jù)的安全性變得極為重要,keeper之間的數(shù)據(jù)傳輸也可以加密,提升安全性。
二、高可用
任何系統(tǒng)都可能會掛掉,如果keeper掛掉,多數(shù)據(jù)中心之間的數(shù)據(jù)傳輸可能會中斷,為了解決這個(gè)問題,需要保證keeper的高可用。我們的方案中,keeper有主備兩個(gè)節(jié)點(diǎn),備節(jié)點(diǎn)實(shí)時(shí)從主節(jié)點(diǎn)復(fù)制數(shù)據(jù),當(dāng)主節(jié)點(diǎn)掛掉后,備節(jié)點(diǎn)會被提升為主節(jié)點(diǎn),代替主節(jié)點(diǎn)進(jìn)行服務(wù)。
提升的操作需要通過第三方節(jié)點(diǎn)進(jìn)行,我們把它稱之為MetaServer,主要負(fù)責(zé)keeper狀態(tài)的轉(zhuǎn)化以及機(jī)房內(nèi)部元信息的存儲。同時(shí)MetaServer也要做到高可用:每個(gè)MetaServer負(fù)責(zé)特定的Redis集群,當(dāng)有MetaServer節(jié)點(diǎn)掛掉時(shí),其負(fù)責(zé)的Redis集群將由其它節(jié)點(diǎn)接替;如果整個(gè)集群中有新的節(jié)點(diǎn)接入,則會自動進(jìn)行一次負(fù)載均衡,將部分集群移交到此新節(jié)點(diǎn)。
Redis也可能會掛,Redis本身提供哨兵(Sentinel)機(jī)制保證集群的高可用。但是在Redis4.0版本之前,提升新的master后,其它節(jié)點(diǎn)連到此節(jié)點(diǎn)后都會進(jìn)行全量同步,全量同步時(shí),slave會處于不可用狀態(tài);master將會導(dǎo)出rdb,降低master的可用性;同時(shí)由于集群中有大量數(shù)據(jù)(RDB)傳輸,將會導(dǎo)致整體系統(tǒng)的不穩(wěn)定。
截止當(dāng)前文章書寫之時(shí),4.0仍然沒有發(fā)布release版本,而且攜程內(nèi)部使用的Redis版本為2.8.19,如果升到4.0,版本跨度太大,基于此,我們在Redis3.0.7的版本基礎(chǔ)上進(jìn)行優(yōu)化,實(shí)現(xiàn)了psync2.0協(xié)議,實(shí)現(xiàn)了增量同步。下面是Redis作者對協(xié)議的介紹:https://gist.github.com/antirez/ae068f95c0d084891305。
三、DR切換
DR切換分為兩種可能,一種是機(jī)房真的掛了或者出異常,需要進(jìn)行切換,另外一種是機(jī)房仍然健康,但是由于演練、業(yè)務(wù)要求等原因仍然需要切換到另外的機(jī)房。XPipe處理機(jī)房切換的流程如下:
-
檢查是否可以進(jìn)行DR切換
類似于2PC協(xié)議,首先進(jìn)行prepare,保證流程能順利進(jìn)行。
-
原主機(jī)房master禁止寫入
此步驟,保證在遷移的過程中,只有一個(gè)master,解決在遷移過程中可能存在的數(shù)據(jù)丟失情況。
-
提升新主機(jī)房master
-
其它機(jī)房向新主機(jī)房同步
當(dāng)然了,即使做了檢查,也無法絕對保證整個(gè)遷移過程肯定能夠成功,為此,我們提供回滾和重試功能。回滾功能可以回滾到初始的狀態(tài),重試功能可以在DBA人工介入的前提下,修復(fù)異常條件,繼續(xù)進(jìn)行切換。
根據(jù)以上分析,XPipe系統(tǒng)的整體架構(gòu)如下所示:
Console用來管理多機(jī)房的元信息數(shù)據(jù),同時(shí)提供用戶界面,供用戶進(jìn)行配置和DR切換等操作。Keeper負(fù)責(zé)緩存Redis操作日志,并對跨機(jī)房傳輸進(jìn)行壓縮、加密等處理。Meta Server管理單機(jī)房內(nèi)的所有keeper狀態(tài),并對異常狀態(tài)進(jìn)行糾正。
四、測試數(shù)據(jù)
我們關(guān)注的重點(diǎn)在于增加keeper后,平均延時(shí)的增加。測試方式如下圖所示。從client發(fā)送數(shù)據(jù)至master,并且slave通過keyspacenotification的方式通知到client,整個(gè)測試延時(shí)時(shí)間為t1+t2+t3。
首先我們測試Redis master直接復(fù)制到slave的延時(shí),為0.2ms。然后在master和slave之間增加一層keeper,整體延時(shí)增加0.1ms,到0.3ms。相較于多個(gè)DC之間幾毫秒,幾十毫秒的延時(shí),增加一層keeper帶來的延時(shí)是完全沒問題的。
在攜程生產(chǎn)環(huán)境進(jìn)行了測試,生產(chǎn)環(huán)境兩個(gè)機(jī)房之間的ping TTL約為0.61ms,經(jīng)過跨數(shù)據(jù)中心的兩層keeper后,測試得到的平均延時(shí)約為0.8ms,延時(shí)99.9線為2ms。
綜上所述:XPipe主要解決Redis多數(shù)據(jù)中心數(shù)據(jù)同步以及DR切換問題,同時(shí),由于XPipe增強(qiáng)后的Redis版本優(yōu)化了psync協(xié)議,會極大的提升Redis集群的穩(wěn)定性。
同時(shí),整個(gè)系統(tǒng)已經(jīng)開源,歡迎大家一起參與優(yōu)化整個(gè)系統(tǒng):
XPipe:?https://github.com/ctripcorp/x-pipe
XRedis(在Redis3.0.7版本上進(jìn)行增強(qiáng)的版本):
https://github.com/ctripcorp/redis
【作者簡介】孟文超,攜程技術(shù)中心框架研發(fā)部高級經(jīng)理。2016年加入攜程,目前主要負(fù)責(zé)Redis多數(shù)據(jù)中心項(xiàng)目XPipe。此前曾在大眾點(diǎn)評工作,任基礎(chǔ)架構(gòu)部門通信團(tuán)隊(duì)負(fù)責(zé)人。
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/articles/9253535.html
總結(jié)
以上是生活随笔為你收集整理的携程开源Redis多数据中心解决方案-XPipe的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Hive或Impala执行SQL语句
- 下一篇: HBase最佳实践