天天看點

ETL為什麼經常變成ELT甚至LET?

ETL是将資料從來源端經過清洗(extract)、轉換(transform)、加載(load)至目的端的過程。正常的 ETL 過程應當是 E、T、L 這三個步驟逐漸進行,也就是先清洗轉換之後再加載進目标端(通常是資料庫),最後在資料庫中的隻是合理的結果資料。這個過程本來很合理,但實際過程中經常被執行成ELT甚至LET,即源端資料先裝載進目标庫再進行清洗和轉換。

出現這種現象是因為源端資料可能來源多處,資料庫、檔案、web等等,不僅資料源多樣資料品質也參差不齊,由于E和T這兩個步驟會涉及大量資料計算,除了資料庫以外,其他資料源并不具備多少的計算能力,想要完成這些計算就要先加載到資料庫再進行,這就形成了LET。而且,即使源端是資料庫也會面臨多庫的場景,跨庫完成資料清洗和轉換遠沒有先裝載到目标庫再處理友善,同樣會造成ELT或LET。

那麼ETL變成ELT/LET會帶來哪些問題呢?

首先是時間成本增加。大量未經清洗和轉換的原始(無用)資料裝載進資料庫會帶來過長的時間消耗。而且資料庫的計算資源有限,完成額外的E、T計算勢必要消耗很長時間,進一步增加時間成本。ETL通常是有時間限制的,一般會在業務空閑的時間進行,比如前一天22點到第二天5點,如果在指定時間段沒有完成就會影響第二天的業務,這就是常說的ETL時間視窗。ETL時間過長會導緻時間視窗不足,影響正常業務。

此外,從資料庫容量的角度來看,存儲大量沒有經過清洗轉換的原始資料會占用過多資料庫空間造成資料庫容量過大,導緻資料庫面臨擴容壓力。現代應用經常使用的JSON或XML格式的多層資料入庫還要在資料庫中建立多個關聯的表來存儲,會進一步加劇資料庫容量問題。任務越來越多、資源越來越少、時間視窗有限,這樣就陷入了惡性循環。

那麼,為什麼要把資料加載資料庫後才能做E和T這兩個動作呢?如前所述,是因為資料庫外的計算能力不足,先入庫再計算是為了利用資料庫的計算能力,如果能夠提供庫外計算能力,那麼這個問題也就迎刃而解了,回歸合理的ETL過程。

使用開源集算器SPL可以實作這個目标。

SPL是一款獨立的開源資料計算引擎,提供了不依賴資料庫的計算能力,可以對接多種資料源完成資料處理。基于SPL豐富的計算類庫、靈活文法和過程計算可以很友善地完成複雜資料計算任務,在資料庫外完成資料清洗(E)和轉換(T),将整理後資料加載(L)到目标庫中實作真正的ETL。

庫外計算實作真正ETL

多源支援與混合計算

SPL可以對接多種資料源,這樣來源端資料源無論有無計算能力都可以通過SPL完成資料清洗和轉換。

ETL為什麼經常變成ELT甚至LET?

特别地,SPL還能實作多源混合計算,将多源資料統一清洗轉換後加載到庫,不需要再借助資料庫的計算能力就能完成ETL工作。尤其是對JSON和XML等多層資料格式提供了很好支援,簡單一個函數就能完成解析,非常友善。

舉個簡單的例子,将json與資料庫混合計算後更新到資料庫的過程:

A
1 =json(file("/data/EO.json").read()) 解析JSON資料
2 =A1.conj(Orders)
3 =A2.select(orderdate>=date(now())) 過濾當日資料
4 =connect(“sourcedb”).query@x(“select ID,Name,Area from Client”) 資料庫資料
5 =join(A3:o,Client;A4:c,ID) 關聯計算
6 =A5.new(o.orderID:orderID,…)
7 =connect(“targetdb”).update(A6,orders) 裝載到目标庫

強計算能力與過程控制

SPL提供了專業的結構化資料對象及其上的豐富運算。不僅分組彙總、循環分支、排序過濾、集合運算等基礎計算可以進行,位置計算、排序排名、不規則分組也提供直接支援。

ETL為什麼經常變成ELT甚至LET?

SPL還提供了專門用于大資料計算的遊标支援,通過遊标就可以處理超過記憶體容量的資料,計算實作與全記憶體方式幾乎完全一樣。比如通過遊标讀取檔案并進行分組彙總:

=file(“persons.txt”).cursor@t(sex,age).groups(sex;avg(age))           

複制

與全記憶體讀取計算:

=file(“persons.txt”).import@t(sex,age).groups(sex;avg(age))           

複制

