業務目的
全量離線運算統計,結果寫入oracle
依賴版本
spark 2.0.1
hive 1.1.0
問題
- 執行時task數量過多
- hive動態分區小文件過多
- 測試環境5運算節點,內存分別爲12G,運行30萬測試數據不斷髮生內存溢出問題
逐步調優
1、執行時task數量過多,總數達到了108000個,OMG,每個任務都是內存溢出,因爲是用sparksql讀hive表,所以spark的spark.default.parallelism強制指定task數並沒有用,考慮–conf spark.sql.shuffle.partitions=30,在查詢hive on hbase外部表時有效,但遇到hive分區表無效,此外考慮通過spark中repartition來處理,但是sparksql原始查詢還是會根據hive分區表的情況開啓task,問題定位到hive分區表。
2、目前是將數據動態分區,執行insert overwrite,產生了大量小文件
如圖可以看到小文件數量達到100個,而且大小都不到10K,這樣一方面對於namenode來說維護成本過高,另一方面在對hive分區表全量數據進行運算清洗時,消耗巨大,導致task數極其不合理。
處理方式:
set mapred.max.split.size=256000000;
set mapred.min.split.size.per.node=100000000;
set mapred.min.split.size.per.rack=100000000;
set mapred.reduce.tasks=20;
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
set hive.map.aggr=true;
set hive.groupby.mapaggr.checkinterval=100000;
set hive.merge.mapfiles = true;
set hive.merge.mapredfiles = true;
set hive.merge.size.per.task=256000000;
set hive.merge.smallfiles.avgsize=16000000;
set hive.exec.reducers.bytes.per.reducer=5120000000;
set hive.exec.reducers.max = 888;
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
-
hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;-使用Combinefileinputformat,將多個小文件打包作爲一個整體的inputsplit,減少map任務數
-
hive.map.aggr=true //用於設定是否在 map 端進行聚合,默認值爲真
-
hive.groupby.mapaggr.checkinterval=100000 //用於設定 map
端進行聚合操作的條目數,根據具體情況設置 -
hive.merge.mapfiles = true #在Map-only的任務結束時合併小文件
-
hive.merge.size.per.task = 256000000 #合併文件的大小
-
hive.merge.smallfiles.avgsize=16000000
#當輸出文件的平均大小小於該值時,啓動一個獨立的map-reduce任務進行文件merge,根據具體情況設置 -
hive.exec.reducers.bytes.per.reducer=5120000000;
輸出文件大小,根據具體情況設置 -
hive.exec.reducers.max = 888 每個任務最大的reduce數,默認爲999
-
mapred.reduce.tasks = 20; reduce task任務數
隨後執行需要的動態分區語句
insert overwrite table part_table
partition(a,b)
SELECT
xxxx
FROM unpart_table
where xxxxx
DISTRIBUTE BY rand();
3、通過處理hive分區小文件數,使得map操作減少從而使得task任務大幅度減少,spark執行過程中不再發生溢出問題。
後記
在排查過程中還發現,之前有使用
set hive.enforce.bucketing = true;
強制分桶會導致分區文件被細化爲更小的文件,使得各種合併配置無效。