支付寶架構到底有多牛逼鸿竖!沒看完我就跪了武花!

作者:湯波
鏈接:https://www.tbwork.org/2019/11/10/ant-ldc-arch/

自 2008 年雙 11 以來圆凰,在每年雙 11 超大規(guī)模流量的沖擊上,螞蟻金服都會不斷突破現(xiàn)有技術的極限髓堪。

2010 年雙 11 的支付峰值為 2 萬筆/分鐘送朱,到 2017 年雙 11 時這個數(shù)字變?yōu)榱?25.6 萬筆/秒。

2018 年雙 11 的支付峰值為 48 萬筆/秒干旁,2019 年雙 11 支付峰值為 54.4 萬筆/秒驶沼,創(chuàng)下新紀錄,是 2009 年第一次雙 11 的 1360 倍争群。

在如此之大的支付 TPS 背后除了削峰等錦上添花的應用級優(yōu)化回怜,最解渴最實質的招數(shù)當數(shù)基于分庫分表的單元化了,螞蟻技術稱之為 LDC(邏輯數(shù)據(jù)中心)。

本文不打算討論具體到代碼級的分析玉雾,而是嘗試用最簡單的描述來說明其中最大快人心的原理翔试。

我想關心分布式系統(tǒng)設計的人都曾被下面這些問題所困擾過:

  • 支付寶海量支付背后最解渴的設計是啥?換句話說复旬,實現(xiàn)支付寶高 TPS 的最關鍵的設計是啥垦缅?

  • LDC 是啥?LDC 怎么實現(xiàn)異地多活和異地災備的驹碍?

  • CAP 魔咒到底是啥壁涎?P 到底怎么理解?

  • 什么是腦裂志秃?跟 CAP 又是啥關系怔球?

  • 什么是 PAXOS,它解決了啥問題浮还?

  • PAXOS 和 CAP 啥關系竟坛?PAXOS 可以逃脫 CAP 魔咒么?

  • Oceanbase 能逃脫 CAP 魔咒么钧舌?

如果你對這些感興趣担汤,不妨看一場赤裸裸的論述,拒絕使用晦澀難懂的詞匯延刘,直面最本質的邏輯漫试。

LDC 和單元化

LDC(logic data center)是相對于傳統(tǒng)的(Internet Data Center-IDC)提出的六敬,邏輯數(shù)據(jù)中心所表達的中心思想是無論物理結構如何的分布碘赖,整個數(shù)據(jù)中心在邏輯上是協(xié)同和統(tǒng)一的。

這句話暗含的是強大的體系設計外构,分布式系統(tǒng)的挑戰(zhàn)就在于整體協(xié)同工作(可用性普泡,分區(qū)容忍性)和統(tǒng)一(一致性)。

單元化是大型互聯(lián)網(wǎng)系統(tǒng)的必然選擇趨勢审编,舉個最最通俗的例子來說明單元化撼班。

我們總是說 TPS 很難提升,確實任何一家互聯(lián)網(wǎng)公司(比如淘寶垒酬、攜程砰嘁、新浪)它的交易 TPS 頂多以十萬計量(平均水平),很難往上串了勘究。

因為數(shù)據(jù)庫存儲層瓶頸的存在再多水平擴展的服務器都無法繞開矮湘,而從整個互聯(lián)網(wǎng)的視角看,全世界電商的交易 TPS 可以輕松上億口糕。

這個例子帶給我們一些思考:為啥幾家互聯(lián)網(wǎng)公司的 TPS 之和可以那么大缅阳,服務的用戶數(shù)規(guī)模也極為嚇人,而單個互聯(lián)網(wǎng)公司的 TPS 卻很難提升景描?

究其本質十办,每家互聯(lián)網(wǎng)公司都是一個獨立的大型單元秀撇,他們各自服務自己的用戶互不干擾。

這就是單元化的基本特性向族,任何一家互聯(lián)網(wǎng)公司呵燕,其想要成倍的擴大自己系統(tǒng)的服務能力,都必然會走向單元化之路件相。

它的本質是分治虏等,我們把廣大的用戶分為若干部分,同時把系統(tǒng)復制多份霍衫,每一份都獨立部署敦跌,每一份系統(tǒng)都服務特定的一群用戶柠傍。

以淘寶舉例,這樣之后辩稽,就會有很多個淘寶系統(tǒng)分別為不同的用戶服務惧笛,每個淘寶系統(tǒng)都做到十萬 TPS 的話,N 個這樣的系統(tǒng)就可以輕松做到 N*十萬的 TPS 了逞泄。

LDC 實現(xiàn)的關鍵就在于單元化系統(tǒng)架構設計患整,所以在螞蟻內部膏萧,LDC 和單元化是不分家的乎完,這也是很多同學比較困擾的地方殖告,看似沒啥關系迈着,實則是單元化體系設計成就了 LDC齐鲤。

小結:分庫分表解決的最大痛點是數(shù)據(jù)庫單點瓶頸昆码,這個瓶頸的產(chǎn)生是由現(xiàn)代二進制數(shù)據(jù)存儲體系決定的(即 I/O 速度)湿镀。

單元化只是分庫分表后系統(tǒng)部署的一種方式椎侠,這種部署模式在災備方面也發(fā)揮了極大的優(yōu)勢。

系統(tǒng)架構演化史

幾乎任何規(guī)模的互聯(lián)網(wǎng)公司,都有自己的系統(tǒng)架構迭代和更新,大致的演化路徑都大同小異鸠窗。

最早一般為了業(yè)務快速上線裕循,所有功能都會放到一個應用里,系統(tǒng)架構如下圖所示:

image

這樣的架構顯然是有問題的,單機有著明顯的單點效應,單機的容量和性能都是很局限的徒扶,而使用中小型機會帶來大量的浪費溶浴。

隨著業(yè)務發(fā)展闯两,這個矛盾逐漸轉變?yōu)橹饕苤芈虼斯こ處焸儾捎昧艘韵录軜嫞?/p>

image

這是整個公司第一次觸碰到分布式囚戚,也就是對某個應用進行了水平擴容,它將多個微機的計算能力團結了起來,可以完勝同等價格的中小型機器。

慢慢的,大家發(fā)現(xiàn)邦泄,應用服務器 CPU 都很正常了蕉拢,但是還是有很多慢請求,究其原因,是因為單點數(shù)據(jù)庫帶來了性能瓶頸。

于是程序員們決定使用主從結構的數(shù)據(jù)庫集群,如下圖所示:

image

其中大部分讀操作可以直接訪問從庫蜂大,從而減輕主庫的壓力。然而這種方式還是無法解決寫瓶頸,寫依舊需要主庫來處理,當業(yè)務量量級再次增高時泌枪,寫已經(jīng)變成刻不容緩的待處理瓶頸修壕。

這時候灌具,分庫分表方案出現(xiàn)了:

image

分庫分表不僅可以對相同的庫進行拆分诱贿,還可以對相同的表進行拆分宵睦,對表進行拆分的方式叫做水平拆分桐智。

不同功能的表放到不同的庫里刊驴,一般對應的是垂直拆分(按照業(yè)務功能進行拆分)捆憎,此時一般還對應了微服務化础拨。

