本篇是談資料工程 (data engineering) 的最後一篇,之後會談另一個主題:資料分析 (data analysis) 。最後一篇談的議題還是在資料工程的範疇之內,但是,解決方案會略為超出一般所認知現代資料棧 (modern data stack) 的邊界。刻意找一些超出現代資料棧可以處理的議題來討論,這是源於我工作經驗之中的啟發。
在序章有提到 L 社的業務部的 BI 部門工作,那段時間,有一回,我就被 BI 部門的主管找去協助處理 JavaScript Debug 的問題。那時,在 L 社的業務部,大部分的員工都是業務,只有少數的員工有軟體開發的背景,就算有軟體開發的背景,多半技藝也早已荒廢。在這種環境之下, BI 部門就成為了整個業務部門裡,技術能力最強的團隊之一。也因此,一些跟 BI 可說是『一表三千里』關系的問題,像是 JavaScript Debug 問題,也還是交給 BI 部門處理。
照我的經驗,如果資料團隊的成果不錯,也許明天,就會接到包山包海的難題,所以下列議題還是先準備一下吧:
異質資料整合問題在各個產業都有可能發生,而在金融業可能因為較早導入 IT 技術,不同世代 IT 技術常在金融業有多代同堂的『榮景』,異質資料整合的問題往往特別嚴重。
先簡述一下何謂「異質資料整合問題」:
一家公司的軟體系統內有很多個不同的子系統,比方說 20 個,各自獨立負責不同的產品功能給客戶。這些子系統有的可以匯出 CSV 報表、有的可以提供 Restful API、有的可以提供 xml API …、總之,有許多不同種的格式。當需要做出一些企業的內部報表時,因為必須要在同一時間需要存取多個子系統的資料,這就是異質資料整合問題。
異質資料整合問題的解決方案,它必須滿足下列兩個條件:
異質資料整合當然還是可以用現代資料棧來處理,EL 如果與 T 解耦了,開發起來就會滿快的。然而,現代資料棧處理起來可能不順的點,主要是卡在「即時 (real time)」的要求。在常見的 BI 場景,可以接受的資料延遲是一天左右。昨天早上的業績資料,不需要昨天中午就立刻同步到資料倉儲,今天臨晨再同步即可。一旦需要做到即時 (real time),那 EL 的部分就會立刻變得複雜且困難。
而 SQL 引擎恰好可以滿足異質資料整合問題的兩個條件:
也因此, SQL 引擎成為了異質資料整合問題的首選解決方案。開源的解決方案有 Trino。
在廣告業,因為廣告需要做即時的競價,它們有時候會希望 BI 提供的報表不是延時一天的資料,而是即時報表,資料隨時是最新的。換言之,如果 EL 程式每一小時同步一次、甚至每 10 分鐘同步一次,也可能還是不滿足需求。
當營運資料庫 (operational database) 寫入時,設定好資料庫的異動資料擷取 (change data capture),並且把這個異動 (change) 不停地更新到資料倉儲 (data warehouse),這個就是串流資料同步。實作了串流資料同步之後,就可以做出即時報表。
許多跟資料倉儲相關的應用,都會有 io 太多的問題。如果有大量的資料必須不停地來回資料庫與後端程式,那很容易造成效能低下。
在前面一篇文有一個案例,本來計算存貨成本的 FIFO 計算,是透過 Node.js + SQL 來完成的,後來改成只用 SQL 來做運算,這樣子就是把 FIFO 演算法直接用 SQL 來實現,這個作法就可以視為是一種資料庫嵌入運算。
資料庫嵌入運算的開源解決方案有 Apache MADlib 。
在 SSD 發明之後,其實 RDBMS 可以承受的 join 數目上限已經大幅地提高了。join 的特性就是會造成大量的硬碟的任意讀寫 (random access)。然而,還是有少數的應用,特別是推荐系統、詐欺偵測之類的演算法,會導致大量的 join ,因此還是可以讓資料倉儲變得緩慢。
嚴格來講,圖學資料庫還是一樣會要運算大量的 join ,最主要的差別是:『圖學資料庫是在寫入資料時,就已經把點 (vertex) 與點的連接關系 (join relationship),以邊 (edge) 的形式寫進資料庫裡。』所以如果要讀取的時候,本來在 RDBMS 需要做大量的 join 的,在圖學資料庫會瞬間做完,因為這些運算已經在資料寫入時先做過了。
開源的圖學資料庫很多,目前比較流行的是 neo4j
SQL 引擎應該也有其使用場景的限制。
假設 a 來源需要資料100萬筆,b 來源需要 10萬筆, c 來源需要5萬筆。
我個人想,光是程式埶行資料傳輸就可能就要花不少時間。拉到引擎 再 hash join. 然後呈現,感覺就會很慢。
這種情況,也許真的要考慮 streaming real time 的解決方案,然後東西就開始變難了。