1. 程式人生 > >ETL調優的一些分享

ETL調優的一些分享

ETL是構建資料倉庫的重要一環。通過該過程使用者將所需資料提取出來,並按照已定義的模型匯入資料倉庫。由於ETL是建立資料倉庫的必經過程,它的效率將影響整個資料倉庫的構建,因此它的有效調優具有很高的重要性。在實際應用中我們通常建議把ETL業務的調優分為若干思路,從而保證調優充分有序進行,避免遺漏,最大化提升ETL的執行效率。

我們將分上下兩篇文章介紹ETL業務的調優手段。本文將首先介紹以下三個:檢查資源是否有效配置;收集資料特徵,確定分割槽分桶;以及Task執行情況收集和監控。並對每個步驟中的調優原則和注意事項進行講解,提出相應的解決辦法和思路。然後通過案例分析幫助讀者加深理解。

1.檢查資源是否有效配置

關於資源,一般原則是根據需求場景,儘量最大化資源的有效配置。POC可考慮採取最大化的配置方式。實施專案中標準可適當保守,確保系統的穩定性。

假如這個叢集主要用作批處理,一般建議Inceptor使用50%左右的CPU資源,另外單個executor不要超過16 core。如果硬體配置比較不錯,如伺服器有40個以上CPU core,建議採用多executor的方式來部署,譬如採用2 executor 每個10 core的方式,會比1 executor每個20 core的效果更好。

如果叢集同時部署了其他服務,請保證其他的服務的資源前提下,給Inceptor部署儘量多的計算資源。計算資源的提高一般都會帶來接近線性的分析效能提升。

2.收集資料特徵,確定分割槽分桶

請注意,合理的DDL設計是批處理專案的一個非常關鍵的過程,需要綜合分析業務和資料特點來確定。我們建議開發人員投入足夠多的時間和經歷來設計DDL,並充分論證設計的有效性。

1.分割槽

分割槽欄位選擇

一般原則為根據系統的業務型別來分則分割槽欄位。通常來講事實表是資料都包含時間屬性,而報表業務也多在一定的時間範圍內做統計分析,那麼根據時間欄位進行分割槽是常用的選擇。而如果業務更多按照部門做統計分析,那麼更適合按照部門程式碼,地域程式碼進行分割槽。所以貼近業務的特點選擇分割槽是第一要素。

另外資料的分佈特點也是分割槽欄位選擇要考量的重要因素。假如按照使用者期望按照某個欄位A做分割槽,但是這個欄位A的分佈絕對傾斜(譬如欄位A一共有1000個不同的數值,但是50%的值都是0,假如按照這個欄位分割槽,那麼對應的分割槽就佔了全表50%的資料,這樣會導致SQL業務的低效),這個時候選擇欄位A就不是一個合理的選擇。

不過只要資料分佈不是絕對傾斜,我們是可以通過Range分割槽指定不同大小的方式來有效的規避傾斜問題的,因此還是可以選用該欄位用於資料分割槽。譬如企業使用者資料,假如2016年使用者數是2015年的3倍,我們在選擇分割槽的時候2016年按照1個月為一個分割槽,而2015年每三個月為一個分割槽,而不是簡單的數值等值切分Range。另外一個常見的情況是按照地域進行分割槽,我們建議把業務量較多的地域單獨放在一個區,其餘業務量不多的地域進行整合,從而保證各個區之間資料量大致均衡,避免出現大部分割槽沒有資料或者資料非常少的情況。如果發現某些區資料特別傾斜,則需要考慮進一步切分或者更換分割槽欄位。

分割槽個數

分割槽個數的選擇需要綜合考量資料的特性,在選擇好分割槽欄位後,我們需要根據資料的特點確定分割槽個數的可選擇區間。

分割槽個數不宜太少,需要根據業務特點來確定,並保證分割槽裡面不會太多的冷熱資料混合。譬如SQL業務大部分都是操作2~3個月的資料,那麼我們就儘量按照3個月做一個分割槽,如果我們選擇1年做一個分割槽的話,每個SQL業務實際執行的時候就會多讀取前面9個月的資料,這這部分的資源和IO開銷都是沒有必要的。

實際情況中我們看到的更多的DDL設計都是分割槽數量過多,譬如單個分割槽的資料量不超過1GB,或者按照天來分割槽,這些都是不合適的設計。分割槽過多的壞處是會導致過多的系統資源佔用(譬如全表掃表類業務,Inceptor會啟動 “分割槽數×分桶數” 的任務去完成這個SQL任務,分割槽數量或分桶數量過多都會導致叢集資源在比較長的週期內被這個任務佔據)。一般我們建議分割槽數量在幾十以內。