這種方法做到極致基本能支撐 TPS 在萬級甚至更高的訪問量了僚焦。然而隨著相同應用擴展的越多边坤,每個數(shù)據(jù)庫的鏈接數(shù)也巨量增長名扛,這讓數(shù)據(jù)庫本身的資源成為了瓶頸。

這個問題產(chǎn)生的本質是全量數(shù)據(jù)無差別的分享了所有的應用資源茧痒,比如 A 用戶的請求在負載均衡的分配下可能分配到任意一個應用服務器上肮韧,因而所有應用全部都要鏈接 A 用戶所在的分庫拘领,數(shù)據(jù)庫連接數(shù)就變成笛卡爾乘積了。

在本質點說,這種模式的資源隔離性還不夠徹底污朽。要解決這個問題股囊,就需要把識別用戶分庫的邏輯往上層移動,從數(shù)據(jù)庫層移動到路由網(wǎng)關層膨更。

這樣一來,從應用服務器 a 進來的來自 A 客戶的所有請求必然落庫到 DB-A甫男,因此 a 也不用鏈接其他的數(shù)據(jù)庫實例了弧满,這樣一個單元化的雛形就誕生了未斑。

思考一下,應用間其實也存在交互(比如 A 轉賬給 B)岗喉,也就意味著撞叨,應用不需要鏈接其他的數(shù)據(jù)庫了芋簿,但是還需要鏈接其他應用。

如果是常見的 RPC 框架如 Dubbo 等蟀苛,使用的是 TCP/IP 協(xié)議益咬,那么等同于把之前與數(shù)據(jù)庫建立的鏈接,換成與其他應用之間的鏈接了。

為啥這樣就消除瓶頸了呢幽告?首先由于合理的設計梅鹦,應用間的數(shù)據(jù)交互并不巨量,其次應用間的交互可以共享 TCP 鏈接冗锁,比如 A->B 之間的 Socket 鏈接可以被 A 中的多個線程復用齐唆。

而一般的數(shù)據(jù)庫如 MySQL 則不行,所以 MySQL 才需要數(shù)據(jù)庫鏈接池冻河。

image

如上圖所示箍邮,但我們把整套系統(tǒng)打包為單元化時,每一類的數(shù)據(jù)從進單元開始就注定在這個單元被消化叨叙,由于這種徹底的隔離性锭弊,整個單元可以輕松的部署到任意機房而依然能保證邏輯上的統(tǒng)一。

下圖為一個三地五機房的部署方式:

image

螞蟻單元化架構實踐

螞蟻支付寶應該是國內最大的支付工具擂错,其在雙 11 等活動日當日的支付 TPS 可達幾十萬級味滞,未來這個數(shù)字可能會更大,這決定了螞蟻單元化架構從容量要求上看必然從單機房走向多機房钮呀。

另一方面剑鞍,異地災備也決定了這些 IDC 機房必須是異地部署的。整體上支付寶也采用了三地五中心(IDC 機房)來保障系統(tǒng)的可用性爽醋。

