sparksql運算調優紀事(一)——hive小文件處理

業務目的

全量離線運算統計,結果寫入oracle

依賴版本

spark 2.0.1
hive 1.1.0

問題

  1. 執行時task數量過多
  2. hive動態分區小文件過多
  3. 測試環境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,產生了大量小文件
hive小文件
如圖可以看到小文件數量達到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;

強制分桶會導致分區文件被細化爲更小的文件,使得各種合併配置無效。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章