Reiterate:不要按天分割槽!

2 分桶

分桶欄位選擇

一般遵循的原則為,選擇離散度高的欄位進行分桶。可以通過收集的資料特徵,如Distinct Value來做參考,值越大的可以優先作為考慮物件。分桶欄位選擇時,注意儘量使記錄分佈均勻,避免資料傾斜。

分桶個數

針對不同的儲存型別,分桶個數的標準稍微有所差別。以ORC表舉例,對於普通ORC表,單分桶大小可以在200M以內;對於ORC事務表,標準適當降低,檔案大小限制在100M以內,記錄條數限制在幾百萬條左右。

另外,在考慮分桶個數的時候,同時要考慮是否已經分過區。對於已經分過區的表,要按照單區的大小和條數進行桶數的估計,而不是依照原始表。例如某執行商專案中,我們發現某些表進行分割槽分桶後,分桶數量過大,導致每個桶的檔案大小僅僅為幾十K,這樣就會使單個Task的執行效率很低,同時總體任務數過大也對系統資源造成極大浪費,併發度上不去。調整方案是根據實際情況,將原桶數降低數量級。

在進行分割槽分桶時,還應注意以下因素:

因為事務性業務大部分情況下建的都是Range分割槽分桶表。此種情況下,Map Task的數量=分割槽數×分桶數,所以,在考慮分割槽數和分桶數時要綜合考慮,Map Task的數量不能過大,比如幾千上萬,這樣可能使單個Task的執行效率太低,並且佔用了系統資源,降低了系統併發度。

3.Task執行情況收集和監控

主要在4040介面上從以下三個方面進行監控:
1) Task數量

Task數量存在過多和過少兩種情況,可以通過在4040介面上對Task數量排序進行檢查。

對於過多的情況,例如發現某Stage有超過幾千上萬的Task,應檢視是否合理。如上所述的分割槽分桶導致的任務數量過大就是一個例子。 另外,如果SQL中有針對分割槽欄位的過濾,但是在4040上觀察到Task數量的數量仍然很多,需要檢查分割槽剪枝是否成功。

然而,任務數量過少會導致單Task的任務量過大,執行時間過長,也需要進行調整。

2) Task傾斜導致的拖尾。

一般情況的主要成因是某些Key導致的傾斜,如NULL值或者熱點地域導致傾斜;還有其他個別情況例如視窗函式導致的單Task任務量過大,引發拖尾。例如我們在某客戶業務中遇到,因row_number視窗函式不加partition by,導致單個Task全排序的情況。定位問題後,可採取相應的措施解決。

Case Study:

這裡寫圖片描述

由4040介面觀察出, task 0的單任務執行時間超過10mins。排除由NULL值導致的經典task 0傾斜問題,最後定位是視窗函式row_number不帶partition by而導致的全域性排序所致。

3) 同時併發執行的stage數量。

一般情況下給定CPU資源以及表的DDL設計後,我們是可以大概確定4040頁面的併發任務數總是處在一個合理的範圍內。譬如說當前Inceptor配置了400 core,而一般的SQL都操作一個分割槽的資料,假如這個分割槽有20個bucket,那麼總體上我們應該能夠看到同時併發的stage數量應該是 “資源總量 % SQL任務平均任務數”,在這個例子中就是400%20=20個。如果我們觀察到併發任務數比預期的要低,這個時候就需要做一些檢查。在4040介面上可以觀察每個Stage提交到執行結束的時間點,可以監控此類資訊,確保執行的合理性。

Case Study:

下圖所示為某個測試場景,上一個Stage結束到下一個Stage提交之間的時間間隔超過3mins。分析hive-server2.log發現異常顯示有等鎖超時的現象,通過有效的規避鎖競爭等問題來避免了這個問題,同時也發現系統性能和併發度有較大提升。

這裡寫圖片描述

4.總結

本文介紹了關於ETL業務調優的三個思路,並針對每個調優步驟中具體的注意事項和調優原則進行了闡述和分析。

在進行ETL業務調優時,我們要注意把握調優步驟中的關鍵點,掌握每步驟的調優原則。在遵照一般性原則的基礎上,具體問題具體分析,理解和掌握每個步驟可能出現的問題及原因,及時排查解決,將ETL調優儘量應用在關鍵位置。

下一篇文章我們將通過幾則案例,繼續介紹其他的幾個思路,希望可以幫助讀者全面掌握ETL業務調優的具體步驟並加深理解,知道什麼時候應該用什麼手段實現ETL調優。