天天看點

impala+kudu優化

打開網易雲,準備tnd哭
           

目錄

1.timestamp類型

2.統計資訊

3.看懂執行計劃

4.臨時表使用parquet

5.join方式&join順序

6.not in 

7.寫kudu

1.timestamp類型

把日期字段轉為timestamp類型,+日期函數,性能不是一般的贊,注意:kudu中timestamp和impala中的timestamp存儲格式不一緻,不要将timestamp類型字段作為主鍵,之前在cdh5.16上,以timestamp作主鍵,impala往該表寫,造成impala服務宕了,後來加了才解決,這2參數後面7.寫kudu會介紹

impala+kudu優化
impala+kudu優化

2.統計資訊

join多的情況下,将每個表執行compute stats 表名,impala優化器會選擇一種最優的方式去join(有時不一定是最優解),單表的話就别浪費資源來擷取統計資訊了

compute stats會将表每個字段都執行以下

impala+kudu優化

ndv類似count(distinct field),前者是估值,是以表大的話,執行特别耗時,

impala+kudu優化

100多G的表,耗時3分鐘

示例:執行前先看執行計劃

impala+kudu優化

三張表的行數

t6:39668698  t1:119764290  a:67694913

impala+kudu優化

可以看到(後面3會介紹執行計劃,相比spark、hive,impala的執行計劃真的賊清晰了), a表被廣播了,6kw的一個表,最上面有警告,

有1個表沒統計資訊,就是被廣播的那個,impala預設會将表廣播(類似hive、spark的map join),是以擷取完a表的統計資訊,再次檢視執行計劃

impala+kudu優化

partitioned join,完美了 

3.看懂執行計劃

示例sql:哈哈,一般我不會寫from後跟多表的,就以下面為例吧

impala+kudu優化

檢視執行計劃

impala+kudu優化

涉及到表的資料量如下:

c 2.3億、e 89、b 4000w、a 1.2億、d 25000

執行計劃是從下往上看:

  1. 掃描c表,并shuffle, exchange[hash(c.proposalno)]類似MR的shuffle,就是一個partiton&網絡fetch的過程
  2. 掃描b表,并shuffle,因為b表要與c表關聯,是以shuffle的key也是proposalno
  3. b、c關聯
  4. 掃描a表,exchange[broadcast],意味着會将a表廣播到所有節點 因為a表是4000w的大表,是以這裡需要調整,調整為shuffle join
  5. b、c關聯的結果與a表關聯
  6. 掃描d表,exchange[broadcast],将d表廣播到所有節點
  7. d表與前面關聯的結果集關聯
  8. 掃描e表,exchange[broadcast],将e表廣播到所有節點
  9. e表與前面關聯的結果及關聯
  10. aggregate count(*),每個節點聚合子結果集的行數,
  11. 協調節點,(jdbc串連impala指定哪個節點,哪個節點就是協調節點),merge,合并别的節點發送過來的行數,就是最終結果了

上面就是在指令行或者jdbc工具(hue、dbvisual)等可以在執行前檢視執行計劃來看多表關聯的時候是否有大表被廣播,join優化目的也是要防止大表被廣播

如果sql已經在執行,也可以去協調節點:25000去檢視圖形化界面

impala+kudu優化
impala+kudu優化

就是剛指令行執行計劃的可視化界面,不過可以等sql執行完成後,檢視各表關聯後的行數,也可以summary檢視每一步的預估資源和實際使用資源 

4.臨時表使用parquet

對于沒有delete、update的dw層或非ods層的表,使用parquet格式

impala+kudu優化
impala+kudu優化

parquet 250s

impala+kudu優化
impala+kudu優化

接近400s 

5.join方式&join順序

impala+kudu優化

務必在多表關聯sql前首先執行explain query,防止大表被broadcast

impala+kudu優化

可以看到雖然impala的優化器有所有表的統計資訊,但還是把t1表給廣播出去了,

t1表是一張1億+行的表,優化器優化的關聯順序方式不一定是最優的,我們需要手動指定下關聯方式,将sql改為如下:

impala+kudu優化

加在t6、t1之間加join [shuffle],注意:t6必須在前邊,如果t1在前邊,不生效,關聯方式還是broadcast

這種我們隻是指定了這兩張表的關聯方式,impala優化器依然會給我們優化關聯順序、和方式,我們可以在select後面加 straight_join,不讓impala優化器來優化,按sql的書寫順序來關聯表

impala+kudu優化

按我們的書寫順序來看,t1表先與a表以broadcast方式關聯,将a表廣播,然後結果再與

t6以broadcast方式關聯,将t6表廣播

檢視執行計劃:

impala+kudu優化

 與書寫順序一緻,當使用straight_join時,需要手動将表排序,原則是先最大表,然後最小表,次小表,次次小表......直到所有表關聯完 ,盡量保證中間物化結果最小,left deep tree 

6.not in 

impala not int預設将右表廣播,而且沒法指定partitioned join ,使用left anti join 

7.寫kudu

impala+kudu優化

參考自

https://docs.cloudera.com/documentation/enterprise/5-16-x/topics/impala_kudu.html#kudu_dml

大緻意思是:從CDH5.12/Impala2.9開始,寫資料到kudu表自動添加一個exchange和一個sort節點到執行plan(疑問:隻添加2個節點幹這事?那這2個節點肯定會大量的網絡I/O和記憶體消耗,勢必會成為性能瓶頸),為了根據目标表的分區/主鍵來partition和sort資料,因為kudu在寫入的時候會partition和sort,是以impala預分區/排序能降低kudu負載并且防止大批量的insert逾時(疑問:應該可以避免kudu逾時,impala預處理好資料kudu直接刷盤)。然而,這種預設行為可能降低寫入資料時end-to-end性能(不讓impala預處理,剛執行寫入沒多久,目标表就可以select出資料,讓impala預處理,可能很長時間後,才能select到),從CDH5.13/Impala2.10起,可以使用、讓impala不預排序、分區資料。

示例均為目标表不存在, 如果目标表存在的話,直接insert即可

impala+kudu優化
impala+kudu優化

 記得調大點kudu的記憶體