跟上文中描述的有所不同的是蚁署,支付寶將單元分成了三類(也稱 CRG 架構):

  • RZone(Region Zone直譯可能有點反而不好理解。實際上就是所有可以分庫分表的業(yè)務系統(tǒng)整體部署的最小單元蚂四。每個 RZone 連上數(shù)據(jù)庫就可以撐起一片天空光戈,把業(yè)務跑的溜溜的。

  • GZone(Global Zone):全局單元证杭,意味著全局只有一份田度。部署了不可拆分的數(shù)據(jù)和服務,比如系統(tǒng)配置等解愤。

    實際情況下镇饺,GZone 異地也會部署,不過僅是用于災備送讲,同一時刻奸笤,只有一地 GZone 進行全局服務。GZone 一般被 RZone 依賴哼鬓,提供的大部分是讀取服務监右。

  • CZone(City Zone):顧名思義,這是以城市為單位部署的單元异希。同樣部署了不可拆分的數(shù)據(jù)和服務健盒,比如用戶賬號服務,客戶信息服務等。理論上 CZone 會被 RZone 以比訪問 GZone 高很多的頻率進行訪問扣癣。

    CZone 是基于特定的 GZone 場景進行優(yōu)化的一種單元惰帽,它把 GZone 中有些有著”寫讀時間差現(xiàn)象”的數(shù)據(jù)和服務進行了的單獨部署,這樣 RZone 只需要訪問本地的 CZone 即可父虑,而不是訪問異地的 GZone该酗。

“寫讀時間差現(xiàn)象”是螞蟻架構師們根據(jù)實踐統(tǒng)計總結的,他們發(fā)現(xiàn)大部分情況下士嚎,一個數(shù)據(jù)被寫入后呜魄,都會過足夠長的時間后才會被訪問。

生活中這種例子很常見莱衩,我們辦完銀行卡后可能很久才會存第一筆錢爵嗅;我們創(chuàng)建微博賬號后,可能想半天才會發(fā)微博膳殷;我們下載創(chuàng)建淘寶賬號后操骡,可能得瀏覽好幾分鐘才會下單買東西。

當然了這些例子中的時間差遠遠超過了系統(tǒng)同步時間赚窃。一般來說異地的延時在 100ms 以內,所以只要滿足某地 CZone 寫入數(shù)據(jù)后 100ms 以后才用這個數(shù)據(jù)岔激,這樣的數(shù)據(jù)和服務就適合放到 CZone 中勒极。

相信大家看到這都會問:為啥分這三種單元?其實其背后對應的是不同性質的數(shù)據(jù)虑鼎,而服務不過是對數(shù)據(jù)的操作集辱匿。

下面我們來根據(jù)數(shù)據(jù)性質的不同來解釋支付寶的 CRG 架構。當下幾乎所有互聯(lián)網(wǎng)公司的分庫分表規(guī)則都是根據(jù)用戶 ID 來制定的炫彩。

而圍繞用戶來看整個系統(tǒng)的數(shù)據(jù)可以分為以下兩類:

用戶流水型數(shù)據(jù):典型的有用戶的訂單匾七、用戶發(fā)的評論、用戶的行為記錄等江兢。

這些數(shù)據(jù)都是用戶行為產(chǎn)生的流水型數(shù)據(jù)昨忆,具備天然的用戶隔離性,比如 A 用戶的 App 上絕對看不到 B 用戶的訂單列表杉允。所以此類數(shù)據(jù)非常適合分庫分表后獨立部署服務邑贴。

用戶間共享型數(shù)據(jù):這種類型的數(shù)據(jù)又分兩類。一類共享型數(shù)據(jù)是像賬號叔磷、個人博客等可能會被所有用戶請求訪問的用戶數(shù)據(jù)拢驾。

比如 A 向 B 轉賬,A 給 B 發(fā)消息改基,這時候需要確認 B 賬號是否存在繁疤;又比如 A 想看 B 的個人博客之類的。

另外一類是用戶無關型數(shù)據(jù),像商品稠腊、系統(tǒng)配置(匯率案疲、優(yōu)惠政策)、財務統(tǒng)計等這些非用戶緯度的數(shù)據(jù)麻养,很難說跟具體的某一類用戶掛鉤褐啡,可能涉及到所有用戶。

比如商品鳖昌,假設按商品所在地來存放商品數(shù)據(jù)(這需要雙維度分庫分表)备畦,那么上海的用戶仍然需要訪問杭州的商品。

這就又構成跨地跨 Zone 訪問了许昨,還是達不到單元化的理想狀態(tài)懂盐,而且雙維度分庫分表會給整個 LDC 運維帶來復雜度提升。

注:網(wǎng)上和支付寶內部有另外一些分法糕档,比如流水型和狀態(tài)性莉恼,有時候還會分為三類:流水型、狀態(tài)型和配置型速那。

個人覺得這些分法雖然嘗試去更高層次的抽象數(shù)據(jù)分類俐银,但實際上邊界很模糊,適得其反端仰。

直觀的類比捶惜,我們可以很輕易的將上述兩類數(shù)據(jù)對應的服務劃分為 RZone 和 GZone,RZone 包含的就是分庫分表后負責固定客戶群體的服務荔烧,GZone 則包含了用戶間共享的公共數(shù)據(jù)對應的服務吱七。

到這里為止,一切都很完美鹤竭,這也是主流的單元化話題了踊餐。對比支付寶的 CRG 架構,我們一眼就發(fā)現(xiàn)少了 C(City Zone)臀稚,CZone 確實是螞蟻在單元化實踐領域的一個創(chuàng)新點吝岭。

再來分析下 GZone,GZone 之所以只能單地部署烁涌,是因為其數(shù)據(jù)要求被所有用戶共享苍碟,無法分庫分表,而多地部署會帶來由異地延時引起的不一致撮执。

比如實時風控系統(tǒng)微峰,如果多地部署,某個 RZone 直接讀取本地的話抒钱,很容易讀取到舊的風控狀態(tài)蜓肆,這是很危險的颜凯。

這時螞蟻架構師們問了自己一個問題——難道所有數(shù)據(jù)受不了延時么?這個問題像是打開了新世界的大門仗扬,通過對 RZone 已有業(yè)務的分析症概,架構師們發(fā)現(xiàn) 80% 甚至更高的場景下,數(shù)據(jù)更新后都不要求立馬被讀取到早芭。

也就是上文提到的”寫讀時間差現(xiàn)象”彼城,那么這就好辦了,對于這類數(shù)據(jù)退个,我們允許每個地區(qū)的 RZone 服務直接訪問本地募壕,為了給這些 RZone 提供這些數(shù)據(jù)的本地訪問能力,螞蟻架構師設計出了 CZone语盈。

在 CZone 的場景下舱馅,寫請求一般從 GZone 寫入公共數(shù)據(jù)所在庫,然后同步到整個 OB 集群刀荒,然后由 CZone 提供讀取服務代嗤。比如支付寶的會員服務就是如此。

即便架構師們設計了完美的 CRG缠借,但即便在螞蟻的實際應用中干毅,各個系統(tǒng)仍然存在不合理的 CRG 分類,尤其是 CG 不分的現(xiàn)象很常見烈炭。

支付寶單元化的異地多活和災備

流量挑撥技術探秘簡介

單元化后溶锭,異地多活只是多地部署而已。比如上海的兩個單元為 ID 范圍為 [0019]符隙,[4059] 的用戶服務。

而杭州的兩個單元為 ID 為 [20~39]和[60,79]的用戶服務垫毙,這樣上海和杭州就是異地雙活的霹疫。

支付寶對單元化的基本要求是每個單元都具備服務所有用戶的能力,即——具體的那個單元服務哪些用戶是可以動態(tài)配置的综芥。所以異地雙活的這些單元還充當了彼此的備份丽蝎。

發(fā)現(xiàn)工作中冷備熱備已經(jīng)被用的很亂了。最早冷備是指數(shù)據(jù)庫在備份數(shù)據(jù)時需要關閉后進行備份(也叫離線備份)膀藐,防止數(shù)據(jù)備份過程中又修改了屠阻,不需要關閉即在運行過程中進行數(shù)據(jù)備份的方式叫做熱備(也叫在線備份)。

也不知道從哪一天開始额各,冷備在主備系統(tǒng)里代表了這臺備用機器是關閉狀態(tài)的国觉,只有主服務器掛了之后,備服務器才會被啟動虾啦。

而相同的熱備變成了備服務器也是啟動的麻诀,只是沒有流量而已痕寓,一旦主服務器掛了之后,流量自動打到備服務器上蝇闭。本文不打算用第二種理解呻率,因為感覺有點野。

為了做到每個單元訪問哪些用戶變成可配置呻引,支付寶要求單元化管理系統(tǒng)具備流量到單元的可配置以及單元到 DB 的可配置能力礼仗。

如下圖所示:

image

其中 Spanner 是螞蟻基于 Nginx 自研的反向代理網(wǎng)關,也很好理解逻悠,有些請求我們希望在反向代理層就被轉發(fā)至其他 IDC 的 Spanner 而無需進入后端服務元践,如圖箭頭 2 所示。

那么對于應該在本 IDC 處理的請求蹂风,就直接映射到對應的 RZ 即可卢厂,如圖箭頭 1。

進入后端服務后惠啄,理論上如果請求只是讀取用戶流水型數(shù)據(jù)慎恒,那么一般不會再進行路由了。

然而撵渡,對于有些場景來說融柬,A 用戶的一個請求可能關聯(lián)了對 B 用戶數(shù)據(jù)的訪問,比如 A 轉賬給 B趋距,A 扣完錢后要調用賬務系統(tǒng)去增加 B 的余額粒氧。

這時候就涉及到再次的路由,同樣有兩個結果:跳轉到其他 IDC(如圖箭頭 3)或是跳轉到本 IDC 的其他 RZone(如圖箭頭 4)节腐。

RZone 到 DB 數(shù)據(jù)分區(qū)的訪問這是事先配置好的迷守,上圖中 RZ 和 DB 數(shù)據(jù)分區(qū)的關系為:

RZ0* --> a
RZ1* --> b
RZ2* --> c
RZ3* --> d

下面我們舉個例子來說明整個流量挑撥的過程,假設 C 用戶所屬的數(shù)據(jù)分區(qū)是 c聋庵,而 C 用戶在杭州訪問了 cashier.alipay.com(隨便編的)炊邦。

目前支付寶默認會按照地域來路由流量,具體的實現(xiàn)承載者是自研的 GLSB(Global Server Load Balancing):

https://developer.alipay.com/article/1889

它會根據(jù)請求者的 IP狼渊,自動將 cashier.alipay.com 解析為杭州 IDC 的 IP 地址(或者跳轉到 IDC 所在的域名)箱熬。

大家自己搞過網(wǎng)站的化應該知道大部分 DNS 服務商的地址都是靠人去配置的,GLSB 屬于動態(tài)配置域名的系統(tǒng)狈邑,網(wǎng)上也有比較火的類似產(chǎn)品城须,比如花生殼之類(建過私站的同學應該很熟悉)的。

好了米苹,到此為止糕伐,用戶的請求來到了 IDC-1 的 Spanner 集群服務器上,Spanner 從內存中讀取到了路由配置驱入,知道了這個請求的主體用戶 C 所屬的 RZ3* 不再本 IDC赤炒,于是直接轉到了 IDC-2 進行處理氯析。

進入 IDC-2 之后,根據(jù)流量配比規(guī)則莺褒,該請求被分配到了 RZ3B 進行處理掩缓。

RZ3B 得到請求后對數(shù)據(jù)分區(qū) c 進行訪問。

處理完畢后原路返回遵岩。

大家應該發(fā)現(xiàn)問題所在了你辣,如果再來一個這樣的請求,豈不是每次都要跨地域進行調用和返回體傳遞尘执?

確實是存在這樣的問題的舍哄,對于這種問題,支付寶架構師們決定繼續(xù)把決策邏輯往用戶終端推移誊锭。

比如表悬,每個 IDC 機房都會有自己的域名(真實情況可能不是這樣命名的):

  • IDC-1 對應 cashieridc-1.alipay.com

  • IDC-2 對應 cashieridc-2.alipay.com

那么請求從 IDC-1 涮過一遍返回時會將前端請求跳轉到 cashieridc-2.alipay.com 去(如果是 App,只需要替換 rest 調用的接口域名)丧靡,后面所有用戶的行為都會在這個域名上發(fā)生蟆沫,就避免了走一遍 IDC-1 帶來的延時。

支付寶災備機制

流量挑撥是災備切換的基礎和前提條件温治,發(fā)生災難后的通用方法就是把陷入災難的單元的流量重新打到正常的單元上去饭庞,這個流量切換的過程俗稱切流。

支付寶 LDC 架構下的災備有三個層次:

  • 同機房單元間災備

  • 同城機房間災備

  • 異地機房間災備

同機房單元間災備:災難發(fā)生可能性相對最高(但其實也很邪揪!)舟山。對 LDC 來說,最小的災難就是某個單元由于一些原因(局部插座斷開卤恳、線路老化累盗、人為操作失誤)宕機了。

從上節(jié)里的圖中可以看到每組 RZ 都有 A突琳,B 兩個單元幅骄,這就是用來做同機房災備的,并且 AB 之間也是雙活雙備的本今。

正常情況下 AB 兩個單元共同分擔所有的請求,一旦 A 單元掛了主巍,B 單元將自動承擔 A 單元的流量份額冠息。這個災備方案是默認的。

同城機房間災備:災難發(fā)生可能性相對更小孕索。這種災難發(fā)生的原因一般是機房電線網(wǎng)線被挖斷逛艰,或者機房維護人員操作失誤導致的。

在這種情況下搞旭,就需要人工的制定流量挑撥(切流)方案了散怖。下面我們舉例說明這個過程菇绵,如下圖所示為上海的兩個 IDC 機房。

image

整個切流配置過程分兩步镇眷,首先需要將陷入災難的機房中 RZone 對應的數(shù)據(jù)分區(qū)的訪問權配置進行修改咬最。

假設我們的方案是由 IDC-2 機房的 RZ2 和 RZ3 分別接管 IDC-1 中的 RZ0 和 RZ1。

那么首先要做的是把數(shù)據(jù)分區(qū) a欠动,b 對應的訪問權從 RZ0 和 RZ1 收回永乌,分配給 RZ2 和 RZ3。

即將(如上圖所示為初始映射):

RZ0* --> a
RZ1* --> b
RZ2* --> c
RZ3* --> d

變?yōu)椋?/p>

