Hive引數調優

2021-08-20 21:36:16 字數 4477 閱讀 3726

一、map

階段的優化()1.

map數的計算公式為:

num_map_tasks=

max[$,min($,$)]

mapred.min.spilt.size

指的是資料的最小分割單元大小(預設為1b)

mapred.max.split.size

指的是資料的最大分割單元大小(預設為

256mb

dfs.block.size

指的是hdfs

設定的資料塊大小(這個值是在配置檔案中定好的,而且

hive

是獲取不到的)

所以

map的數量是由

mapred.min.spilt.size

、mapred.max.split.size

這兩個引數的最大值決定的。如果不做修改的話乙個

map task

處理256mb

的資料,增大

mapred.max.split.size

的值可以減少

map的數量,減少

mapred.max.split.size

的值可以增大

map的數量。但是直接修改

mapred.map.tasks

是沒有效果的。如果執行速度較慢,可以考慮增加

map的數量,增加並行度,如果執行速度較快,增加

map數量不太可能加快速度,反而有可能因為初始化

map使速度變慢,此時可以考慮減少

map,這樣可以節省更多資源給其他

job

1.

map數的計算公式為:

num_reduce_tasks=

min[$,($/ $)]

hive.exec.reducers.bytes.per.reducer(預設值為1g)

所以reduce的數量是由輸入的資料量大小決定的,但是reduce的數量不能超過999,可以通過設定hive.exec.reducers.bytes.per.reducer來設定reduce的個數,也可以通過設定mapred.reduce.tasks來設定reduce的數量。

1.        在spill階段,由於記憶體不夠,資料需要溢寫到磁碟再排序,然後對所有的檔案進行merge。可以通過設定io.sort.mb來增大環形緩衝區的大小,避免spill

2.        在copy階段是把檔案從map端copy到reduce端。預設情況下是5%的map完成時reduce就開始啟動copy,這個時候是很浪費資源的,因為reduce一旦啟動就被占用,直到所有的map完成,reduce才可以進行接下來的動作。這個比例可以通過mapred.reduce.slowstart.completed.maps這個引數來設定。如果覺得這麼做會導致reduce端copy的速度減慢,可以通過tasktracker.http.threads決定作為server端的map用於提供資料傳輸服務的執行緒數量。mapred.reduce.parallel.copies可以決定作為client端的reduce同時從map端拉取資料的並行度(一次同時從多少個map

中拉取資料),注意引數協調一致。

1.hive的預設配置可以將對個小檔案合併成乙個map處理,輸出時如果檔案很小也會自動合併,所以不用設定了。關於檔案格式,上述三種rcfile的壓縮比例和查詢時間都比較好一些,可以在建立表時設定指定。

例如:create tablerc_file_test(id int)stored asrcfile;

然後設定引數set hive.exec.compress.output=true;指定輸出格式

另外可以設定hive.default.fileformat來設定輸出格式,適用於createtable as select

例如:set hive.default.fileformat=sequencefile; sethive.exec.compress.output=true;

sequencefile有record和block兩種壓縮方式,block壓縮比更高

setmapred.output.compression.type=block; create table seq_file_test as select *from a;

1.

hadoop的job分為三種模式,分別為本地模式、偽分布式、完全分布式。

set hive.exec.mode.local.auto=true,此時預設情況下如果處理的檔案不超過4個,並且總大小不超過128mb就會啟用local模式

1.        正常情況下mapreduce啟動jvm完成乙個task後就退出了,如果任務花費時間短,但又要多次啟動jvm的情況下(比如對很大資料量進行計數操作),jvm的啟動的啟動時間就會變成乙個比較大的overhead(開銷),這種情況下可以通過設定

mapred.job.reuse.jvm.num.tasks=5; 可以讓jvm執行多次任務之後再退出

1.        比如有個場景:未註冊使用者user_id=0,註冊使用者有唯一的user_id,那麼對於user_id的group by和join時,某個reduce會收到比其他reduce更多的資料。

如果是group by造成的,有兩個引數可以解決:第乙個是hive.map.aggr,他的預設值為true,意思是會做map端的combiner,所以count(*)是看不出區別的,但是

count(distinct)會有一些傾斜。另乙個引數是hive.groupby.skewindata,這個引數的意思是在reduce操作時,拿到的key不是相同值分給同乙個reduce,而是隨機分發(在每個可以後面拼接隨機字串),然後reduce做聚合,做完之後再進行一輪mr,因為要額外啟動一次job,效果不明顯,不推薦使用。

如果是join造成的,可以使用skew join,其原理是把特殊值先不在reduce端計算掉,而是先寫入hdfs,然後啟動一輪map join專門做這個特殊值的計算。需要設定

set hive.optimize.skewjoin=true; 然後根據hive.skewjoin.key的值來判斷超過多少條算特殊值。這種情況可以在sql語句裡將特殊值隔離開來避免資料傾斜:

改寫前:select a.* from logs a join users b on a.user_id = b.user_id; 

改寫後:

select a.* from  (

select a.*

from (select * from logs where user_id = 0)  a

join (select * from users where user_id = 0) b

on a。user_id =  b。user_id

union all

select a.*

from logs a join users b

on a.user_id <> 0 and a。user_id = b.user_id )t; 

1.處理分布式join,一般有兩種方法:

replication join:把其中乙個表複製到所有節點,這樣另乙個表在每個節點上面的分片就可以跟這個完整的表join了;

repartition join:把兩份資料按照join key進行hash重分布,讓每個節點處理hash值相同的join key資料,也就是做區域性的join。

在mr中,replication join對應map side join;repartitionjoin對應reduce side join;

hive預設使用的是reduce side join,但是在其中一張表較小時,可以考慮使用mapside join,因為小表的複製代價小於大表shuffle的代價。set hive.auto.convert.join=true;

hive會根據hive.smalltable.filesize的引數來判斷是否該使用map sidejoin,預設小於25mb算小表。

hive常用引數調優

決定是否可以在 map 端進行聚合操作 開啟資料傾斜時的負載均衡 設定所提交 job 的 reduer 的個數 hive map join 所快取的行數。決定 hive 是否應該自動地根據輸入檔案大小,在本地執行 需要合併的小檔案群的平均大小,預設 16 m。是否根據輸入小表的大小,自動將 redu...

hive效能調優

原文 limit 限制調整 因為使用 limit 語句時候,是先執行整個查詢語句,然後再返回部分結果的 set hive.limit.optimize.enable true set hive.limit.row.max.size 10000 set hive.limit.optimize.limi...

Hive效能調優

軟體環境 hive1.2.1 hadoop2.6.4 直接使用hive cli模式執行 1.設定執行引擎 set hive.execution.engine mr set hive.execution.engine spark 如果設定執行引擎為mr,那麼就會呼叫hadoop的maprecude來執...