近一年多沒在博客園寫東西了,從換公司後就一直努力學習公司的框架和業務。而今接手一個電商數據統計項目,在博客園搜索統計項目解決方案卻一無所獲,最終自己設計並在開發的過程中持續更新,希望可以和大家一起交流。
需求
項目組的電商系統運行了3年多,每天下單量在2w單左右。
1.要求從商戶,客戶,商品的角度統計每天,每月,任意天數查詢的需求。
2.並對部分敏感數據做實時查詢,例如下單數,下單金額之類的指標。
3.對客戶,商品交易額交易量指標做top並支持導出。
4.按地域統計各個交易指標並做top。
5.不能在原有的系統上做集成,防止影響主業務。
設計思路
服務器採用windows2012 IIS7.5 .netfromwork4.0 數據庫是部分sqlserver和部分mysql 基於目前系統的狀況和需求,決定採用觸發式預統計方式來完成部分重要功能。
何爲觸發式? 目前多個系統之間通信有消息中間件來處理業務。例如 下單,下單時創建訂單後就直接往消息系統中註冊一條創建訂單任務,任務系統會分發給對應執行者去執行下單相關的後續任務。
根據消息系統的特性,在不摻和主系統的情況下利用下單,支付,等業務觸發,完成數據的收集,處理,這就是觸發式。
非實時部分
關於預統計呢,其實只要是統計,都繞不過這個方法。數據少的時候我們統計一般採用全表查詢,count,groupby等形式來得出結果。但大多數情況下,會重複獲取大量數據,每次都統計一遍,不但耗時,而且在數據庫性能,數據傳輸,超時等問題上都是不能容忍的。
因此我們會總結,將可以增量統計的部分採取一點一滴的疊加,每天統計增量數據,將合理的數據結構存儲起來(半成品),下次統計或者查詢的時候直接查半成品,不僅數據量少,而且不用遍歷原來的表。特別是電商系統,每天增量數據大,多會採用分庫分表的方式來提高數據庫性能和訪問速度,但是卻給統計造成了困擾。
實時部分
對於部分實時性要求高的指標,就需要我們達到流式計算的要求了。一樣採用觸發式的任務,在任務中維護一個全局的內存變量,不同商家也可以區分開,另外由於數據實時性和內存大小考慮,需要一個定時推送redis,一個定時定量去移除存儲到數據庫。
關於定時定量,是指內存中累積到一定個數比如客戶交易商品累計到100或者離上次存儲已經過去1分鐘,這個時候就會觸發存儲規則。推送也一樣,說是實時,但是不可能有變化就推送到redis,那這樣用redis就沒有意義。按我的想法是每個有交易的商家每分鐘推一次,下單任務觸發後根據上次推送時間來決定,如果沒有交易當然就不推送。
庫表設計
統計項目的庫表我採用的是查從庫,從庫擁有和主庫一樣的表結構,並且只讀不寫。在分表原則上 將表設計爲待統計表,預統計表,按月統計表 按月存儲表 並根據數據量分表,讓每個表中預期數據不超過1千萬,我將部分數據量大的表分爲128張,少量的分爲16張
極限情況下可以分庫,來提升連接數。
流程設計
在提升系統性能和響應速度方面,會採用長緩存+短緩存的方式。例如 不變通用的數據採用長緩存(2-24小時),實時要求敏感數據(1-5分鐘)
對於部分慢的地方還可以採用首頁緩存,默認參數緩存等方式來提高頁面打開速度。
消息系統架構
觸發式統計是建立在消息中間件的基礎之上的,因此將它的架構和設計思路貼出來,供大家參考和借鑑。消息系統的存在主要有幾點好處,1.解耦系統之間的依賴 2.異步執行耗時任務 3.具有可靠的日誌和重試機制 4.可分佈式部署橫向擴展
統計任務中心
觸發式統計的核心有兩個,一是消息系統 二是統計任務中心。它的職責主要是收集交易數據,管理預統計結果並推送(redis和數據庫)。已下列支付爲例,它在全局中單例,並負責收集數據,管理(統計,存儲,推送)
總結
這一次,我將統計項目的大體結構和設計思路分享了出來,目前項目還未正式開始 ,後期可能會做調整,改掉不合理的設計。我打算將統計項目作爲一個系列,在實現的途中分享,也希望有人能獲益,有人能給予指點。