攜程 Redis 海外機房資料同步實踐
作者簡介
孟文超,攜程技術中心框架研發部高階經理。2016年加入攜程,目前負責框架資料(資料庫,快取)及相關專案。此前曾在大眾點評工作,任基礎架構部門通訊團隊負責人。
一、背景
隨著攜程國際化業務的發展,為了給海外使用者提供更好的服務,公司開始在歐洲部署業務(使用Amazon雲),歐洲的使用者訪問歐洲的本地服務。攜程機票業務重依賴於Redis,同時目前的資料產生大部分都在上海,這樣就對Redis資料同步至歐洲產生了極大的需求,部署在歐洲的業務只需讀取Redis資料即可。
資料傳輸如果走專線,將會產生高昂的專線費用(1MB的頻寬,每月約1萬RMB),如果能夠通過公網,基本可以將資料傳輸費用降低到忽略不計。這樣產生了第二個需求:資料傳輸走公網。
XPipe(https://github.com/ctripcorp/x-pipe)是攜程內部開源的一套Redis多機房系統,現有的功能在以往的基礎上繼續擴充套件,可以參考公眾號的另外一篇文章 ofollow,noindex">《攜程Redis多資料中心解決方案-XPipe》 。
二、系統分析設計
在 這樣的需求背景下,產生了下面幾個問題:
-
公網資料網路傳輸效能不可靠,Redis記憶體快取的增量資料有限,是否會產生頻繁的全量同步?
-
資料如何從上海內網傳輸至公網,再傳輸至Amazon內網?
-
公網傳輸的效能能滿足業務需求嗎,會不會導致延時過高,甚至無法追上上海的資料產生速度?
2.1 Redis全量同步問題
Redis資料複製本身的工作原理可以參考一下官方手冊:
https://redis.io/topics/replication。
本質上是說在Redis Master記憶體裡面會以RingBuffer的資料結構快取一段增量資料;如果網路瞬斷的話,slave將會繼續從自上一次中斷的位置同步資料,如果續不上,就會進行一次全量同步。
因為資料在記憶體中快取,而記憶體有限且昂貴,一個思路就是將資料快取在磁盤裡面。
在我們的具體方案中,設計了一個Keeper節點,作為Redis Slave向Master同步資料,同時將同步後的資料存入本地磁碟,海外資料同步通過Keeper進行資料傳輸,這樣就產生了下面的結構:
關於Keeper的高可用及其相關的設計,可以參考前文所述的公眾號文章。
2.2 資料從上海內網傳輸到公網問題
公網到內網 呼叫可以使用反向代理軟體,因為Redis協議為基於TCP自定義的文字協議,因此我們要使用支援TCP的反向代理工具。
Http 的反向代理可以通過域名、URL等資訊進行路由,定位到目標伺服器;TCP協議的反向代理通過暴漏的埠來路由到不同的伺服器叢集。
公司內部的的Redis叢集非常多,如果使用目前的反向代理軟體,就意味著要在公網開多個埠,不同的埠路由到不同的Redis叢集,單個IP支援的埠有限,過多埠也會帶來更多的安全以及管理問題。
基於此,我們設計了支援動態路由的TCP Proxy,假設有四個點:S(Source) P1(Proxy) P2(Proxy) D(Destination),A需要通過Proxy建立到D的連線,整個過程如下:
-
S 建立到P1的TCP連線
-
S 傳送路由資訊:proxy route P2 D
-
P1 收到資訊後建立到P2的tcp連線
-
P1 傳送路由資訊:proxy route D
-
P2 收到路由資訊後建立到D的tcp連線
整體架構圖如下:
如上圖所示,上述箭頭方向為資料傳輸方向,TCP連線建立方向正好相反。Pxory本身無狀態,所以天然可以做到高可用;Proxy本身支援資料加密、壓縮等功能。
使用者可能會產生疑問,為什麼歐洲還需要一組Proxy叢集,而不是Keeper直接連線上海的Proxy?
這個主要是基於功能隔離的考慮,Proxy專注處理好加密、壓縮等傳輸層需要考慮的問題,Keeper只需要考慮業務相關的功能。加密、壓縮演算法的優化和變更不會影響Keeper 。
2.3 公網傳輸效能問題
一般考 慮網路問題時,需要考慮頻寬、延時、丟包三組要素,公網傳輸是高頻寬,高延時,高丟包。網路上有很多關於Long Fat Network以及網路效能調優的文章,具體不贅述,這裡主要描述一下整個實踐過程。
首先我們調整了TCP的傳送接收視窗:
net.core.wmem_max=50485760
net.core.rmem_max=50485760
net.ipv4.tcp_rmem=4096 87380 50485760
net.ipv4.tcp_wmem=4096 87380 50485760
上海到歐洲的網路延時在200ms左右,調整完成之後發現在24小時的穩定性測試中,會有多個時間點頻寬無法打上去,導致資料同步延時過高。仔細觀察了一下當時TCP連線的狀態(通過ss命令),發現傳送資料時,TCP傳送視窗(cwnd)因為時不時的丟包,導致一直很小,問題主要出在資料傳送方。
據此,我們在測試環境比較了多種傳送端的擁塞控制(CongestionControl)演算法:Cubic, Reno, Htcp. BBR,下面是在1%丟包率下不同演算法頻寬比較:
演算法 |
平均 頻寬 |
Cubic |
0.15 MBytes/sec |
Htcp |
0.11 MBytes/sec |
Reno |
0.09 MBytes/sec· |
BBR |
13.6 MBytes/sec· |
在測試Case下,BBR演算法的頻寬比其他演算法提升了幾乎100倍,其他丟包率的情況下,也有更好的表現。關於BBR演算法的更多資料可以參考:
https://netdevconf.org/1.2/papers/bbr-netdev-1.2.new.new.pdf
因為我們的場景中資料傳送方是在上海,所以在上海端的伺服器部署了BBR演算法,下面是在10MB資料傳輸速率下,公網24小時延時測試資料(單位為納秒),資料最大延遲為88S。
公網和專線比較:
公網 |
專線 |
|
丟包 |
高(約1%) |
低(約0.05%) |
頻寬 |
高 |
低 |
延時 |
中 |
中 |
價格 |
非常低 |
高,1W RMB/MByte/月 |
2.4 監控、報警
整個系統中最重要的指標是資料從上海到歐洲的延時是多少。根據此資料可以判定系統是否健康。系統延時監控架構如下圖所示:
測試Client Publish一個時間戳資料給Master,然後將這個資料從Slave這邊訂閱收回,整個延時測試時間為:T1+T2+T3+T4。將資料收回計算延時時間主要是為了避免不同伺服器時鐘不一致產生的影響。
為什麼資料訂閱走專線?
-
監控系統兩秒Publish一個時間戳,資料量足夠小,不會佔用過大專線頻寬
-
我們關注的延時其實主要是T1+T2的時間。專線比較穩定,如果資料傳輸到歐洲走公網,訂閱回來也走公網,可能會導致延時測試資料不準確
為什麼資料訂閱通過Proxy轉發?
這個主要是公司安全策略問題,歐洲的伺服器只暴漏出了有限的埠供上海訪問,而Redis伺服器可能部署在很多的埠上面,這樣可以通過Proxy進行轉發代理。
2.5 整體系統架構
整體系統架構如上圖所示。Console用來管理多機房的元資訊資料,同時提供使用者介面,供使用者進行配置和DR切換等操作。Keeper負責快取Redis操作日誌。Proxy主要解決公網傳輸問題。Meta Server管理單機房內的所有Keeper狀態,並對異常狀態進行糾正。Zookeer用來供Meta Server和Keeper進行Leader選舉。
三、實踐結果
整個系 統目前從2018年7月上線,穩定執行至今。下圖是某一業務叢集的一個分片30天延時監控資料(單位為微秒)。平均延時180ms左右,最大可能波動到1-2min。
同 時, 整個系統已開源 :
XPipe: https://github.com/ctripcorp/x-pipe (點選閱讀原文直達)
【推薦閱讀】