RZ0* --> /
RZ1* --> /
RZ2* --> a
RZ2* --> c
RZ3* --> b
RZ3* --> d

然后再修改用戶 ID 和 RZ 之間的映射配置具伍。假設之前為:

[00-24] --> RZ0A(50%),RZOB(50%)
[25-49] --> RZ1A(50%),RZ1B(50%)
[50-74] --> RZ2A(50%),RZ2B(50%)
[75-99] --> RZ3A(50%),RZ3B(50%)

那么按照災備方案的要求翅雏,這個映射配置將變?yōu)椋?/p>

[00-24] --> RZ2A(50%),RZ2B(50%)
[25-49] --> RZ3A(50%),RZ3B(50%)
[50-74] --> RZ2A(50%),RZ2B(50%)
[75-99] --> RZ3A(50%),RZ3B(50%)

這樣之后,所有流量將會被打到 IDC-2 中人芽,期間部分已經(jīng)向 IDC-1 發(fā)起請求的用戶會收到失敗并重試的提示望几。

實際情況中,整個過程并不是災難發(fā)生后再去做的萤厅,整個切換的流程會以預案配置的形式事先準備好橄抹,推送給每個流量挑撥客戶端(集成到了所有的服務和 Spanner 中)。

這里可以思考下祈坠,為何先切數(shù)據(jù)庫映射害碾,再切流量呢?這是因為如果先切流量赦拘,意味著大量注定失敗的請求會被打到新的正常單元上去慌随,從而影響系統(tǒng)的穩(wěn)定性(數(shù)據(jù)庫還沒準備好)。

異地機房間災備:這個基本上跟同城機房間災備一致(這也是單元化的優(yōu)點)躺同,不再贅述阁猜。

支付寶單元化的異地多活和災備

回顧 CAP

①CAP 的定義

CAP 原則是指任意一個分布式系統(tǒng),同時最多只能滿足其中的兩項蹋艺,而無法同時滿足三項剃袍。

所謂的分布式系統(tǒng),說白了就是一件事一個人做的捎谨,現(xiàn)在分給好幾個人一起干民效。我們先簡單回顧下 CAP 各個維度的含義:

Consistency(一致性),這個理解起來很簡單涛救,就是每時每刻每個節(jié)點上的同一份數(shù)據(jù)都是一致的畏邢。

這就要求任何更新都是原子的,即要么全部成功检吆,要么全部失敗舒萎。想象一下使用分布式事務來保證所有系統(tǒng)的原子性是多么低效的一個操作。

Availability(可用性)蹭沛,這個可用性看起來很容易理解臂寝,但真正說清楚的不多章鲤。我更愿意把可用性解釋為:任意時刻系統(tǒng)都可以提供讀寫服務。

舉個例子咆贬,當我們用事務將所有節(jié)點鎖住來進行某種寫操作時败徊,如果某個節(jié)點發(fā)生不可用的情況,會讓整個系統(tǒng)不可用素征。

對于分片式的 NoSQL 中間件集群(Redis集嵌,Memcached)來說,一旦一個分片歇菜了御毅,整個系統(tǒng)的數(shù)據(jù)也就不完整了根欧,讀取宕機分片的數(shù)據(jù)就會沒響應,也就是不可用了端蛆。

需要說明一點凤粗,哪些選擇 CP 的分布式系統(tǒng),并不是代表可用性就完全沒有了今豆,只是可用性沒有保障了嫌拣。

為了增加可用性保障,這類中間件往往都提供了”分片集群+復制集”的方案呆躲。

Partition tolerance(分區(qū)容忍性)异逐,這個可能也是很多文章都沒說清楚的。P 并不是像 CA 一樣是一個獨立的性質插掂,它依托于 CA 來進行討論灰瞻。

參考文獻中的解釋:”除非整個網(wǎng)絡癱瘓,否則任何時刻系統(tǒng)都能正常工作”辅甥,言下之意是小范圍的網(wǎng)絡癱瘓酝润,節(jié)點宕機,都不會影響整個系統(tǒng)的 CA璃弄。

