建造適於業務分析的日誌數據系統

轉自 [韓大 公衆號內容](http://mp.weixin.qq.com/s?__biz=MzA5ODExMTkwMA==&mid=402256133&idx=1&sn=04985b865ef8b40a06ab275791e886b8&scene=4#wechat_redirect),

現在“大數據”非常的火。我們看到有各種相關的技術文章和軟件推出,但是,當我們面對真正日常的業務時,卻往往覺得無法利用上“大數據”。初步想來,好像原因有兩個:第一個原因是,我們的數據往往看起來不夠“大”,導致我們似乎分析不出什麼來。第二個原因是,大數據往往其作用在於“預測”,比如給用戶推薦商品,就是通過預測用戶的消費傾向;給用戶推送廣告,局勢通過預測用戶的瀏覽習慣。然而很多時候我們要的並不是預測,而是弄明白用戶本身的情況。
對於業務中產生的數據,一般我們期望有幾種用途:一是通過統計,用來做成分析報告,幫助人去思考解決業務問題;二是對一些篩選和統計後的數據,針對其變動進行自動監測,及時發現突發狀況和問題;三是使用某些統計模型或者推算方法,去對一些情況進行預測。這三種數據的利用方法,可以說是層層遞進的。我們現在最流行的“大數據”,是最頂級的需求,然而,我們實際的工作中,往往連最初級的數據系統都還未建立起來。所幸的是,現在“大數據”體系的實現手段,基本都已經開源化,我們完全可以利用這些知識和概念,去先構造我們最基礎的數據系統,滿足最基本的分析需求。
這裏寫圖片描述
那麼,我們就應該來看看,流行的數據系統的結構,以及其概念。這些基礎設施一旦建立好了,就能成爲一個具備日後擴展更多數據需求的基礎。爲了更好的理解這些概念,我們可以對比着來看。

首先說說最傳統的數據系統的構成——數據庫統計系統。這種做法,其實是很自然而原始的,就是把需要統計的日誌信息,以數據庫記錄的形式,一條一條的存放在數據表中,在需要看統計結果的時候,就編寫SQL去運算出結果來。但是這種做法有幾個明顯的缺點,第一是數據庫裏面會有大量的日誌數據,很容易就突破存儲的上限;第二是我們一般沒有去預測SQL的內容,導致存放日誌的表一般沒有精心的去建立索引,這導致了統計查詢運行往往會很慢;第三個問題是最致命的,就是由於對於統計需求沒有規劃,隨着數據統計需求的增加,數據表結構會不斷變得更加複雜,最後沒有人能搞明白具體每個字段的含義,導致了無法編寫正確的SQL。由於以上的缺點,人們開始反思這種做法,並且開始更仔細的對待數據統計需求。

這裏寫圖片描述
這樣,就誕生了第二種數據系統:日誌與報表分離的數據系統。爲了解決日誌數據量大的問題,人們不再把原始日誌插入數據表,而是以文件形式存放。爲了解決統計速度緩慢的問題,人們會預先根據統計的需求,設定一些需要索引的日誌字段,然後編寫一些數據的彙總和篩選的程序,按這些預設的需求,把海量的日誌記錄,使用統計算法歸併縮小,存入到預建索引的數據表中,一般我們會使用按小時或按天去歸併,這樣無論多少條記錄,可能都會變成有限的幾十條或幾百條,數據量會減少幾個數量級。

爲了解決統計數據結構過於複雜的問題,人們不再修改日誌的字段結構,而是根據具體不同的統計需求,建立不同的“報表”數據表,由經過歸併的日誌數據表來進行統計,結果記錄於報表數據表中。這也大大加快了報表的重複展示。雖然這種做法能解決很多問題,但是最終還是有一些缺陷:當我們產生的日誌數據量很大,而且產生日誌的程序很多,二者這些程序都部署在不同的服務器上的時候,要蒐集和歸併大量的日誌文件,是一件不容易的事情,因爲單一的一臺服務器往往承受不住多臺服務器產生的日誌數據,存儲的磁盤很容易就爆滿了;第二是這種系統的數據歸併程序和報表統計程序,都是根據具體的業務需求來編寫的,現實情況下,這些需求往往多變,這就讓維護這套系統的程序員疲於奔命,要不停的修改這些程序。

這裏寫圖片描述
根據上面總結的缺點,以及在Google的MapReduce思想啓發下,現在很多海量數據統計系統,會設計成這樣:首先,日誌文件需要一個分佈式的存儲系統來集中存放,我們現在有很多這樣的開源軟件可供選擇,比如kafka,或者BigTable;然後,我們需要以某種腳本語言,快速開發歸併過濾程序。在這裏的“歸併”和“過濾”,實際上已經是某種意義上的統計,或者叫對某種特徵數據的抽取。這個功能的腳本,如果僅僅以awk之類的模型去做,還是比較耗費開發人員工作量的,所以,還應該有以定義字段統計方法(最大、最小、平均、總數)和條件(等於、不等於、大於、小於、包含、不包含、並且、或者)的API,這樣才能快速的開發這種統計和過濾的程序。

除了要能定義字段統計方法和過濾條件,還有一個重要的回調功能,就是能自動按某條件進行拆分統計任務。——這個就是MapReduce中的Map函數。但是一般的業務統計系統,Map函數是無需太複雜的,設置大部分都可以默認成按某個字段分段,比如可以按“時間”字段,每1000000條拆分一個任務、或者按“用戶ID”字段取模來拆分。由於我們的業務系統往往並非Google的網頁訪問統計程序,也不是淘寶的商品推薦預測程序,而僅僅是需要利用多臺服務器一起做統計,所以我們的“拆分”邏輯是可以比較簡單來做的。在拆分工作完成後,我們可以部署多臺統計服務器執行這些工作,這些服務器最後都會把結果數據插入到一個數據庫中。

如果我們使用SQL數據庫,我們就要自己做好分庫分表的僞分佈式存儲工作,好處是後續的報表邏輯可以用簡單的SQL來定義生成;如果我們不使用SQL數據庫,我們則需要把報表生成的工作,放在拆分彙總的步驟完成:多臺統計服務器的結果先回寫到一個存儲空間,然後彙總服務器根據報表需求,使用分拆的統計結果,計算出真正需要的報表結果,然後寫入到某種報表存儲中(比如文件)。這個步驟,實際上就是Reduce的過程。這個過程也是需要編寫Reduce函數的。在一般的業務系統中,我建議使用SQL數據庫,因爲編寫SQL和WEB的腳本是比較容易掌握的技能,用這種方案來取代編寫Reduce函數,更容易適應變化快的需求。但如果彙總技術的數據量還是很大,並且統計需求比較穩定,那麼使用編寫Reduce函數的方法會比較容易提高統計系統的運行性能。
這裏寫圖片描述

這裏寫圖片描述
當我們把統計系統建立起來,我們就可以利用它做第二層的需求——實時監控。說到底,實時監控不過是設置了一個統計報表,然後增加對其某幾個指標的閾值;由程序自動運行報表的生成,然後程序去判斷這些指標有無超越既定閾值範圍,決定是否發出報警。一般做實時監控,統計系統的後段Reduce就不會選擇SQL數據庫,原因是我們需要更快的把報表生成出來,SQL的運行受數據庫的限制,難以分佈式運算;如果我們使用Reduce函數,我們可以讓不同的Reduce函數在不同的服務器上運行,提供針對不同數據項的監控報警。

這裏寫圖片描述
最後大概說說預測系統的構建。一般來說最流行的是使用神經網絡算法對數據進行運算,所以我們在經過MapReduce之後的數據,可能不適合直接用來運算。這樣我們就需要更龐大穩定的分佈式存儲系統,用來存放更多的原始日誌數據。但是,我們依然用其他的方式來提供預測的能力,比如使用一些人工設定的統計數據模型,比如用戶畫像對比,來做一些預測運算。舉個例子,我們可以先設定一個用戶的數據特徵,比如性別、年齡、使用產品的時間段、消費水平,然後根據這些特徵對購買某種類商品的行爲進行統計,然後我們就能得到一個報表,這樣我們就得到一個報表:各個性別、年齡段、使用實踐、消費能力的人對某貨品的購買量佔全體的百分比。然後我們拿到一個用戶,就把他的性別、年齡等特徵數據放入這個報表中做對比,看是屬於哪一段的,就能得到一個預測值。
這裏寫圖片描述

在諸多底層設施中,分佈式存儲系統始終是最核心的部件,首先建設好這一塊是毫無疑問的。至於預測本身,大量開發統計模型,現在也是比較符合一般業務系統的限制,所以在神經網絡算法還沒能很方便的運用前,先降低統計模型和數據對比的開發複雜度,也是很不錯的選擇。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章