除了豐富的計算類庫,SPL還支援過程計算,可以按自然思維思維分步編寫代碼,适合完成原本在資料庫中使用存儲過程實作的ETL複雜計算。而SPL計算在資料庫外,不會對資料庫造成負擔,同時兼具靈活性和高性能,實作“庫外存儲過程”的效果,是傳統存儲過程的很好替代。庫外計算還可以為資料庫充分減負。以往要借助資料庫完成的ET計算現在都在庫外完成,既不需要額外消耗資料庫的計算資源,也無需存儲未經清洗的大量原始資料,空間占用也少,資料庫的資源和容量問題都能得到很好解決。

同時,SPL的文法體系比SQL和Java等也更為靈活,涉及E和T計算尤其是複雜計算,算法實作更簡潔代碼更短,開發效率更高。比如在實作某保險公司車險保單ETL業務時,使用SPL不到500格(網格式編碼)代碼就實作了原本2000行存儲過程的計算,工作量減少了1/3以上。(案例詳情:開源 SPL 優化保險公司跑批優從 2 小時到 17 分鐘)

從技術棧的角度來看,基于SPL還可以獲得一緻的文法風格,面對多樣性資料源ETL時可以獲得通用一緻的計算能力。不僅技術路線統一,開發維護也很友善,程式員無需掌握不同資料源資料的處理方法,學習成本也更低。特别的,統一的技術路線具備更強的移植性,ETL資料源變化隻需要更改取數代碼即可,主要的計算邏輯無需更改,具備很強的移植性。

高性能保障時間視窗

對于源資料讀取,SPL能很友善地進行并行處理,充分發揮多CPU的優勢加速資料讀取和計算速度。比如并行取數:

A B
1 fork to(n=12) =connect("sourcedb")
2 =B1.query@x("SELECT * FROM ORDERS WHERE MOD(ORDERID,?)=?", n, A3-1)
3 =A1.conj()

類似的,讀取大檔案時也可以并行:

=file(“orders.txt”).cursor@tm(area,amount;4)           

複制

使用 @m 選項即可建立多路并行遊标,SPL 會自動處理并行以及将結果再彙總。SPL還有很多計算函數也提供并行選項,如過濾A.select()、排序A.sort()等增加@m選項後都可以自動完成并行計算。

在ELT任務中還經常出現資料落地的情況,無論是中間資料還是最後的計算結果,這都涉及資料存儲。SPL提供了兩種二進制存儲形式,不僅存儲了資料類型不必再次解析效率更高,而且還采用了适合的壓縮機制可以有效平衡CUP和硬碟時間,同時提供了行式和列式存儲方式适應更多場景,采用獨有的倍增分段技術還可以實作單檔案可追加分塊方案更友善并行計算。這些高性能存儲機制為計算性能提供了基礎保障,要知道高性能計算依靠的就是存儲和算法。

SPL提供了衆多高性能算法,仍是上述案例(開源 SPL 優化保險公司跑批優從 2 小時到 17 分鐘)中,使用SPL不僅把代碼量減少到1/3,還将計算時間從2小時縮短到17分鐘。其中主要使用了SPL特有的周遊複用技術,可以在對大資料的一次周遊過程中實作多種運算,有效地減少外存通路量。而關系資料庫中用SQL無法實作這樣的運算,有多種運算就需要周遊多次。在本例中就涉及對一個大表進行三次關聯和彙總的運算,使用SQL要将大表周遊三次,而使用SPL隻需要周遊一次,是以獲得了巨大的性能提升。

在ETL業務中還經常出現巨大主子表關聯的情況,比如訂單和訂單明細,這些關聯是通過主鍵(或部分主鍵)的一對多關聯,如果事先按照主鍵排序,那麼關聯計算可以使用有序歸并算法,相對正常HASH JOIN算法,複雜度可以從O(N*M)降到O(M+N),性能将大幅提升。但資料庫基于無序集合理論,SQL也很難利用資料有序來提高性能。在上面案例中也涉及這種主子關聯運算,使用SPL的有序歸并算法大幅提升了關聯性能。

将具備強計算能力的SPL作為ETL過程中的ET引擎,将資料計算從源端和目标端獨立出來不與任何一端耦合在一起,這樣可以獲得更強的靈活性和更高的移植性,同時不對源和目标造成過大壓力,享受庫外計算的便利,實作了真正的ETL過程。同時基于SPL的高性能存儲、高性能算法與并行計算又充分保障了ETL效率,這樣就可以在有限的時間視窗内完成更多ETL任務。

SPL資料

  • SPL官網
  • SPL下載下傳
  • SPL源代碼