我感覺這個解釋聽著還是有點懵逼要销,所以個人更愿意解釋為當節(jié)點之間網(wǎng)絡不通時(出現(xiàn)網(wǎng)絡分區(qū)),可用性和一致性仍然能得到保障夏块。

從個人角度理解疏咐,分區(qū)容忍性又分為“可用性分區(qū)容忍性”和“一致性分區(qū)容忍性”。

出現(xiàn)分區(qū)時會不會影響可用性的關鍵在于需不需要所有節(jié)點互相溝通協(xié)作來完成一次事務脐供,不需要的話是鐵定不影響可用性的凳鬓。

慶幸的是應該不太會有分布式系統(tǒng)會被設計成完成一次事務需要所有節(jié)點聯(lián)動,一定要舉個例子的話患民,全同步復制技術下的 MySQL 是一個典型案例。

出現(xiàn)分區(qū)時會不會影響一致性的關鍵則在于出現(xiàn)腦裂時有沒有保證一致性的方案垦梆,這對主從同步型數(shù)據(jù)庫(MySQL匹颤、SQL Server)是致命的仅孩。

一旦網(wǎng)絡出現(xiàn)分區(qū),產(chǎn)生腦裂印蓖,系統(tǒng)會出現(xiàn)一份數(shù)據(jù)兩個值的狀態(tài)辽慕,誰都不覺得自己是錯的。

需要說明的是赦肃,正常來說同一局域網(wǎng)內溅蛉,網(wǎng)絡分區(qū)的概率非常低,這也是為啥我們最熟悉的數(shù)據(jù)庫(MySQL他宛、SQL Server 等)也是不考慮 P 的原因船侧。

下圖為 CAP 之間的經(jīng)典關系圖:

image

還有個需要說明的地方,其實分布式系統(tǒng)很難滿足 CAP 的前提條件是這個系統(tǒng)一定是有讀有寫的厅各,如果只考慮讀镜撩,那么 CAP 很容易都滿足。

比如一個計算器服務队塘,接受表達式請求袁梗,返回計算結果,搞成水平擴展的分布式憔古,顯然這樣的系統(tǒng)沒有一致性問題遮怜,網(wǎng)絡分區(qū)也不怕,可用性也是很穩(wěn)的鸿市,所以可以滿足 CAP锯梁。

②CAP 分析方法

先說下 CA 和 P 的關系,如果不考慮 P 的話灸芳,系統(tǒng)是可以輕松實現(xiàn) CA 的涝桅。

而 P 并不是一個單獨的性質,它代表的是目標分布式系統(tǒng)有沒有對網(wǎng)絡分區(qū)的情況做容錯處理烙样。

如果做了處理冯遂,就一定是帶有 P 的,接下來再考慮分區(qū)情況下到底選擇了 A 還是 C谒获。所以分析 CAP蛤肌,建議先確定有沒有對分區(qū)情況做容錯處理。

以下是個人總結的分析一個分布式系統(tǒng) CAP 滿足情況的一般方法:

if( 不存在分區(qū)的可能性 || 分區(qū)后不影響可用性或一致性 || 有影響但考慮了分區(qū)情況-P){
    if(可用性分區(qū)容忍性-A under P))
      return "AP";
    else if(一致性分區(qū)容忍性-C under P)
      return "CP";
}
else{  //分區(qū)有影響但沒考慮分區(qū)情況下的容錯
     if(具備可用性-A && 具備一致性-C){
         return AC;
     }
}

這里說明下批狱,如果考慮了分區(qū)容忍性裸准,就不需要考慮不分區(qū)情況下的可用性和一致性了(大多是滿足的)。

水平擴展應用+單數(shù)據(jù)庫實例的 CAP 分析

讓我們再來回顧下分布式應用系統(tǒng)的來由赔硫,早年每個應用都是單體的炒俱,跑在一個服務器上,服務器一掛,服務就不可用了权悟。

另外一方面砸王,單體應用由于業(yè)務功能復雜,對機器的要求也逐漸變高峦阁,普通的微機無法滿足這種性能和容量的要求谦铃。

所以要拆!還在 IBM 大賣小型商用機的年代榔昔,阿里巴巴就提出要以分布式微機替代小型機驹闰。

所以我們發(fā)現(xiàn),分布式系統(tǒng)解決的最大的痛點撒会,就是單體單機系統(tǒng)的可用性問題嘹朗。

要想高可用,必須分布式茧彤。一家互聯(lián)網(wǎng)公司的發(fā)展之路上骡显,第一次與分布式相遇應該都是在單體應用的水平擴展上。

也就是同一個應用啟動了多個實例曾掂,連接著相同的數(shù)據(jù)庫(為了簡化問題惫谤,先不考慮數(shù)據(jù)庫是否單點),如下圖所示:

image

這樣的系統(tǒng)天然具有的就是 AP(可用性和分區(qū)容忍性):

  • 一方面解決了單點導致的低可用性問題珠洗。

  • 另一方面無論這些水平擴展的機器間網(wǎng)絡是否出現(xiàn)分區(qū)溜歪,這些服務器都可以各自提供服務,因為他們之間不需要進行溝通许蓖。

然而蝴猪,這樣的系統(tǒng)是沒有一致性可言的,想象一下每個實例都可以往數(shù)據(jù)庫 insert 和 update(注意這里還沒討論到事務)膊爪,那還不亂了套自阱。

于是我們轉向了讓 DB 去做這個事,這時候”數(shù)據(jù)庫事務”就被用上了米酬。用大部分公司會選擇的 MySQL 來舉例沛豌,用了事務之后會發(fā)現(xiàn)數(shù)據(jù)庫又變成了單點和瓶頸。

單點就像單機一樣(本例子中不考慮從庫模式)赃额,理論上就不叫分布式了加派,如果一定要分析其 CAP 的話,根據(jù)上面的步驟分析過程應該是這樣的:

  • 分區(qū)容忍性:先看有沒有考慮分區(qū)容忍性跳芳,或者分區(qū)后是否會有影響芍锦。單臺 MySQL 無法構成分區(qū),要么整個系統(tǒng)掛了飞盆,要么就活著娄琉。

  • 可用性分區(qū)容忍性:分區(qū)情況下次乓,假設恰好是該節(jié)點掛了,系統(tǒng)也就不可用了车胡,所以可用性分區(qū)容忍性不滿足檬输。

  • 一致性分區(qū)容忍性:分區(qū)情況下,只要可用匈棘,單點單機的最大好處就是一致性可以得到保障。

因此這樣的一個系統(tǒng)析命,個人認為只是滿足了 CP主卫。A 有但不出色,從這點可以看出鹃愤,CAP 并不是非黑即白的簇搅。

包括常說的 BASE (最終一致性)方案,其實只是 C 不出色软吐,但最終也是達到一致性的瘩将,BASE 在一致性上選擇了退讓。

關于分布式應用+單點數(shù)據(jù)庫的模式算不算純正的分布式系統(tǒng)凹耙,這個可能每個人看法有點差異姿现,上述只是我個人的一種理解,是不是分布式系統(tǒng)不重要肖抱,重要的是分析過程备典。

