隨着雙11進入千億時代,電商平臺正在向「全球化,娛樂互動化,無線化,全渠道」發展。算法
爲實現全民互動,電商平臺會進行低價預售,狂歡紅包,購物券,紅包雨,商品半價,滿n減1等多種促銷方式。sql
每筆剁手操做都會經歷一系列核心系統處理,如圖:數據庫
如此眼花繚亂的玩法,底層是多個核心繫統的支撐,整個系統要保證在交易高峯下的海量訂單有序,準確,順滑。緩存
紅包發放要保證精確預算控制,預算髮放的紅包總金額不能超過預算的金額。服務器
每條預算在數據庫中是一條記錄,在高併發場景下,可能會成爲單熱點瓶頸,維護過多的記錄表,可能形成數據傾斜。網絡
預算控制和用戶無關,無需實現單元化。用戶的紅包信息則須要實現單元化,發放流程涉及到預算扣減,扣減操做後,用戶須要儘快收到紅包。數據結構
因單元化和非單元化的數據處於不一樣數據中心,可能形成跨機房調用,也就引入了不肯定性。架構
因此紅包系統和預算系統須要解決高併發場景下的預算扣減和用戶收取紅包的一致性。併發
分桶方案框架
經過分析歷史數據,咱們將預算拆分爲多個子預算,瓶頸分配到多個數據庫中,根據紅包發放請求的userId進行路由。在子預算餘額不足時,路由到主預算中。 每一個子預算的扣減並不相等,確定有一部分子預算會出現餘額不足的狀況,因此主預算要比子預算多分配一些金額。當多個子預算餘額很是少時,能夠對子預算進行回收,避免預算分片的碎片化。
數據庫優化
爲提高記錄表性能,須要對數據庫操做進行梳理及優化。設想這個場景主要有3條sql:
更新語句是形成熱點的瓶頸,爲減小更新致使的獨佔鎖,能夠將3條sql合在一塊兒,經過一次網絡傳輸到達數據庫服務器,同時在更新語句中設置餘額大於等於0的條件,這樣能夠避免在扣減以前再查詢一次餘額,而僅僅經過判斷sql錯誤碼就能識別餘額是否足,減小了對數據庫的壓力。
更新語句添加commit_on_success標籤,保證事務成功後當即提交事務,不用等到客戶端獲取更新結果再發起commit,減小了一次網絡交互,同時記錄的獨佔鎖能夠當即釋放。
更新語句添加target_affect_row 1 標籤,保證若是知足條件的記錄不存在,事務應該失敗,而不是返回影響行數爲0。
能夠將多個事務封裝成一個數據庫的寫入單位。總體優化後系統qps能夠摸高到30w。
用戶領取紅包後須要在多個系統終端中進行紅包展現,好比領了多少紅包,金額是多少等。 統計這些會比較消耗數據庫性能,同時展現紅包也是比較高頻的需求。採用緩存能夠解決這個問題,可是隨之而來的問題是緩存的失效處理。紅包自己涉及多個生命週期,到底在哪一個緩解設置緩存失效是合理的呢?
在用戶的紅包每次進行狀態變動時都會更新modify_time,因此採用讀時更新緩存:
在業務規則角度進行了紅包使用控制,每次只能使用10個紅包,紅包使用場景qps也很高放大到紅包系統qps是10倍。每次紅包使用須要更新10個紅包狀態,產生10條紅包使用的流水,還須要產生至多10條紅包相關的業務單據。
一次紅包使用場景涉及到大量cpu資源進行sql解析,一次下單涉及到多個sql,對網絡消耗較大。咱們採用batch insert語法優化插入性能,更新語句採用多條方式提高更新性能。在業務系統中生成一個大sql發送給數據庫服務器,減小網絡交互。
好比此次下單操做涉及到5個紅包,能夠經過一個sql將5個紅包餘額更新爲0,同時加入金額鎖保證紅包的併發更新。設置語句的target_affect_row 5標籤,若是某個紅包已經被其餘訂單併發下單使用,事務會提交失敗,能夠經過數據庫返回的錯誤碼識別出這一狀況。
上面的狀況只是處理非單元化場景預算,系統須要在預算扣減以後寫入單元化的用戶數據中。兩種數據處於不一樣數據庫,須要保證操做的一致性。同時在紅包領取後,在1s內展現用戶紅包,這種狀況通常採用跨庫事務框架來解決。 但跨庫事務不能作到嚴格的事務一致性,嚴格的事務一致會形成性能的極大降低,因而採用內部的一致性消息jbus實現。
jbus
jbus思想是業務在事務中插入一條消息記錄,創建一套消息訂閱和分發系統對消息進行處理。消息的記錄和業務記錄在一個數據庫中,能夠作到事務一致性。 多個消息訂閱者能夠共享一條消息記錄,所以不會增長過多的數據庫性能損耗。作到1s內消息消費,則能夠保證用戶看到本身領取的紅包。
同時創建監控系統對消息擠壓進行監控,能夠及時發現消息的積壓問題,同時在消費出現問題時進行流程完整性的保障。
下單系統涉及到訪問物流系統獲取運費模版,計算運費價格,以前的架構會調用遠程服務,獲取計算結果,這種方式會將下單峯值帶到下游依賴的系統中,須要下游系統具有一樣的峯值承載能力,提升了整個核心鏈路的成本,同時穩定性也帶來了複雜和挑戰。
流程前置處理後,下單系統再也不須要請求物流系統,而是直接訪問運費模板緩存服務器,經過前置下單運費計算模塊在本地計算出運費,減小了對於遠程服務的調用和依賴,提高了系統性能,加強了系統穩定性。
隨着業務玩法的愈來愈豐富,參與的團隊愈來愈多,多個團隊在一套平臺開發形成的效率浪費愈來愈多。
爲提高開發效率架構進行了升級,業務級代碼和平臺級代碼分離,平臺級代碼對交易相關能力進行分類抽取,抽象提取對外提供支撐服務,業務方根據團隊能力自助式定製邏輯開發,無需平臺團隊介入,大幅提升開發效率。
爲達到業務和平臺分離的架構目的,主要經過能力模型,配置模型,所生成對配置數據貫穿業務配置主線和業務運行主線來實現。
經過對交易建模,抽象,收斂,造成了交易基礎能力層,採用功能域->能力->擴展點方式進行表達。
在下單環節中概括十幾個功能域,優惠,支付,交付,價格,訂單,結算,稅費等,針對這些域進行能力擴展,同時開放給業務方進行定製,適應不一樣業務場景需求。
同時引入產品概念,將多個域能力進行整合,對業務方提供知足業務功能的能力包,進一步提升業務研發效率。
整個架構中,業務能力,產品,場景屬於平臺能力,業務方定製功能都在業務包中,這樣能夠作到業務和平臺分離,業務之間隔離,使得平臺開發人員和業務開發人員之間互不干擾,提高總體協做和交付效率。
營銷平臺核心系統:
優惠計算系統能力:
交易系統和金錢打交道,稍有不慎會帶來資損,因此數據一致性和業務正確性是平臺最大的挑戰。
挑戰:
目標:
實時對帳: 底層基於storm流式計算框架,上層增長調度任務管理,數據源,對帳腳本管理,監控報警管理等模塊。用戶能夠經過實現簡單對帳腳本,完成數據對帳工做。實時對帳經過db的drc消息觸發。
離線對帳: 經過定時任務,掃碼db或定時拉取表數據,將須要對帳內容組成元數據消息,datacheck根據消息內容執行對應數據腳本對帳,獲得最終結果。
交易相關核心鏈路每到大促時節,數據熱點都會變成最須要解決的問題。同時對於數據一致性有必定的要求,因而好的緩存系統,作好防止熱點數據擊穿,提高熱點數據訪問效率就顯得尤其重要。
三級緩存結構
特色:
如圖:
熱點數據緩存與驅除
兩個小時內數據有效,在週期內針對數據訪問qps和最近一次時間點進行排序,最後的驅除。 hotsensor針對週期內單位時間作滑動窗口,窗口長度採樣採用1.5s或2h,採樣窗口劃分爲20個格子,經過必定算法統計20個格子平均滑動窗口累計平均值。
hotsensor計算方式:
多級緩存場景中,某個key到下一級緩存查詢,多key時須要組裝每次查詢結果,能夠進行封裝,統一代碼風格。
利用平臺提供模塊化,可視化配置的技術組件,開放服務和元數據來快速定製獨有商業形態,多個渠道數據進行沉澱,實現了「大中臺,小前臺」的業務劃分,支撐了業務的快速發展和低成本創新的目標。