Hive中優化經驗小結

2021-10-16 03:37:16 字數 3488 閱讀 4673

以下內容整理自學習資料和自己平時實踐中遇見的一些問題和經驗小結

•避免記憶體溢位

將條目少的表/子查詢放在 join的左邊。 原因是在 join 操作的 reduce 階段,位於 join左邊的表的內容會被載入進記憶體,將條目少的表放在左邊,可以有效減少發生記憶體溢位的機率。

•解決資料傾斜問題,多發生於資料在節點上分布不均勻,join時左邊的表key分布比較集中(空值較多),count(distinct)字段存在大量值為null或空的記錄等場景

1. 引數控制 hive.groupby.skewindata =true。

2. 在key前面加上乙個隨機數,範圍為[0,reducer數量),把傾斜的資料分到不同的reduce上。

3. 當乙個小表關聯乙個超大表時,容易發生資料傾斜,可以用mapjoin把小表全部載入到內存在map端進行join,避免reducer處理,hive.auto.convert.join = true可以自動選擇小表mapjoin。

•控制合理的map reduce的task數,能有效提公升效能

1. 減少map數可以通過合併小檔案來實現,增加map數的可以通過控制上乙個job的reduer數來控制。

2. 不指定reducer個數的情況下,hive分配reducer個數基於引數1:hive.exec.reducers.bytes.per.reducer(預設為1g),引數2 :hive.exec.reducers.max(預設為999),計算reducer數的公式  n=min(引數2,總輸入資料量/引數1),也可以利用引數指定set mapred.reduce.tasks=13。

•減少job數(multi-insert,multi-group by),盡量避免笛卡爾積

•注意一些特殊的情況,比如資料量較大的情況下,慎用count(distinct),order by這類操作

#資料分桶優化

set hive.enforce.bucketing=true

set hive.input.format=org.apache.hadoop.hive.ql.io.bucketizedhiveinputformat

set hive.optimize.bucketmapjoin=true

set hive.optimize.bucketmapjoin.sortedmerge=true

#大小表join優化

hive.mapjoin.smalltable.filesize=25000000 #大表小表的閥值

hive.mapjoin.cache.numrows #mapjoin 存在記憶體裡的資料量 

hive.mapjoin.followby.gby.localtask.max.memory.usage #map join做group by 操作時,可以使用多大的記憶體來儲存資料,如果資料太大,則不會儲存在記憶體裡

hive.mapjoin.localtask.max.memory.usage hive.mapjoin.localtask.max.memory.usage

#小檔案合併優化

set mapred.map.tasks=20; 

set hive.merge.mapfiles = true #在map-only的任務結束時合併小檔案

set hive.merge.mapredfiles = true #預設是false,true時在map-reduce的任務結束時合併小檔案

set hive.merge.size.per.task = 256*1000*1000 #合併檔案的大小

set mapred.max.split.size=256000000;  #每個map最大分割大小

set mapred.min.split.size.per.node=100000000; #乙個節點上split的最少值,決定了多個data node上的檔案是否需要合併~

set hive.input.format=org.apache.hadoop.hive.ql.io.combinehiveinputformat;  #執行map前進行小檔案合併

案例1向tmp_content表中按照t_when欄位匯入對應分割槽時,生成的mr任務數量太少導致作業卡住,通過下列引數可以進行拆分然後就可以正常匯入了。

set hive.exec.dynamici.partition=true;

set hive.exec.dynamic.partition.mode=nonstrict;

set hive.exec.max.dynamic.partitions=2048;

set hive.exec.max.dynamic.partitions.pernode=1000;

set hive.exec.reducers.max=500;

set hive.exec.max.created.files=500000;  

set mapred.reduce.tasks =20000;  

set hive.merge.mapfiles=true;

insert overwrite table tmp_content partition(dt)

select msg_id,account_id,t_when,substr(t_when,1,8) from tmp_content_his distribute by rand();

案例2任務中不管資料量多大,不管有沒有設定調整reduce個數的引數,任務中一直都只有乙個reduce任務可能原因:

1. 除了資料量小於hive.exec.reducers.bytes.per.reducer引數值的情況外

2. 沒有group by的彙總

3. 用了order by

案例3環境如下:

hive.merge.mapredfiles=true (預設是false,可以在hive-site.xml裡配置)

hive.merge.mapfiles=true

hive.merge.size.per.task=256000000

mapred.map.tasks=2

因為合併小檔案預設為true,而dfs.block.size與hive.merge.size.per.task的搭配使得合併後的絕大部分檔案都在256mb左右。

case 1:

現在我們假設有3個300mb大小的檔案,

整個job會有6個map,其中3個map分別處理256mb的資料,還有3個map分別處理44mb的資料。

木桶效應就來了,整個job的map階段的執行時間不是看最短的1個map的執行時間,而是看最長的1個map的執行時間。所以,雖然有3個map分別只處理44mb的資料,可以很快跑完,但它們還是要等待另外3個處理256mb的map。顯然,處理256mb的3個map拖了整個job的後腿。

case 2:

如果我們把mapred.map.tasks設定成6,再來看一下有什麼變化:

goalsize = min(900mb/6,256mb) = 150mb

整個job同樣會分配6個map來處理,每個map處理150mb的資料,非常均勻,誰都不會拖後腿,最合理地分配了資源,執行時間大約為case 1的59%(150/256)

hive優化經驗

hive是 資料倉儲 主要涉及到對海量資料的 儲存和讀取 以及資料的處理 資料的儲存和讀取基本是基於hadoop的hdfs,所以要進行的優化就是 提高資料的傳輸 速度,可以 通過配置引數 map和reduce階段 優化hive的效能 如 在map階段設定task的數量 mapred.min.spli...

01 hive優化總結經驗

hive優化總結 hive是將符合sql語法的字串解析生成可以在hadoop上執行的mapreduce的工具。使用hive盡量按照分布式計算的一些特點來設計sql,和傳統關係型資料庫有區別,所以需要去掉原有關係型資料庫下開發的一些固有思維。基本原則 1 盡量盡早地過濾資料,減少每個階段的資料量,對於...

Hive專案經驗

1.hive的資料傳輸 hive 中的 null 在底層是以 n 來儲存,而 mysql 中的 null 在底層就是 null,為了 保證資料兩端的一致性。在匯出資料時採用 input null string 和 input null non string 兩個參 數。匯入資料時採用 null st...