其實我們討論分布式,就是希望系統(tǒng)的可用性是多個系統(tǒng)多活的意述,一個掛了另外的也能頂上提佣,顯然單機單點的系統(tǒng)不具備這樣的高可用特性。

所以在我看來荤崇,廣義的說 CAP 也適用于單點單機系統(tǒng)拌屏,單機系統(tǒng)是 CP 的。

說到這里术荤,大家似乎也發(fā)現(xiàn)了倚喂,水平擴展的服務應用+數(shù)據(jù)庫這樣的系統(tǒng)的 CAP 魔咒主要發(fā)生在數(shù)據(jù)庫層。

因為大部分這樣的服務應用都只是承擔了計算的任務(像計算器那樣)喜每,本身不需要互相協(xié)作务唐,所有寫請求帶來的數(shù)據(jù)的一致性問題下沉到了數(shù)據(jù)庫層去解決。

想象一下带兜,如果沒有數(shù)據(jù)庫層枫笛,而是應用自己來保障數(shù)據(jù)一致性,那么這樣的應用之間就涉及到狀態(tài)的同步和交互了刚照,ZooKeeper 就是這么一個典型的例子刑巧。

水平擴展應用+主從數(shù)據(jù)庫集群的CAP分析

上一節(jié)我們討論了多應用實例+單數(shù)據(jù)庫實例的模式,這種模式是分布式系統(tǒng)也好,不是分布式系統(tǒng)也罷啊楚,整體是偏 CP 的吠冤。

現(xiàn)實中,技術人員們也會很快發(fā)現(xiàn)這種架構的不合理性——可用性太低了恭理。

于是如下圖所示的模式成為了當下大部分中小公司所使用的架構:

image

從上圖我可以看到三個數(shù)據(jù)庫實例中只有一個是主庫拯辙,其他是從庫。

一定程度上颜价,這種架構極大的緩解了”讀可用性”問題涯保,而這樣的架構一般會做讀寫分離來達到更高的”讀可用性”,幸運的是大部分互聯(lián)網(wǎng)場景中讀都占了 80% 以上周伦,所以這樣的架構能得到較長時間的廣泛應用夕春。

寫可用性可以通過 Keepalived 這種 HA(高可用)框架來保證主庫是活著的,但仔細一想就可以明白专挪,這種方式并沒有帶來性能上的可用性提升及志。還好,至少系統(tǒng)不會因為某個實例掛了就都不可用了寨腔。

可用性勉強達標了速侈,這時候的 CAP 分析如下:

  • 分區(qū)容忍性:依舊先看分區(qū)容忍性,主從結構的數(shù)據(jù)庫存在節(jié)點之間的通信脆侮,他們之間需要通過心跳來保證只有一個 Master锌畸。

    然而一旦發(fā)生分區(qū),每個分區(qū)會自己選取一個新的 Master靖避,這樣就出現(xiàn)了腦裂潭枣,常見的主從數(shù)據(jù)庫(MySQL,Oracle 等)并沒有自帶解決腦裂的方案幻捏。所以分區(qū)容忍性是沒考慮的氯庆。

  • 一致性:不考慮分區(qū)冗懦,由于任意時刻只有一個主庫摊溶,所以一致性是滿足的墨礁。

  • 可用性:不考慮分區(qū),HA 機制的存在可以保證可用性榛臼,所以可用性顯然也是滿足的伊佃。

所以這樣的一個系統(tǒng),我們認為它是 AC 的沛善。我們再深入研究下航揉,如果發(fā)生腦裂產(chǎn)生數(shù)據(jù)不一致后有一種方式可以仲裁一致性問題,是不是就可以滿足 P 了呢金刁。

還真有嘗試通過預先設置規(guī)則來解決這種多主庫帶來的一致性問題的系統(tǒng)帅涂,比如 CouchDB议薪,它通過版本管理來支持多庫寫入,在其仲裁階段會通過 DBA 配置的仲裁規(guī)則(也就是合并規(guī)則媳友,比如誰的時間戳最晚誰的生效)進行自動仲裁(自動合并)斯议,從而保障最終一致性(BASE),自動規(guī)則無法合并的情況則只能依賴人工決策了醇锚。

螞蟻單元化 LDC 架構 CAP 分析

①戰(zhàn)勝分區(qū)容忍性

在討論螞蟻 LDC 架構的 CAP 之前哼御,我們再來想想分區(qū)容忍性有啥值得一提的,為啥很多大名鼎鼎的 BASE(最終一致性)體系系統(tǒng)都選擇損失實時一致性焊唬,而不是丟棄分區(qū)容忍性呢艇搀?

分區(qū)的產(chǎn)生一般有兩種情況:

某臺機器宕機了,過一會兒又重啟了求晶,看起來就像失聯(lián)了一段時間,像是網(wǎng)絡不可達一樣衷笋。

異地部署情況下芳杏,異地多活意味著每一地都可能會產(chǎn)生數(shù)據(jù)寫入,而異地之間偶爾的網(wǎng)絡延時尖刺(網(wǎng)絡延時曲線圖陡增)辟宗、網(wǎng)絡故障都會導致小范圍的網(wǎng)絡分區(qū)產(chǎn)生爵赵。

前文也提到過,如果一個分布式系統(tǒng)是部署在一個局域網(wǎng)內的(一個物理機房內)泊脐,那么個人認為分區(qū)的概率極低空幻,即便有復雜的拓撲,也很少會有在同一個機房里出現(xiàn)網(wǎng)絡分區(qū)的情況容客。

而異地這個概率會大大增高秕铛,所以螞蟻的三地五中心必須需要思考這樣的問題,分區(qū)容忍不能丟缩挑!

同樣的情況還會發(fā)生在不同 ISP 的機房之間(想象一下你和朋友組隊玩 DOTA但两,他在電信,你在聯(lián)通)供置。

為了應對某一時刻某個機房突發(fā)的網(wǎng)絡延時尖刺活著間歇性失聯(lián)谨湘,一個好的分布式系統(tǒng)一定能處理好這種情況下的一致性問題。

那么螞蟻是怎么解決這個問題的呢芥丧?我們在上文討論過紧阔,其實 LDC 機房的各個單元都由兩部分組成:負責業(yè)務邏輯計算的應用服務器和負責數(shù)據(jù)持久化的數(shù)據(jù)庫。

大部分應用服務器就像一個個計算器续担,自身是不對寫一致性負責的擅耽,這個任務被下沉到了數(shù)據(jù)庫。所以螞蟻解決分布式一致性問題的關鍵就在于數(shù)據(jù)庫赤拒!

想必螞蟻的讀者大概猜到下面的討論重點了——OceanBase(下文簡稱OB)秫筏,中國第一款自主研發(fā)的分布式數(shù)據(jù)庫诱鞠,一時間也確實獲得了很多光環(huán)。

在討論 OB 前这敬,我們先來想想 Why not MySQL航夺?

首先,就像 CAP 三角圖中指出的崔涂,MySQL 是一款滿足 AC 但不滿足 P 的分布式系統(tǒng)阳掐。

