接着上篇繼續講,接下來主要介紹交易整體設計的技術要點設計,對於電商中臺來講,交易系統是核心中的核心,一開始就須要圍繞高性能,高可用,和高擴展三個方面來重點設計。本篇主要介紹高性能設計。數據庫
對於高性能的定義,一般能夠理解爲系統/服務接口響應時間低(rt)且併發量(qps,tps)高. 提升性能的主要策略有:選擇合理的分佈式事務處理機制,數據庫的分庫分表,讀寫分離,異步化,緩存,複雜查詢走搜索。api
交易業務要求訂單,庫存,優惠券,紅包,支付等數據要強一致,如何保證這些數據之間的一致性是必需要解決的問題,也就是分佈式事務的場景。緩存
業界分佈式事務的選擇方案很是多,每種方案之間的差別性很是大。讓咱們大概看一下幾種常見的方案和其特色:微信
2PC: 二階段提交協議,最大幾個問題是事務管理器(協調者)和資源管理器(參與者)之間的調用是同步阻塞的,若是在一次事務中只有部分資源管理器進行了commit操做,其餘超時或者沒有成功,會致使數據的不一致性。網絡
3PC: 三階段提交協議,是對2PC的改進版本,引入了超時機制,極大的下降了同步阻塞,preCommit 階段協調者和參與者出現通訊問題後,仍然會出現數據不一致性的問題。架構
TCC: 其實也是2PC的改進版本,TCC將事務參與者從數據庫自己提高到了業務服務粒度,讓每一個業務單元實現try,confirm,cancel三個接口,協調者在調用完try接口會,根據返回接口調用confirm仍是cancel,其最大問題是業務侵入性很是強,2PC的單點問題,超時問題也都存在,而且須要業務單元考慮各類異常狀況,無法利用數據庫的事務機制。併發
阿里GTS: GTS經過將事務協調器集羣化的方式解決了單點問題,但這也帶來了另一個問題,原來本地化的協調者變成了要網絡通訊的雲協調者,若是不是在同一個數據中心,要跨越公網或者專有網絡,性能損耗比較大,此外GTS支持的服務框架也是有限的,若是不支持也須要實現相似於TCC的業務接口。框架
SAGA: 在微服務架構下,關注的人愈來愈多了,但saga早在1987年就提出來了,基本核心思想Saga是一系列本地交易,每筆事務都會更新單個服務中的數據。第一個事務由系統外部請求啓動,而後每一個後續步驟由前一個事件完成而觸發。其最多見的兩種實現方式以下:異步
1.事件/編排:沒有中央協調器,每一個服務產生並聆聽其餘服務的事件,而後採起對應的處理動做。一般會使用消息中間件來實現。elasticsearch
2. 命令/協調:中央協調器負責集中處理事件的決策和業務邏輯排序。因引入協調器模式比較重,目前沒有好的框架。
對saga要詳細理解能夠自行google,baidu.
事務消息最終一致性方案:利用消息中間件的事務性消息/兩階段消息來實現,流程以下:
這種模式對業務的侵入性比較比較低,利用消息中間件,性能上有很是好的保障,此外即便趕上網絡超時等問題,經過消息中間件的超時回調功能最終都能保證數據的最終一致性。所以咱們也選擇了這種方案做爲咱們的實現。以簡化的確認下單時序來講明這個場景:
經過時序圖能夠看出,經過事務消息的2階段提交和消息的超時回調極大的提高了各個業務數據的一致性,已是很是不錯的方案了,但仔細分析這個圖,你仍是能發如今極端場景仍是有缺點,看個明顯的問題:
庫存回滾失敗:在本地事務回滾的狀況下,調用庫存系統回滾庫存超時或者發生異常,庫存數據將會出現不一致狀況。對於這種狀況須要經過離線或者實時的庫存對帳系統專門來解決。針對這個問題咱們後面能夠寫一篇文章單獨討論了。
對交易來講,數據量最大的是交易主表和子表,這兩個表的數據也是隨着業務量增加最快的,須要在一開始,就要考慮分庫分表策略,否則等到業務發展到必定量再來調整,會很是痛苦,你會從前到後修改一邊,還要遷移數據。對於這塊咱們總結了一些比較實用的策略,以下:
用商家id取模做爲分庫分表的字段:這種策略比較適合平臺性的公司,若是淘寶,天貓和拼多多。 但對於一些很是大的商家來講,仍是會發生數據傾斜的狀況。
用買家id取模做爲分庫分表的字段:這種策略比較試用於自營性的平臺,像京東這樣的。
自定義分庫分表的規則: 大部分的狀況,經過上面兩種策略就能知足,若是你的業務很是特殊,好比要按照年月日之類的分,那就須要本身寫分庫分表規則函數來作了。
分庫分表的總原則是:利用交易經常使用的字段做爲分庫分表的字段,能夠聯合使用,庫和表的數量支持後期修改,對應用代碼透明,後期數據庫擴容,上層應用無感知,至多調整一下分庫分表規則。目前咱們利用的是開源mycat來作這塊,這塊好用的還真很少,不少須要本身作額外工做。
讀寫分離不太適用交易的場景,特別是在併發量很是高的時候,數據庫的主備之間一般存在幾ms的延遲,搞很差會形成很大的故障。可是爲了節省成本,把備庫的資源利用起來,對於一些規則肯定不會形成問題的查詢能夠走備庫,如:對交易完成數據的查詢,對實時性要求不是很是高的運營管理系統和客服系統的查詢,均可以切到備庫查詢。 讀寫分離也是須要提早考慮,在一開始就須要制定出規範,明確使用不當的後果。如今不少分庫分表的框架均可以作到對應用透明的主備讀寫比例的調整,但業務代碼必需要評估哪些場景是不能走備庫讀的。
對於核心系統異步化的重要性和帶來的好處不用多說,但什麼樣的場景須要異步化了,就交易來講,像扣減庫存,優惠券使用,支付這些核心鏈路是不能異步化處理,能異步化處理的是在交易時刻就不須要馬上肯定的場景。如建立物流訂單,佣金計算等。異步化的整體概覽圖以下:
整體原則就是將不在交易核心鏈路的部分,儘可能異步化去處理。
異步化經常使用的手段就是消息機制和分佈式定時任務。
消息機制:首先須要標準化交易事件消息,如交易建立,確認,支付完成等。來看一個樣例代碼片斷:
不要每一個交易事件,都單獨搞個事件對象。發消息到消息中間件時,每一個event爲一個messageType,同一個topic,爲了下游系統只訂閱本身感興趣的少部分數據,能夠利用消息中間件的tags之類的機制進行訂閱消息過濾。
分佈式定時任務:支付超時關閉交易,失敗重試,異常交易掃描這些場景適應定時任務,延遲在分鐘級別,這塊選用開源界比較優秀的框架就能夠了,沒有必要本身搞。
異步化帶來的好處主要是:
將交易系統和非核心繫統解耦,從而確保交易的穩定性和響應時間。
幫下游系統削峯,不少下游系統的容量是很是小的,在大促這樣的高峯期間,是沒有足夠的資源跟上交易的處理速度的,消息中間件集羣,會起到很是好的緩衝削峯做用,下游系統按照本身的速度消費就能夠了,若是下游消費太慢會出現消息堆積,但消息集羣自己就是耐堆積的。
緩存適用於讀多寫少的場景,但交易是以寫爲主的場景。因此交易數據自己是沒有緩存需求的,但經過前面的核心鏈路分析能夠看出,像交易依賴的商品,優惠,用戶這些信息若是直接走DB, 會很是慢,而這些數據是讀多寫少,是很是適合使用緩存,提升性能的。交易團隊須要經過依賴調用關係分析,推進依賴的上下游系統的技術團隊,使用緩存技術,作性能提高和可靠性保障。經常使用的緩存策略有前置緩存和後置緩存。
前置緩存:
優勢:即便業務系統掛了,也沒有啥影響,
缺點:後期升級比較麻煩,必須通知依賴client的應用都強制升級。
後者緩存:
優缺點正好和前置緩存相反。
在實際使用中,若是爲了保障很是高的可用性,能夠二者結合使用,經過動態配置開關作切換,在client層的代碼作一下路由切換處理。
🏙成熟的電商系統,都有本身單獨統一的搜索平臺,選擇什麼樣的索引構建方式,徹底取決於業務上要多實時的查到最新的數據,目前主流的搜索框架,支持dump DB 和 api 直接推送兩種模式。在咱們本身的實踐中,認爲交易數據的實時性很是高,須要在1秒以內完成數據索引的構建。
在接受交易事情消息上能夠利用批量投遞的策略,提高處理能力,。
這塊須要特別注意的是消息集羣到交易索引的構建系統消息在處理上會出現亂序的問題,必需要經過業務字段作前後次序處理,忽略過時的數據,通常都用業務發生時間bizTime.
在推送索引這塊能夠利用聚合緩存策略, 減小推送索引的頻率,不少搜索框架都對每次推送數據的大小,每秒的推送次數都有限制,須要利用聚合緩存策略來適應選擇的搜索框架,總的來講就是不能推的太快,也不來太慢,還要保證全部的索引構建完成在業務容許的範圍(1s)以內。
搜索框架的選型很是多:開源的有ElasticSearch,lucene,nutch,solr,solandra. 商業產品的每一個雲平臺都有搜索產品提供,默認推薦 elasticsearch, 若是對搜索結果準確性和智能化程度比較高,使用商業化雲產品。
此次就先寫這麼多,後面接着講高可用和高擴展的技術要點設計。
對這塊有興趣的歡迎交流技術方案和產品玩法。
更多文章歡迎訪問 http://www.apexyun.com/
聯繫郵箱:public@space-explore.com,微信:yinhexi-one
(未經贊成,請勿轉載)