微信支付核心訂單系統(tǒng)的架構(gòu)是怎樣實(shí)現(xiàn)的?
對于支付寶和微信支付這樣的國民應(yīng)用,海量交易帶來的系統(tǒng)可用性問題成了關(guān)乎國計民生的問題。本文總結(jié)了微信支付的核心訂單系統(tǒng)的架構(gòu)實(shí)現(xiàn),以及海量交易所帶來的擴(kuò)容、成本、容災(zāi)和灰度等問題及解決方案,最終通過系統(tǒng)架構(gòu)多次迭代確立基于 Mysql 單機(jī)存儲引擎,業(yè)務(wù)和存儲強(qiáng)耦的高可用的分布式訂單系統(tǒng)。
本文主要講述了基于條帶構(gòu)建的高可用分布式訂單存儲系統(tǒng),條帶是由無狀態(tài)服務(wù)和有狀態(tài)存儲服務(wù)組成的條帶架構(gòu)的基本單元,通過條帶可以實(shí)現(xiàn)線性擴(kuò)縮容的能力;在下單時通過跳單的操作可以允許一次下單重試更換到可用的條帶,這樣可以應(yīng)對少數(shù)條帶不可用帶來的下單不可用問題;同時基于條帶的架構(gòu)也帶了冷熱分離、故障壓縮、差異服務(wù)、熱點(diǎn)均衡和灰度控制的能力。
基于條帶化的架構(gòu)雖然帶來很多優(yōu)點(diǎn),但同時也造成業(yè)務(wù)和存儲強(qiáng)耦合,另外業(yè)務(wù)開發(fā)人員在開發(fā)時也需要了解整體架構(gòu)不能更加專注業(yè)務(wù)邏輯。
1. 簡介
隨著移動支付的飛速發(fā)展,移動支付用戶量持續(xù)增加,移動支付已悄無聲息的融入到國民的生活并且產(chǎn)生重要的作用。
在支付系統(tǒng)中,一筆交易往往需要多個相關(guān)系統(tǒng)的協(xié)作完成,其中包括支付產(chǎn)品系統(tǒng)、訂單交易系統(tǒng)、風(fēng)控系統(tǒng)、支付系統(tǒng)、賬號系統(tǒng)、商戶系統(tǒng)、賬戶系統(tǒng)和清結(jié)算系統(tǒng)等等。在一個交易系統(tǒng)中一筆交易是通過一筆訂單進(jìn)行標(biāo)識的,訂單系統(tǒng)需要提供創(chuàng)建訂單、支付訂單、查詢訂單、關(guān)閉訂單和訂單退款的能力。
訂單系統(tǒng)作為其它系統(tǒng)的依賴系統(tǒng),它的可用性將直接影響整個交易系統(tǒng)的可用性。交易系統(tǒng)的可用性將直接影響用戶的交易體驗和整個品牌的口碑。
傳統(tǒng)的銀行都是基于大型的商業(yè)服務(wù)器和正版授權(quán)的數(shù)據(jù)庫軟件構(gòu)建自己的交易系統(tǒng),互聯(lián)網(wǎng)有別于傳統(tǒng)銀行,往往是采用小型廉價的商業(yè)服務(wù)器和開源的數(shù)據(jù)庫軟件構(gòu)建自己的交易系統(tǒng)。
另外傳統(tǒng)銀行的交易系統(tǒng)是集中式的,而互聯(lián)網(wǎng)企業(yè)多采用分布式系統(tǒng)構(gòu)建自己的系統(tǒng),這樣對數(shù)據(jù)的一致性、災(zāi)備、可用性提出更高的要求。對于大型企業(yè)或者第三方數(shù)據(jù)庫公司,它們會研發(fā)一些自己的分布式數(shù)據(jù)庫存儲,例如 OceanBase、TiDB 等。但是很多企業(yè)還是會采用開源的 mysql 作為自己的數(shù)據(jù)庫系統(tǒng),一種基于 mysql 實(shí)現(xiàn)的易擴(kuò)展、高可用支持海量存儲的訂單交易系統(tǒng)對于是一個企業(yè)也是一種很好的方案選擇。
本文會討論一種基于 mysql 構(gòu)建的海量訂單交易系統(tǒng),高可用和易擴(kuò)展作為整個系統(tǒng)兩個主要特征。為達(dá)到整個系統(tǒng)的高可用,可用性主要包含三種改進(jìn):
- 通過使用 HaProxy 來進(jìn)行數(shù)據(jù)庫的快速切換解決存儲不可用。
- 通過條帶化進(jìn)行物理隔離防止單存儲故障導(dǎo)致的不可用擴(kuò)散。
- 在系統(tǒng)頂層通過跳單來降低邏輯服務(wù)和存儲不可用帶來的影響。
為了解決系統(tǒng)的容量,主要通過條帶化單元的水平擴(kuò)展來擴(kuò)充整個系統(tǒng)的容量,同時條帶化的結(jié)構(gòu)可以很好的解決數(shù)據(jù)冷熱分離的問題。在系統(tǒng)的垂直方向整個系統(tǒng)主要分為代理層、邏輯服務(wù)層和存儲層;系統(tǒng)在水平方向是由眾多物理隔離的條帶組成的,一個條帶包含了對應(yīng)的邏輯服務(wù)和存儲,同時條帶也是水平擴(kuò)展的基本單位。
本文主要先描述整個系統(tǒng)的整體架構(gòu),接下來會描述傳統(tǒng)架構(gòu)中存在問題并提出對應(yīng)的解決方案,然后會討論整個架構(gòu)對可用性和易擴(kuò)展的實(shí)現(xiàn)細(xì)節(jié),以及探討結(jié)合通用組件來快速開發(fā)整個系統(tǒng)。
2.業(yè)界現(xiàn)狀
交易系統(tǒng)的可用性主要分為無狀態(tài)服務(wù)的可用性和有狀態(tài)存儲的可用性,無狀態(tài)服務(wù)的可用性相比更容易解決,而有狀態(tài)存儲服務(wù)的可用性則成為整個交易系統(tǒng)的核心瓶頸。
為了解決有狀態(tài)存儲服務(wù)的可用性,業(yè)界也研發(fā)了很多的金融級分布式系統(tǒng)存儲方案。例如 Google 的 Bigtable、MegaStore 和 Spanner;Facebook 的 MyRocks;阿里的OceanBase 和 XEngine;騰訊的TDSQL;PingCap 的 TiDB。
這里的存儲主要分為兩個大的方向:基于關(guān)系型數(shù)據(jù)庫構(gòu)造建分布式關(guān)系型存儲系統(tǒng)和基于NoSql 構(gòu)建的分布式存儲系統(tǒng)。分布式關(guān)系型存儲系統(tǒng)如 OceanBase、MyRocks 和TDSQL 等;分布式 NoSql 存儲系統(tǒng)如:Spanner、X-Engine 和 TiDB 等。
近代互聯(lián)網(wǎng)時代,Google 的存儲技術(shù)是整個互 聯(lián)網(wǎng)行業(yè)的技術(shù)標(biāo)桿,其發(fā)表的 GFS、Bigtable 和 Spanner 等一些列技術(shù)成果,奠定了近幾〸年的存儲 發(fā)展方向。其存儲系統(tǒng)也經(jīng)歷 Bigtable、MegaStore 到 Spanner 的演化,并且 Spanner 是第一個把數(shù)據(jù) 分布在全球范圍內(nèi)的系統(tǒng),并且支持外部一致性的 分布式事務(wù)。不管是在存儲的理論研究和技術(shù)實(shí)現(xiàn), Google 都是這個時代的拓荒者。
Facebook 作為一家技術(shù)實(shí)力同樣強(qiáng)勁的互聯(lián)網(wǎng)廠商,MyRocks 是 Facebook 開發(fā)的一款基于 RocksDB 的開源 MySQL 存儲引擎,并且已經(jīng)穩(wěn)定支撐 Facebook 的海量業(yè)務(wù),并作為 Facebook 的 mysql 的主分支。
阿里作為中國電商的代表性公司每天都會面臨海量的交易,雖然海量交易代表業(yè)務(wù)的快速增長,但也會對整個交易系統(tǒng)的可用性、擴(kuò)展性、一致性、性能等提出了更高的要求。在中國移動支付整體快速 增長以及阿里的雙 11 活動的推動下,阿里的交易系統(tǒng)也在一次一次的交易海嘯中快速成長起來。阿里整個集團(tuán)不僅完成了去 IOE,也完成存儲的自研,以及到打磨成為業(yè)界頂尖的互聯(lián)網(wǎng)分布式金融存儲產(chǎn)品。
阿里目前分布式存儲產(chǎn)品有完全自主研發(fā)的金融級分布式關(guān)系數(shù)據(jù)庫 OceanBase 和阿里數(shù)據(jù)庫產(chǎn)品事業(yè)部自研的OLTP 數(shù)據(jù)庫存儲引擎 X-Engine 等。OceanBase 作為完全自主研發(fā)的金融級分布式關(guān)系數(shù)據(jù)庫,支持強(qiáng)一致、高可用、高擴(kuò)展、高性能、高度兼容和低成本等特性。OceanBase 是基于單機(jī)關(guān)系型數(shù)據(jù)庫,根據(jù)數(shù)據(jù)特性分為基線數(shù)據(jù)和更新 數(shù)據(jù)構(gòu)建的一種類 Bigtable 的分布式存儲系統(tǒng);而X-Engine 定位于為阿里云上的公有云客戶提供低成 本高性能的數(shù)據(jù)庫服務(wù)。X-Engine 采用了基于 LSM Tree 的分布式架構(gòu),通過優(yōu)化和借助硬件加速從而提供更低成本下的高性能的讀寫的 OLTP 存儲解決方案。
伴隨著微信支付的快速發(fā)展,以及用戶持續(xù)增長和交易量的增長。騰訊的財付通作為支付底層的服務(wù)提供者有自研的金融級分布式數(shù)據(jù)庫 TDSQL, 不僅支撐微信紅包業(yè)務(wù),也在騰訊云為更多的企業(yè)用戶提供分布式數(shù)據(jù)庫解決方案。
由于歷史原因,微信支付的核心訂單系統(tǒng)沒有將所有的可用性轉(zhuǎn)移到分布式存儲系統(tǒng),而是走出了一條基于單機(jī)關(guān)系型數(shù)據(jù)庫,業(yè)務(wù)和存儲強(qiáng)耦的高可用訂單系統(tǒng)方案。上面業(yè)務(wù)和存儲強(qiáng)耦的訂單存儲方案也正是本文討論的方案,雖然沒有采用一些分布式存儲方案,但它可能更加適合互聯(lián)網(wǎng)的中小型企業(yè)構(gòu)建自主的高可用訂單存儲系統(tǒng)。
除了阿里和騰訊,PingCap 是一家專注開源的新型分布式數(shù)據(jù)庫公司,其研發(fā)的分布式關(guān)系型數(shù)據(jù)庫 TiDB 項目具備分布式強(qiáng)一致性事務(wù)、在線彈性水平擴(kuò)展、故障自恢復(fù)的高可用、跨數(shù)據(jù)中心多活等核心特性,并提供 HTAP 的一站式解決方案。雖 然 TiDB 沒有海量的交易,但作為一家專注存儲自研的公司,代表了中國自研存儲的努力和崛起。
3. 系統(tǒng)架構(gòu)
通過上節(jié)的描述,訂單交易系統(tǒng)的可用性更加聚焦在有狀態(tài)存儲服務(wù)的可用性,一些高可用、強(qiáng)一致的分布式存儲方案可以解決問題。也正如前面提到,微信支付的核心訂單交易系統(tǒng)沒有采用高可用、 強(qiáng)一致分布式存儲系統(tǒng),而是走出了一條基于單機(jī)存儲,存儲和業(yè)務(wù)強(qiáng)耦的一種訂單可用方案。這里的方案也可以給更多中小企業(yè)提供一種自主構(gòu)建可用訂單系統(tǒng)的解決方案。
圖 1: 訂單系統(tǒng)架構(gòu)概覽
如圖 1 所示的整個系統(tǒng)的簡要結(jié)構(gòu),整個系統(tǒng)是由代理層和若干的條帶共同組成的,每個條帶內(nèi)包含無狀態(tài)的邏輯服務(wù)和有狀態(tài)的存儲。整個系統(tǒng)在垂直方向分為三層:代理層、邏輯服務(wù)層和存儲層。
其中,代理層主要功能包含訂單路由和跳單、邏輯服務(wù)層聚合業(yè)務(wù)特性、數(shù)據(jù)的增刪改查和單機(jī)事務(wù)等、 存儲層負(fù)責(zé)數(shù)據(jù)的存儲;在水平方向是由多個可動態(tài)擴(kuò)縮的條帶組成。條帶是系統(tǒng)構(gòu)成的基本單元,可以通過條帶的邏輯聚合實(shí)現(xiàn)讀寫分離、冷熱分離、差異化服務(wù)、和提升版本發(fā)布質(zhì)量等。
整個系統(tǒng)的容量是通過動態(tài)的添加和刪除條帶來達(dá)到容量的動態(tài)擴(kuò)縮容;系統(tǒng)的可用性通過對存儲不可用問題提出針對性的解決 方案和優(yōu)化來提升整個系統(tǒng)的可用性。系統(tǒng)中各條帶是物理隔離的,如果存在條單不可用,在代理層可以通過跳過不可用條帶保證訂單的創(chuàng)建和訂單支付有很高的可用性。條單不可用還是會影響該條帶內(nèi)的訂單查詢和訂單退款,實(shí)際中訂單查詢和訂單退款相比訂單創(chuàng)建和訂單支付可以 更加柔性和更好的容忍度。
通過上面的描述整個系統(tǒng)通過無狀態(tài)的代理層和跳單共同保證系統(tǒng)的創(chuàng)建 訂單和支付訂單有很高的可用性。條帶內(nèi)的無狀態(tài)邏輯服務(wù)采用三機(jī)部署,這樣一個條帶內(nèi)所有邏輯服務(wù)同時不可用的概率將會極低;條帶內(nèi)的存儲也是三機(jī)部署,一主兩備可以保證集群的數(shù)據(jù)的災(zāi)備 和可用性,集群內(nèi)的主備之間采用半同步保證數(shù)據(jù) 的最終一致(可以采用基于 Paxos 改造 binlog 的強(qiáng) 一致數(shù)據(jù)存儲,例如 PhxSql)。
訂單號
基于業(yè)務(wù)和單機(jī)存儲強(qiáng)耦的訂單存儲方案,本質(zhì)是將存儲層的分布式方案上移到業(yè)務(wù)層進(jìn)行實(shí)現(xiàn)。對于通用分布式存儲系統(tǒng)中主鍵的概念,在分布式訂單存儲系統(tǒng)中可以天然的使用訂單號來代替。存 儲的分布式一般采用基于 Range 或者 Hash 的分片 方案,一般先生成好一個全局唯一的主鍵,然后根據(jù)主鍵決定好數(shù)組所在的分片,我們稱之為分片先綁定。
文章中提出的方案是,通過隨機(jī)在所有可用的分片中隨機(jī)選取一個作為當(dāng)前單號所在的分片,然后 將分片的編號記錄在到訂單號中并進(jìn)行訂單的創(chuàng)建, 我們稱這種方案為分片遲綁定。
訂單號 = (版本號,條帶編號,時間,訂單編號)
訂單號主要由版本號、條帶編號、時間信息和訂 單編號組成。其中版本號用于控制訂單號的版本升級;條帶編號存儲了數(shù)據(jù)所在的分片,根據(jù)條帶編號進(jìn)行路由;時間信息用于記錄單號的生成時間,根據(jù)時間和訪問頻率決定數(shù)據(jù)冷、熱和溫的程度;訂單編號用戶保證訂單號在全局的唯一性,根據(jù)我們的條帶方案可以降級到 (條帶編號、時間信息、訂單編 號) 唯一即可,這樣訂單編號只需要在一個條帶內(nèi)唯一即可。
同時會降低對全局唯一序號生成器的依賴,這樣每個條帶都可以使用條帶內(nèi)的序號生成器進(jìn)一步提高整個系統(tǒng)的可用性。
路由信息表
路由信息表維護(hù)了每個條帶的路由信息,每條 路由信息維護(hù)了每個條帶的編號、邏輯服務(wù)的地址和端口、存儲服務(wù)的地址和端口、條帶是否可用、條帶的冷、熱、溫等情況、以及所屬分區(qū)。如表 1 所示,條帶編號是一個增長的 ID,沒新增一個條帶就自增的為條帶分配一個新的 ID;分區(qū)是條帶的邏輯聚合概念,我們可以根據(jù)聚合的分區(qū) 構(gòu)建重點(diǎn)商戶分區(qū)、普通商戶分區(qū)、預(yù)發(fā)布分區(qū)和 冷分區(qū),從而提供差異服務(wù)、冷熱隔離等能力。
每個條帶都有自己的對應(yīng)的邏輯服務(wù)和存儲服務(wù),通過配置的地址我們可以在邏輯上形成邏輯隔離的條帶, 如果機(jī)器也不混合部署和重復(fù)使用,條帶在物理上也是隔離的。
可用狀態(tài)表明當(dāng)前條帶是否可用;冷熱狀態(tài)表明 DB 中數(shù)據(jù)的時間特性,我們粗略分為冷、 熱和溫三類。
代理服務(wù)
代理服務(wù)作為整個訂單系統(tǒng)的入口,需要提供下單、支付、查單和關(guān)單等接口。下單屬于創(chuàng)建訂單,支付和關(guān)單屬于更新訂單,查單屬于查詢訂單。下單的時候,代理服務(wù)需要正確和均勻的選擇條帶, 并在某些條帶不可用的情況下進(jìn)行跳單保證有限跳單次數(shù)內(nèi)可以找到可用的條帶。
對于支付、查單和關(guān)單需要正確解析單號中的條帶信息,進(jìn)行正確的路由。由于代理服務(wù)是無狀態(tài)的邏輯服務(wù),為了提高代理服務(wù)的可用性,通過水平部署多個代理服務(wù)實(shí)例可以解決。假定同一時刻只有有限個代理服務(wù)實(shí)例同時不可用,業(yè)務(wù)方在一次請求中進(jìn)行失敗重試便可將請求路由到其它正常的代理服務(wù),從而保證代理服務(wù)具有較高的可用性。
條帶
傳統(tǒng)的基于 Mysql 的系統(tǒng)架構(gòu)中為了擴(kuò)充系統(tǒng)的容量一般會采用水平的分庫分表策略,通過對主鍵進(jìn)行哈希將數(shù)據(jù)分布在不同的機(jī)器上從而提升系統(tǒng)的容量。例如實(shí)際系統(tǒng)假定有 8 組 DB,可以將主鍵按 8 求余進(jìn)行存儲,但是這樣的方案存在兩個缺點(diǎn):冷熱分離和翻倍擴(kuò)容。
在訂單系統(tǒng)中,訂單記錄在一段時間之后很少會進(jìn)行訂單查詢和訂單退款,所以具有明顯的冷熱特性。為了更好的利用機(jī)器資源,一般會將 x 冷數(shù)據(jù)進(jìn)行分離并存儲到低成本的機(jī)器進(jìn)行存儲和訪問。對于上面的 Sharding 模式,我們需要按天建表進(jìn)行冷數(shù)據(jù)分離。
對于上面的 Sharding 模式,擴(kuò)容的時候會選擇將 DB 的數(shù)量增加到 16 組,需要將擴(kuò)容的數(shù)據(jù)拷貝一份到新的機(jī) 器上,然后根據(jù) 16 進(jìn)行請求重新計算路由,上面的 過程被稱作翻倍擴(kuò)容。上面的翻倍擴(kuò)容對于實(shí)時訂單系統(tǒng)是無法忍受的,我們更希望對系統(tǒng)的容量進(jìn)行線性擴(kuò)縮容,同時不需要影響已經(jīng)生成的訂單。為了更好的支持冷熱數(shù)據(jù)分離和線性擴(kuò)容,我們提出基于條帶的動態(tài)擴(kuò)容架構(gòu)。一個條帶作為存儲的基本單元,其中包含了無狀態(tài)的邏輯服務(wù)和有狀態(tài)的存儲,通過增加和減少條帶的數(shù)量進(jìn)行線性的擴(kuò)縮容。
事務(wù)
對于交易系統(tǒng)很多場景下會面臨需要操作多個資源同時成功或者失敗,如轉(zhuǎn)賬、多個單據(jù)狀態(tài)的同時扭轉(zhuǎn)等。在單機(jī)關(guān)系型數(shù)據(jù)中我們會使用單機(jī)事務(wù)來進(jìn)行解決,同樣對于分布式系統(tǒng)需要系統(tǒng)具 備分布式事務(wù)的能力。
由于分布式事務(wù)的實(shí)現(xiàn)復(fù)雜、性能低下等特點(diǎn),在業(yè)務(wù)系統(tǒng)中往往會將分布式事務(wù)轉(zhuǎn)化為單機(jī)事務(wù)進(jìn)行解決,或者將分布式事務(wù)根據(jù)核心程度劃分為主事務(wù)和次事務(wù),通過將次事務(wù)通過異步組件進(jìn)行異步補(bǔ)償完成整個事務(wù)。
另外,由于交易系統(tǒng)一筆交易往往會操作多個相關(guān)的交易單據(jù),我們可以將相關(guān)的多個單據(jù)部署在同一個分片, 這樣就可以轉(zhuǎn)化為單機(jī)事務(wù)進(jìn)行解決。通過上面的分析,我們將系統(tǒng)的事務(wù)轉(zhuǎn)為條帶內(nèi)的單機(jī)事務(wù)和跨條帶的異常補(bǔ)償事務(wù),這樣各個條帶就可以充分解耦做到物理和邏輯的隔離。
跳單
在進(jìn)行下單前,系統(tǒng)中存在一個條帶健康度的檢查服務(wù),它會實(shí)時模式真實(shí)訂單探測和收集條帶的健康度、耗時等情況。
另外,在某些情況下需要手動屏蔽不可用或者可用的條帶 (如增加或減少跳單, 冷熱分離等場景)。在下單的時候,代理服務(wù)結(jié)合條帶健康度、黑名單等信息,并在可用的條帶內(nèi)根據(jù)短期內(nèi)每個條帶的請求量選擇一個可用的條帶,然后根據(jù)訂單號到對應(yīng)的條帶生成訂單。
如果第一次成功,則直接返回訂單號;如果沒有成功,此時可以屏蔽掉當(dāng)前的條帶,進(jìn)一步在剩余的可用條帶內(nèi)選擇一個可用的條帶,直到重試到達(dá)上限。我們稱上面不斷重試尋找可用條帶的過程為跳單,跳單主要是通過有限次重試跳過不可用條帶而保證下單操作的高可用。
健康度檢查服務(wù)
條帶健康度檢查服務(wù)是所有條帶的觀察者,它通過周期性模擬真實(shí)的交易探測每個條帶的可用性和耗時等情況。
根據(jù)健康度檢查服務(wù)提供的條帶可用和耗時信息可以在下單的時候以更高的概率選到可用的條帶而有效的屏蔽掉不可用的條帶。條帶的是否可用也需要提供好的評價策略和兜底方案,防止網(wǎng)絡(luò)持續(xù)抖動時造成過探測導(dǎo)致所有條帶的不可 用。
4.訂單流程
對于訂單系統(tǒng),作為支付系統(tǒng)的核心流程,往往需要提供創(chuàng)建訂單、更新訂單和查詢訂單的能力。對于訂單的復(fù)雜查詢,為了不影響實(shí)時交易鏈路的可用性,會采用將備機(jī)的數(shù)據(jù)通過可靠的異步組件同步到非實(shí)時的數(shù)據(jù)庫進(jìn)行復(fù)雜查詢或者統(tǒng)計等操作。
下面會介紹基于上面的條帶化架構(gòu)的創(chuàng)建訂單、 修改訂單和查詢訂單的流程:
創(chuàng)建訂單
如表 2 所示的流程,主要由入口的路由服務(wù)完成訂單號的生成以及條帶不可用時的跳單操作。
這樣可以保證創(chuàng)建訂單的一個高可用,即使存在若干不可用的條帶整個系統(tǒng)還是可以進(jìn)行下單操作。
更新訂單
如表 3 所示的流程,當(dāng)業(yè)務(wù)在下單流程獲取訂單號之后,業(yè)務(wù)方攜帶單號,代理服務(wù)解析單號中的條帶編號,就可以保證請求在對應(yīng)的條帶內(nèi)進(jìn)行請求, 并正確找到對應(yīng) DB 的信息。
查詢訂單
對于訂單查詢,我們可以將查詢分為實(shí)時的讀請求和非實(shí)時的讀請求。實(shí)時的讀請求讀取主庫的數(shù)據(jù),主要為核心鏈路提供準(zhǔn)確的數(shù)據(jù)查詢;非實(shí)時的讀請求讀取備庫的數(shù)據(jù),主要為核心鏈路提供降級的備機(jī)讀取以及非實(shí)時鏈路的讀取。
如表 4 所示 的流程,當(dāng)業(yè)務(wù)在下單流程獲取訂單號之后,業(yè)務(wù)方攜帶單號,代理服務(wù)解析單號中的條帶編號,就可以保證請求在對應(yīng)的條帶內(nèi)進(jìn)行請求,并正確找到對應(yīng) DB 的信息。
5. 架構(gòu)特性
線性擴(kuò)容
對于海量交易的系統(tǒng),線性擴(kuò)容成為一個重要的特性。線性擴(kuò)容給整個系統(tǒng)提供了更多的靈活性以應(yīng)對特定時期的交易洪峰,并且能通過簡單的擴(kuò)縮容取得交易處理能力和成本的平衡。
對于業(yè)務(wù)可能快速持續(xù)增長的系統(tǒng),線性擴(kuò)容能力可以應(yīng)對不必要的系統(tǒng)重新設(shè)計和重構(gòu)。
故障壓縮
由于各條帶是邏輯和物理隔離的,不管是由于條帶內(nèi) DB 導(dǎo)致的故障或者灰度發(fā)布導(dǎo)致的故障, 相應(yīng)的故障只會壓縮在該條帶內(nèi),不會擴(kuò)散導(dǎo)致整個系統(tǒng)的雪崩。
通過統(tǒng)計我們可以簡單估算每個條單不可用的概率,然后估算整個系統(tǒng)不可用的概率。
差異服務(wù)
根據(jù)我們抽象的條帶概念,我們可以再聚合某些條帶為一個分區(qū),某些商戶的請求只可以落在某些分區(qū)的條帶內(nèi)。這樣不同的分區(qū)提供不同的機(jī)器、帶寬等,可以實(shí)現(xiàn)對重點(diǎn)商戶和非重點(diǎn)商戶的差異化服務(wù)。
冷熱分離
當(dāng)系統(tǒng)某些條帶的容量到達(dá)預(yù)警值,或者其中的數(shù)據(jù)已經(jīng)超過某個冷卻閾值。我們可以將條帶變?yōu)橹蛔x和可更新,但不能再進(jìn)行數(shù)據(jù)的寫入。
等到數(shù)據(jù)的訪問量下降到某個閾值后,可以將條帶內(nèi)的全量數(shù)據(jù)停寫后拷貝到冷庫,然后修改條帶路由信息中的存儲服務(wù)地址為冷數(shù)據(jù)所在的新機(jī)器的地址。
然后刪除舊機(jī)器上的數(shù)據(jù)并新增一個空的條帶,這樣就可以簡單的完成冷熱數(shù)據(jù)分離,同時上面的過程可以實(shí)現(xiàn)完全自動化。
灰度控制
在互聯(lián)網(wǎng)系統(tǒng)的可用性問題中,統(tǒng)計發(fā)現(xiàn)很多版本的問題可以通過合理的灰度提早發(fā)現(xiàn)和解決?;跅l帶的架構(gòu)可以輕松的構(gòu)建預(yù)發(fā)布環(huán)境,預(yù)發(fā)布環(huán)境通過后可以控制新版本先對某些生產(chǎn)條帶進(jìn)行灰度發(fā)布,然后逐步灰度到所有的條帶。
同時還可以通過控制某些條帶的請求量從而可以做到更細(xì)粒度的灰度。
熱點(diǎn)均衡
在選擇分區(qū)的時候,可以統(tǒng)計近期每個條帶創(chuàng)建的訂單數(shù)作出一個合理的條帶選擇,從而達(dá)到最大程度的數(shù)據(jù)均衡,避免傳統(tǒng)分片模式下數(shù)據(jù)傾斜的問題。
6. 備份、容災(zāi)和恢復(fù)
備份
為了應(yīng)對機(jī)架級不可用、機(jī)房級不可用和城市級不可用,需要通過數(shù)據(jù)備份進(jìn)行容災(zāi)??梢愿鶕?jù)業(yè)務(wù)的容災(zāi)選擇合理的容災(zāi)級別,通常業(yè)務(wù)會選擇一主兩備的三機(jī)備份策略。
數(shù)據(jù)一致性
如果采用 Mysql 作為條帶內(nèi)的存儲引擎,Mysql 支持同步復(fù)制、異步復(fù)制、半同步復(fù)制、增強(qiáng)半同步復(fù)制和 MGR(MySQL Group Replication)。通常我們很少采用同步和異步復(fù)制,在 Mysql5.7 增強(qiáng)半同步之前 DBA 多會采用半同步復(fù)制,但如果主機(jī)宕機(jī) 切換到備機(jī)會出現(xiàn)一定的數(shù)據(jù)不一致。
為了解決半同步帶來的問題,Mysql5.7 之后推出了增強(qiáng)半同步。但是 MGR 是基于 Paxos 的強(qiáng)一致復(fù)制方案,但是 MGR 業(yè)界的互聯(lián)網(wǎng)公司卻很少有公司采用。
容災(zāi)
我們假定所有的機(jī)房都在一個城市內(nèi)的不同機(jī)房,為了應(yīng)對城市內(nèi)的機(jī)房級不可用,我們需要將三份數(shù)據(jù)分布在同城的三個不同機(jī)房內(nèi),同時保證每個機(jī)房內(nèi)有相同的主機(jī)和備機(jī)的數(shù)量,對機(jī)房級進(jìn)行負(fù)載均衡。
當(dāng)出現(xiàn)機(jī)房級以及機(jī)房級以下的不可用,可以快速的進(jìn)行主機(jī)切換保證業(yè)務(wù)的可用性, 如果出現(xiàn)整個機(jī)房的不可用最多會損失 1/3 的交易量。但是對于條帶化的架構(gòu),我們可以快速調(diào)整條帶路由信息表將不可用的條帶進(jìn)行屏蔽,這樣只會有一個短暫的不可用。
7. 架構(gòu)缺點(diǎn)及改進(jìn)
對于分布式事務(wù)不太友好。
其實(shí)可以將更多的能力下降到存儲進(jìn)行解決, 這樣對業(yè)務(wù)人員的架構(gòu)能力提出較高的要求。
如果現(xiàn)行系統(tǒng)進(jìn)行改造的成本過高。
8. 總結(jié)
上文首先描述了基于單機(jī) Mysql 構(gòu)建的業(yè)務(wù)和存儲強(qiáng)耦合的高可用海量分布式訂單系統(tǒng),基于抽象的條帶概念使得整個系統(tǒng)架構(gòu)天然具備了一些線性擴(kuò)容、故障壓縮、冷熱分離、灰度控制、差異服務(wù)和熱點(diǎn)均衡等能力。雖然不同于支付寶通過強(qiáng)一致分布式存儲系統(tǒng)來保證分布式存儲服務(wù)的高可用, 但這種構(gòu)建于單機(jī) Mysql 的架構(gòu)更加適合沒有獨(dú)立研發(fā)分布式存儲的中小企業(yè)。從目前業(yè)界存儲演進(jìn)的方向來看,強(qiáng)一致的分布式關(guān)系型數(shù)據(jù)存儲系統(tǒng)還是業(yè)界努力的方向。