Hive優化相關設定

hiekay發表於2018-11-29
引數
hive.optimize.cp=true:列裁剪
hive.optimize.prunner:分割槽裁剪
hive.limit.optimize.enable=true:優化LIMIT n語句
hive.limit.row.max.size=1000000:
hive.limit.optimize.limit.file=10:最大檔案數
1. 本地模式(小任務):

需要滿足以下條件:
  1.job的輸入資料大小必須小於引數:hive.exec.mode.local.auto.inputbytes.max(預設128MB)
  2.job的map數必須小於引數:hive.exec.mode.local.auto.tasks.max(預設4)
  3.job的reduce數必須為0或者1

hive.exec.mode.local.auto.inputbytes.max=134217728
hive.exec.mode.local.auto.tasks.max=4
hive.exec.mode.local.auto=true
hive.mapred.local.mem:本地模式啟動的JVM記憶體大小
2. 併發執行:
hive.exec.parallel=true ,預設為false
hive.exec.parallel.thread.number=8
3.Strict Mode:

hive.mapred.mode=true,嚴格模式不允許執行以下查詢:
分割槽表上沒有指定了分割槽
沒有limit限制的order by語句
笛卡爾積:JOIN時沒有ON語句

4.動態分割槽:
hive.exec.dynamic.partition.mode=strict:該模式下必須指定一個靜態分割槽
hive.exec.max.dynamic.partitions=1000
hive.exec.max.dynamic.partitions.pernode=100:在每一個mapper/reducer節點允許建立的最大分割槽數
DATANODE:dfs.datanode.max.xceivers=8192:允許DATANODE開啟多少個檔案
5.推測執行:
mapred.map.tasks.speculative.execution=true
mapred.reduce.tasks.speculative.execution=true
hive.mapred.reduce.tasks.speculative.execution=true;
6.Single MapReduce MultiGROUP BY
hive.multigroupby.singlemar=true:當多個GROUP BY語句有相同的分組列,則會優化為一個MR任務
7. 是否提供虛擬列
hive.exec.rowoffset:是否提供虛擬列
8. 分組

兩個聚集函式不能有不同的DISTINCT列,以下表示式是錯誤的:
INSERT OVERWRITE TABLE pv_gender_agg SELECT pv_users.gender, count(DISTINCT pv_users.userid), count(DISTINCT pv_users.ip) FROM pv_users GROUP BY pv_users.gender;
SELECT語句中只能有GROUP BY的列或者聚集函式。

9.
hive.map.aggr=true;在map中會做部分聚集操作,效率更高但需要更多的記憶體。
hive.groupby.mapaggr.checkinterval:在Map端進行聚合操作的條目數目
10.

hive.groupby.skewindata=true:資料傾斜時負載均衡,當選項設定為true,生成的查詢計劃會有兩個MRJob。第一個MRJob 中,
Map的輸出結果集合會隨機分佈到Reduce中,每個Reduce做部分聚合操作,並輸出結果,這樣處理的結果是相同的GroupBy Key
有可能被分發到不同的Reduce中,從而達到負載均衡的目的;第二個MRJob再根據預處理的資料結果按照GroupBy Key分佈到
Reduce中(這個過程可以保證相同的GroupBy Key被分佈到同一個Reduce中),最後完成最終的聚合操作。

11.Multi-Group-By Inserts:
FROM test
INSERT OVERWRITE TABLE count1
SELECT count(DISTINCT test.dqcode)
GROUP BY test.zipcode
INSERT OVERWRITE TABLE count2
SELECT count(DISTINCT test.dqcode)
GROUP BY test.sfcode;
12.排序
ORDER BY colName ASC/DESC
hive.mapred.mode=strict時需要跟limit子句
hive.mapred.mode=nonstrict時使用單個reduce完成排序
SORT BY colName ASC/DESC :每個reduce內排序
DISTRIBUTE BY(子查詢情況下使用 ):控制特定行應該到哪個reducer,並不保證reduce內資料的順序
CLUSTER BY :當SORT BY 、DISTRIBUTE BY使用相同的列時。
13.合併小檔案
hive.merg.mapfiles=true:合併map輸出
hive.merge.mapredfiles=false:合併reduce輸出
hive.merge.size.per.task=256*1000*1000:合併檔案的大小
hive.mergejob.maponly=true:如果支援CombineHiveInputFormat則生成只有Map的任務執行merge
hive.merge.smallfiles.avgsize=16000000:檔案的平均大小小於該值時,會啟動一個MR任務執行merge。
14.map/reduce數目

減少map數目:
  set mapred.max.split.size
  set mapred.min.split.size
  set mapred.min.split.size.per.node
  set mapred.min.split.size.per.rack
  set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
增加map數目:
當input的檔案都很大,任務邏輯複雜,map執行非常慢的時候,可以考慮增加Map數,來使得每個map處理的資料量減少,從而提高任務的執行效率。
假設有這樣一個任務:
  select data_desc, count(1), count(distinct id),sum(case when …),sum(case when …),sum(…) from a group by data_desc
如果表a只有一個檔案,大小為120M,但包含幾千萬的記錄,如果用1個map去完成這個任務,肯定是比較耗時的,這種情況下,我們要考慮將這一個檔案合理的拆分成多個,這樣就可以用多個map任務去完成。
  set mapred.reduce.tasks=10;
  create table a_1 as select * from a distribute by rand(123);
這樣會將a表的記錄,隨機的分散到包含10個檔案的a_1表中,再用a_1代替上面sql中的a表,則會用10個map任務去完成。每個map任務處理大於12M(幾百萬記錄)的資料,效率肯定會好很多。

reduce數目設定:
 引數1:hive.exec.reducers.bytes.per.reducer=1G:每個reduce任務處理的資料量
 引數2:hive.exec.reducers.max=999(0.95*TaskTracker數):每個任務最大的reduce數目
 reducer數=min(引數2,總輸入資料量/引數1)
 set mapred.reduce.tasks:每個任務預設的reduce數目。典型為0.99*reduce槽數,hive將其設定為-1,自動確定reduce數目。

15.使用索引:
hive.optimize.index.filter:自動使用索引
hive.optimize.index.groupby:使用聚合索引優化GROUP BY操作


相關文章