試想一下,一個 MySQL 主從結構的數(shù)據(jù)庫集群冷蚂,當出現(xiàn)分區(qū)時缭保,問題分區(qū)內的 Slave 會認為主已經(jīng)掛了,所以自己成為本分區(qū)的 Master(腦裂)蝙茶。

等分區(qū)問題恢復后艺骂,會產(chǎn)生 2 個主庫的數(shù)據(jù),而無法確定誰是正確的隆夯,也就是分區(qū)導致了一致性被破壞钳恕。這樣的結果是嚴重的,這也是螞蟻寧愿自研 OceanBase 的原動力之一蹄衷。

那么如何才能讓分布式系統(tǒng)具備分區(qū)容忍性呢忧额?按照老慣例,我們從”可用性分區(qū)容忍”和”一致性分區(qū)容忍”兩個方面來討論:

可用性分區(qū)容忍性保障機制:可用性分區(qū)容忍的關鍵在于別讓一個事務一來所有節(jié)點來完成愧口,這個很簡單睦番,別要求所有節(jié)點共同同時參與某個事務即可。

一致性分區(qū)容忍性保障機制:老實說耍属,都產(chǎn)生分區(qū)了托嚣,哪還可能獲得實時一致性。

但要保證最終一致性也不簡單恬涧,一旦產(chǎn)生分區(qū)注益,如何保證同一時刻只會產(chǎn)生一份提議呢?

換句話說溯捆,如何保障仍然只有一個腦呢丑搔?下面我們來看下 PAXOS 算法是如何解決腦裂問題的。

這里可以發(fā)散下提揍,所謂的“腦”其實就是具備寫能力的系統(tǒng)啤月,“非腦”就是只具備讀能力的系統(tǒng),對應了 MySQL 集群中的從庫劳跃。

下面是一段摘自維基百科的 PAXOS 定義:

Paxos is a family of protocols for solving consensus in a network of unreliable processors (that is, processors that may fail).

大致意思就是說谎仲,PAXOS 是在一群不是特別可靠的節(jié)點組成的集群中的一種共識機制。

Paxos 要求任何一個提議刨仑,至少有 (N/2)+1 的系統(tǒng)節(jié)點認可郑诺,才被認為是可信的夹姥,這背后的一個基礎理論是少數(shù)服從多數(shù)。

想象一下辙诞,如果多數(shù)節(jié)點認可后辙售,整個系統(tǒng)宕機了,重啟后飞涂,仍然可以通過一次投票知道哪個值是合法的(多數(shù)節(jié)點保留的那個值)旦部。

這樣的設定也巧妙的解決了分區(qū)情況下的共識問題,因為一旦產(chǎn)生分區(qū)较店,勢必最多只有一個分區(qū)內的節(jié)點數(shù)量會大于等于 (N/2)+1士八。

通過這樣的設計就可以巧妙的避開腦裂,當然 MySQL 集群的腦裂問題也是可以通過其他方法來解決的梁呈,比如同時 Ping 一個公共的 IP婚度,成功者繼續(xù)為腦,顯然這就又制造了另外一個單點官卡。

如果你了解過比特幣或者區(qū)塊鏈陕见,你就知道區(qū)塊鏈的基礎理論也是 PAXOS。區(qū)塊鏈借助 PAXOS 對最終一致性的貢獻來抵御惡意篡改味抖。

而本文涉及的分布式應用系統(tǒng)則是通過 PAXOS 來解決分區(qū)容忍性。再說本質一點灰粮,一個是抵御部分節(jié)點變壞仔涩,一個是防范部分節(jié)點失聯(lián)。

大家一定聽說過這樣的描述:PAXOS 是唯一能解決分布式一致性問題的解法粘舟。

這句話越是理解越發(fā)覺得詭異熔脂,這會讓人以為 PAXOS 逃離于 CAP 約束了,所以個人更愿意理解為:PAXOS 是唯一一種保障分布式系統(tǒng)最終一致性的共識算法(所謂共識算法柑肴,就是大家都按照這個算法來操作霞揉,大家最后的結果一定相同)。

PAXOS 并沒有逃離 CAP 魔咒晰骑,畢竟達成共識是 (N/2)+1 的節(jié)點之間的事适秩,剩下的 (N/2)-1 的節(jié)點上的數(shù)據(jù)還是舊的,這時候仍然是不一致的硕舆。

所以 PAXOS 對一致性的貢獻在于經(jīng)過一次事務后秽荞,這個集群里已經(jīng)有部分節(jié)點保有了本次事務正確的結果(共識的結果),這個結果隨后會被異步的同步到其他節(jié)點上抚官,從而保證最終一致性扬跋。

以下摘自維基百科:

Paxos is a family of protocols for solving consensus in a network of unreliable processors (that is, processors that may fail).Quorums express the safety (or consistency) properties of Paxos by ensuring at least some surviving processor retains knowledge of the results.

另外 PAXOS 不要求對所有節(jié)點做實時同步,實質上是考慮到了分區(qū)情況下的可用性凌节,通過減少完成一次事務需要的參與者個數(shù)钦听,來保障系統(tǒng)的可用性洒试。

②OceanBase 的 CAP 分析

上文提到過,單元化架構中的成千山萬的應用就像是計算器朴上,本身無 CAP 限制垒棋,其 CAP 限制下沉到了其數(shù)據(jù)庫層,也就是螞蟻自研的分布式數(shù)據(jù)庫 OceanBase(本節(jié)簡稱 OB)余指。

在 OB 體系中捕犬,每個數(shù)據(jù)庫實例都具備讀寫能力,具體是讀是寫可以動態(tài)配置(參考第二部分)酵镜。

實際情況下大部分時候碉碉,對于某一類數(shù)據(jù)(固定用戶號段的數(shù)據(jù))任意時刻只有一個單元會負責寫入某個節(jié)點,其他節(jié)點要么是實時庫間同步淮韭,要么是異步數(shù)據(jù)同步垢粮。

OB 也采用了 PAXOS 共識協(xié)議。實時庫間同步的節(jié)點(包含自己)個數(shù)至少需要 (N/2)+1 個靠粪,這樣就可以解決分區(qū)容忍性問題蜡吧。

下面我們舉個馬老師改英文名的例子來說明 OB 設計的精妙之處:

假設數(shù)據(jù)庫按照用戶 ID 分庫分表,馬老師的用戶 ID 對應的數(shù)據(jù)段在 [0-9]占键,開始由單元 A 負責數(shù)據(jù)寫入昔善。

假如馬老師(用戶 ID 假設為 000)正在用支付寶 App 修改自己的英文名,馬老師一開始打錯了畔乙,打成了 Jason Ma君仆,A 單元收到了這個請求。

這時候發(fā)生了分區(qū)(比如 A 網(wǎng)絡斷開了)牲距,我們將單元 A 對數(shù)據(jù)段 [0,9] 的寫入權限轉交給單元 B(更改映射)返咱,馬老師這次寫對了,為 Jack Ma牍鞠。

而在網(wǎng)絡斷開前請求已經(jīng)進入了 A咖摹,寫權限轉交給單元 B 生效后,A 和 B 同時對 [0,9] 數(shù)據(jù)段進行寫入馬老師的英文名难述。

