線上系統與分析系統對數據效能的不同需求

前面兩篇以系統的觀點分享數據系統儲存與傳輸資料的格式。今天我想分享我對數據分析所使用的格式的看法。

以系統的觀點,資料很自然的是一筆一筆做處理的。這是因為系統在收到一筆資料(Bid Request)之後,是要很快的做反應的(我要出標嘛?要的話出多少錢?)。因此,系統的觀點通常在追求我們對單一筆資料的處理時間。舉例來說,RTB系統都會即時監控平均每一個bid request的處理時間(主管希望系統平均的處理時間在0.05秒以下)。

然而在分析數據時,處理完一筆並沒有太多意義,而是要處理完全部的數據。因此,分析的觀點通常在追求我們處理整體資料的時間。舉例來說,一天有86400秒。如果用和線上系統相同的方式做處理,難道分析一整天的數據,我們就要等一天嘛?

其實大部份的檔案系統,在處理一整段資料時,會比一筆一筆處理來快的許多。這和硬碟的結構有關。只要資料在硬碟上的位置是連續的,當硬碟的指針找到位置後,就可以連續的讀過去。但如果資料在硬碟上不是連續的,那讀取硬碟的指針就需要跳動。這會讓處理資料的速度慢非常多。

以RTB為例,如果每筆Bid Request進來之後,我們需要查詢該使用者的興趣,就會把這樣的數據放到資料庫中。但是如果我是在做分析,想要看使用者的興趣使否會導致Bid Request的價格產生變化,那這樣的數據放到檔案系統其實就可以了。

如果我們把數據放到檔案系統後,再讓系統在收到Bid Request之後自己去找該筆使用者的位置,就會花費許多時間,而造成系統處理該比數據的時間過長。因此在線上系統,我們都會建構一個Key-Value based的資料庫(例如Redis,或Cassandra),讓系統可以在很短的時間內找到使用者的資料。

但是在做分析的線下系統處理數據時,這樣的資料庫系統反而是個累贅。如果數據放到記憶體不會出問題的話,那是最簡單的狀況,只要用excel / R / python等工具就可以簡單處理掉了。如果數據的大小超過記憶體呢?

依照我的經驗,在反正規劃後直接把資料讀到檔案系統,對分析反而是最友善的。

主要的原因在於:我們不知道分析會用到的欄位

一個資料科學家通常都在解決未知的問題。舉例來說,在我想要看使用者的興趣使否會導致Bid Request的價格產生變化之前,我是不知道答案的。這樣的查詢也很可能是最後一次。因此,為了這樣的查詢去建Index,是很沒有效率的。

如果資料庫系統事先沒有準備好Index,那直接倒資料,還不如直接從硬碟讀取整個資料。只要選用的資料格式正確(我們下一篇再談),那效能會非常驚人的快。

但是在實務上,有一種狀況是「每日報表」。這是我們可以事先知道需要分析的欄位,那就可以透過資料庫,或是其他的手段,再大幅加速處理資料的效能。一種作法是直接在線上系統做運算。舉例來說,如果我想要知道每天的花費,那就直接在線上系統收到win notice的時候直接累計花費即可。這樣的效能比我上面提到的,將資料存到硬碟後再讀出來算,要快的多,而且還是即時數據。之後我們再來看看這部份的系統要如何設計的好。

如果大家理解為什麼分析要使用檔案系統後,就可以理解Hadoop / Spark為什麼會被開發出來了。但是這兩個東西無論任何一個,都絕對是需要工程師支援的。因此我直接使用Google的Dataflow服務,專注於開發程式邏輯,將系統的維護丟給Google(並付給他們一些費用)。

這也是今年我獲得最大的技能:用小小的人力做出大大的事情中,一個很好的經驗:如何利用各種雲端服務來讓自己專注在最有價值的工作內容。