異地多活在近年越來越多大型互聯網公司采用的方案,幾乎也是大型應用發展到一定階段的必然選擇,綜合比較一下各個互聯網公司的方案,會發現有很多共性的東西,也有很多差異化的東西,這是最有意思的地方
什么是異地多活
異地多活一般是指在不同城市建立獨立的數據中心,“活”是相對於冷備份而言的,冷備份是備份全量數據,平時不支撐業務需求,只有在主機房出現故障的時候才會切換到備用機房,而多活,是指這些機房在日常的業務中也需要走流量,做業務支撐。冷備份的主要問題是成本高,不跑業務,當主機房出問題的時候,也不一定能成功把業務接管過來。
CAP原則
分布式架構設計無論怎樣都繞不開CAP原則,C一致性 A可用性 P分區容錯性,分區容錯性是必不可少的,沒有分區容錯性就相當於退化成了單機系統,所以實際上架構設計是在一致性和可用性一個天平上的兩端做衡量。為什么強一致性和高可用性是不能同時滿足?假如需要滿足強一致性,就需要寫入一條數據的時候,擴散到分布式系統里面的每一台機器,每一台機器都回復ACK確認后再給客戶端確認,這就是強一致性。如果集群任何一台機器故障了,都回滾數據,對客戶端返回失敗,因此影響了可用性。如果只滿足高可用性,任何一台機器寫入成功都返回成功,那么有可能中途因為網絡抖動或者其他原因造成了數據不同步,部分客戶端獨到的仍然是舊數據,因此,無法滿足強一致性。
異地多活的挑戰
- 延遲 異地多活面臨的主要挑戰是網絡延遲,以北京到上海 1468 公里,即使是光速傳輸,一個來回也需要接近10ms,在實際測試的過程中,發現上海到北京的網絡延遲,一般是 30 ms。
- 一致性 用戶在任何一個機房寫入的數據,是否能在任何一個機房讀取的時候返回的值是一致性的。
誤區
-
所有業務都要異地多活
以用戶中心為例,注冊是沒必要做異地多活的,假如用戶在A機房注冊了,在數據沒有向外同步的時候,A機房網絡中斷,這個時候如果讓用戶切換到B機房注冊,就有可能發生數據不一致,出現兩個基本相同的賬號,這是不可容忍的。但是相對應的來說,用戶登錄這種是關鍵核心業務,就有必要做到異地多活了,用戶在A機房登錄不了,那就讓用戶在B機房登錄。雖然有極端的情況,用戶在A機房修改了密碼,但是出現網絡中斷,B機房的用戶仍然保存的是舊密碼,但是相對於不可登錄來說,這種情況是可容忍的。同時有些業務仍然是無法實現異地多活的,比如涉及到金錢的業務,加入有一個用戶有100塊,消費了50塊,A機房發生異常,數據沒有同步出去,這時候用戶在B機房登錄后發現自己還有100塊,可以繼續消費,就會對業務造成嚴重的影響。 -
必須做到實時一致性
受限於物理條件,跨地域的網速一定會存在延遲,一般是幾十毫秒,如果遇上網絡抖動,延遲超過幾秒甚至幾十秒都有可能。解決方法只能是減少需要同步的數據和只保證數據的最終一致性,有時候用戶在A機房修改了一條數據,業務上實際上是能容忍數據的短時間不一致的,即使其他用戶在B機房讀到的是舊數據,實際上對業務也沒有任何影響。 -
只使用存儲系統的同步功能
大部分場景下,MySQL Redis自帶的同步功能已經足以滿足需求了,但是在某些極端情況下,可能就不合適了,MySQL的單線程復制可能會產生較大的延遲,Redis可能會有全量復制,所以系統要靈活使用各種解決方案。
- 用消息隊列把數據廣播到各個數據中心
- 回源讀取,當A機房發現沒有這條數據的時候,根據路由規則去B機房去讀取該數據
- 重新生成數據,A機房登錄后生成session數據,這時候A機房掛了,可以把用戶切換到B機房,重新生成session數據。
- 實現100%的高可用
100%的高可用是無法保證的,硬件的損壞,軟件的BUG,光纖傳輸等太多不可控的因素,而且也要在成本上做一個權衡,尤其是對於強一致性業務,C和A只能取一個平衡,容忍短時間的不可用來保證數據的完全一致性。
餓了么異地多活方案
特點
-
業務內聚,單個訂單的所有流程保證在一個機房內完成調用,不允許進行跨機房調用。每一個機房稱為一個ezone,對服務進行分區,讓用戶,商戶,騎手按照規則聚合到一個ezone內。根據業務特點,餓了么選擇了把地理位置作為划分業務的單元,以行政省界用圍欄
把全國分為多個shard。在某個機房出現問題的時候,也可以按照地理位置把用戶,商戶,騎手打包遷移到別的機房即可。
-
可用性優先,當機房發生故障的時候,優先保證可用,用戶可以先下單吃飯,有限時間窗口內的數據不一致可以事后再修復。每個 ezone 都會有全量的業務數據,當一個 ezone 失效后,其他的 ezone 可以接管用戶。用戶在一個ezone的下單數據,會實時的復制到其他ezone。
-
保證數據的正確性,在切換和故障時,檢測到某些訂單在兩個機房不一致,會鎖定改訂單,避免錯誤進一步擴散。
通過DRC復制MySQL數據
MySQL的數據量最大,每個機房產生的數據,都通過 DRC 復制到其他 ezone,每個ezone的主鍵取值空間是ezoneid + 固定步長,所以產生的 id 各不相同,數據復制到一起后不會發生主鍵沖突。按照分區規則,正常情況下,每個 ezone 只會寫入自己的數據,但萬一出現異常,2個 ezone 同時更新了同一筆數據,就會產生沖突。DRC 支持基於時間戳的沖突解決方案,當一筆數據在兩個機房同時被修改時,最后修改的數據會被保留,老的數據會被覆蓋。
通過Global Zone保證強一致性
對於個別一致性要求很高的應用,我們提供了一種強一致的方案(Global Zone),Globa Zone是一種跨機房的讀寫分離機制,所有的寫操作被定向到一個 Master 機房進行,以保證一致性,讀操作可以在每個機房的 Slave庫執行,也可以 bind 到 Master 機房進行,這一切都基於我們的數據庫訪問層(DAL)完成,業務基本無感知。
新浪微博異地多活方案
微博使用了基於 MCQ(微博自研的消息隊列)的跨機房消息同步方案,並開發出跨機房消息同步組件 WMB(Weibo Message Broker)。
每個機房的緩存是完全獨立的,由每個機房的 Processor(專門負責消息處理的程序,類 Storm)根據收到的消息進行緩存更新。由於消息不會重復分發,而且信息完備,所以 MytriggerQ 方案存在的緩存更新臟數據問題就解決了。而當緩存不存在時,會穿透到 MySQL 從庫,然后進行回種。可能出現的問題是,緩存穿透,但是 MySQL 從庫如果此時出現延遲,這樣就會把臟數據種到緩存中。解決方案是做一個延時 10 分鍾的消息隊列,然后由一個處理程序來根據這個消息做數據的重新載入。一般從庫延時時間不超過 10 分鍾,而 10 分鍾內的臟數據在微博的業務場景下也是可以接受的。
由於微博對數據庫不是強依賴,加上數據庫雙寫的維護成本過大,選擇的方案是數據庫通過主從同步的方式進行。這套方案可能的缺點是如果主從同步慢,並且緩存穿透,這時可能會出現臟數據。這種同步方式已運行了三年,整體上非常穩定,沒有發生因為數據同步而導致的服務故障。
阿里異地多活方案
阿里在部署異地多活的時候同樣是碰到延時問題,解決方案是訪問一次頁面的操作都在本機房完成,不做跨機房調用。阿里把業務划分成各種單元,如交易單元,這個單元是完成交易業務,稱之為單元化。
服務延時
讓操作全部在同一中心內完成,單元化
比如用戶進入以后,比如說在淘寶上看商品,瀏覽商品,搜索、下單、放進購物車等等操作,還包括寫數據庫,就都是在所進入的那個數據中心中完成的,而不需要跨數據中心
部署:
異地部署的是流量會爆發式增長的,流量很大的那部分。流量小的,用的不多的,不用異地部署。
其他一些功能就會缺失,所以我們在異地部署的並非全站,而是一組業務,這組業務就成為單元
比如:在異地只部署跟買家交易相關的核心業務,確保一個買家在淘寶上瀏覽商品,一直到買完東西的全過程都可以完成
路由一致性:
買家相關的數據在寫的時候,一定是要寫在那個單元里。要保障這個用戶從進來一直到訪問服務,到訪問數據庫,全鏈路的路由規則都是完全一致的。如果說某個用戶本來應該進A城市的數據中心,但是卻因為路由錯誤,進入了B城市,那看到的數據就是錯的了。造成的結果,可能是用戶看到的購買列表是空的,這是不能接受的。
延時:
異地部署,我們需要同步賣家的數據、商品的數據。能接受的延時必須要做到一秒內,即在全國的范圍內,都必須做到一秒內把數據同步完中心之間骨干網。
數據一致性:
把用戶操作封閉在一個單元內完成,最關鍵的是數據。在某個點,必須確保單行的數據在一個地方寫,絕對不能在多個地方寫。
為了做到這一點,必須確定數據的維度。淘寶除了用戶本身的信息以外,還會看到所有商品的數據、所有賣家的數據,面對的是買家、賣家和商品三個維度。因為異地的是買家的核心鏈路,所以選擇買家這個維度。按買家維度來切分數據。但因為有三個維度的數據,當操作賣家、商品數據時,就無法封閉。
在所有的異地多活項目中,最重要的是保障某個點寫進去的數據一定是正確的。這是最大的挑戰,也是我們在設計整個方案中的第一原則。業務這一層出故障我們都可以接受,但是不能接受數據故障。
多個單元之間一定會有數據同步。一方面,每個單元都需要賣家的數據、商品的數據;
另一方面,我們的單元不是全量業務,那一定會有業務需要這個單元,比如說買家在這個單元下了一筆定單,而其他業務有可能也是需要這筆數據,否則可能操作不了,所以需要同步該數據。
所以怎樣確保每個單元之間的商品、賣家的數據是一致的,然后買家數據中心和單元是一致的,這是非常關鍵的。
總結
各種方案都是針對不同的業務場景設計的,所以會有一定的不同,但是基本思路都是一致的。通過各種手段避免進行跨機房調用,消除延遲,讓用戶無感知。必要的時候通過業務的妥協,犧牲一致性來獲取更高的可用性和更低的部署復雜程度。細讀CAP理論就知道,這個問題是不存在完美的解決方案的,只有盡量貼合業務,逐漸迭代出更合適的方案。
引用:
異地多活設計辣么難?其實是你想多了!
餓了么異地多活技術實現(一)總體介紹
微博“異地多活”部署經驗談
絕對干貨:解密阿里巴巴“異地多活”技術
阿里和微博的異地多活方案zt