假如這時候都允許寫入的話就會出現(xiàn)不一致萤晴,A 單元說我看到馬老師設置了 Jason Ma,B 單元說我看到馬老師設置了 Jack Ma胁后。

然而這種情況不會發(fā)生的硫眯,A 提議說我建議把馬老師的英文名設置為 Jason Ma 時,發(fā)現(xiàn)沒人回應它择同。

因為出現(xiàn)了分區(qū)两入,其他節(jié)點對它來說都是不可達的,所以這個提議被自動丟棄敲才,A 心里也明白是自己分區(qū)了裹纳,會有主分區(qū)替自己完成寫入任務的择葡。

同樣的,B 提出了將馬老師的英文名改成 Jack Ma 后剃氧,大部分節(jié)點都響應了敏储,所以 B 成功將 Jack Ma 寫入了馬老師的賬號記錄。

假如在寫權限轉交給單元 B 后 A 突然恢復了朋鞍,也沒關系已添,兩筆寫請求同時要求獲得 (N/2)+1 個節(jié)點的事務鎖,通過 no-wait 設計滥酥,在 B 獲得了鎖之后更舞,其他爭搶該鎖的事務都會因為失敗而回滾。

下面我們分析下 OB 的 CAP:

  • 分區(qū)容忍性:OB 節(jié)點之間是有互相通信的(需要相互同步數(shù)據(jù))坎吻,所以存在分區(qū)問題缆蝉,OB 通過僅同步到部分節(jié)點來保證可用性。這一點就說明 OB 做了分區(qū)容錯瘦真。

  • 可用性分區(qū)容忍性:OB 事務只需要同步到 (N/2)+1 個節(jié)點刊头,允許其余的一小半節(jié)點分區(qū)(宕機、斷網(wǎng)等)诸尽,只要 (N/2)+1 個節(jié)點活著就是可用的原杂。

    極端情況下,比如 5 個節(jié)點分成 3 份(2:2:1)您机,那就確實不可用了污尉,只是這種情況概率比較低。

  • 一致性分區(qū)容忍性:分區(qū)情況下意味著部分節(jié)點失聯(lián)了往产,一致性顯然是不滿足的。但通過共識算法可以保證當下只有一個值是合法的某宪,并且最終會通過節(jié)點間的同步達到最終一致性仿村。

所以 OB 仍然沒有逃脫 CAP 魔咒,產(chǎn)生分區(qū)的時候它變成 AP+最終一致性(C)兴喂。整體來說蔼囊,它是 AP 的,即高可用和分區(qū)容忍衣迷。

結語

個人感覺本文涉及到的知識面確實不少畏鼓,每個點單獨展開都可以討論半天『耍回到我們緊扣的主旨來看云矫,雙十一海量支付背后技術上大快人心的設計到底是啥?

我想無非是以下幾點:

  • 基于用戶分庫分表的 RZone 設計汗菜。每個用戶群獨占一個單元給整個系統(tǒng)的容量帶來了爆發(fā)式增長让禀。

  • RZone 在網(wǎng)絡分區(qū)或災備切換時 OB 的防腦裂設計(PAXOS)挑社。我們知道 RZone 是單腦的(讀寫都在一個單元對應的庫),而網(wǎng)絡分區(qū)或者災備時熱切換過程中可能會產(chǎn)生多個腦巡揍,OB 解決了腦裂情況下的共識問題(PAXOS 算法)痛阻。

  • 基于 CZone 的本地讀設計。這一點保證了很大一部分有著“寫讀時間差”現(xiàn)象的公共數(shù)據(jù)能被高速本地訪問腮敌。

  • 剩下的那一丟丟不能本地訪問只能實時訪問 GZone 的公共配置數(shù)據(jù)阱当,也興不起什么風,作不了什么浪糜工。

    比如用戶創(chuàng)建這種 TPS弊添,不會高到哪里去。再比如對于實時庫存數(shù)據(jù)啤斗,可以通過“頁面展示查詢走應用層緩存”+“實際下單時再校驗”的方式減少其 GZone 調用量表箭。

而這就是螞蟻 LDC 的 CRG 架構,相信 54.4 萬筆/秒還遠沒到 LDC 的上限钮莲,這個數(shù)字可以做到更高免钻。

當然雙 11 海量支付的成功不單單是這么一套設計所決定的,還有預熱削峰等運營+技術的手段崔拥,以及成百上千的兄弟姐妹共同奮戰(zhàn)极舔,特此在這向各位雙 11 留守同學致敬。

感謝大家的閱讀链瓦,文中可能存在不足或遺漏之處拆魏,歡迎批評指正。

參考文獻:

作者:湯波

簡介:阿里巴巴架構師慈俯,熱愛技術渤刃,深信技術讓世界更美好。對前沿技術一直保持饑餓感贴膘,熱衷于創(chuàng)新和革新卖子,讓系統(tǒng)體制更為高效和人性化,也深知一個人強走的快刑峡,一個團體強才能走的遠洋闽。在技術團隊建設(團隊招聘和組建、梯隊梯度建設)突梦、技術棧管理(包含技術選型诫舅、技術規(guī)范建設、軟件體系規(guī)劃)和項目研發(fā)管理(軟件工程管理宫患、開發(fā)效能和質量管理)方面有著較為豐富的實踐經(jīng)驗刊懈。關注領域:SaaS,PaaS,Serverless俏讹,Service mesh当宴,新零售,區(qū)塊鏈泽疆,人工智能户矢,互聯(lián)網(wǎng)全棧,分布式企業(yè)級開發(fā)殉疼,網(wǎng)絡應用/協(xié)議開發(fā)梯浪,計算機算法應用。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末瓢娜,一起剝皮案震驚了整個濱河市挂洛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌眠砾,老刑警劉巖虏劲,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異褒颈,居然都是意外死亡柒巫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門谷丸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來堡掏,“玉大人,你說我怎么就攤上這事刨疼∪洌” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵揩慕,是天一觀的道長亭畜。 經(jīng)常有香客問我,道長迎卤,這世上最難降的妖魔是什么拴鸵? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮止吐,結果婚禮上,老公的妹妹穿的比我還像新娘侨糟。我一直安慰自己碍扔,他們只是感情好,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布秕重。 她就那樣靜靜地躺著不同,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上二拐,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天服鹅,我揣著相機與錄音,去河邊找鬼百新。 笑死企软,一個胖子當著我的面吹牛,可吹牛的內容都是我干的饭望。 我是一名探鬼主播仗哨,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼铅辞!你這毒婦竟也來了厌漂?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤斟珊,失蹤者是張志新(化名)和其女友劉穎苇倡,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體囤踩,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡旨椒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了高职。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钩乍。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖怔锌,靈堂內的尸體忽然破棺而出催束,到底是詐尸還是另有隱情冈敛,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站滩报,受9級特大地震影響,放射性物質發(fā)生泄漏躯嫉。R本人自食惡果不足惜壶唤,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望类嗤。 院中可真熱鬧糊肠,春花似錦、人聲如沸遗锣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽精偿。三九已至弧圆,卻和暖如春赋兵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搔预。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工霹期, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拯田。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓历造,卻偏偏與公主長得像,于是被迫代替她去往敵國和親勿锅。 傳聞我的和親對象是個殘疾皇子帕膜,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348