在工做中須要同步pg數據庫下的某張表到hive,使用的工具是開源的sqoop,業務表的數據表包含最近一年的數據,數據表的行數爲366,830,898,數據表的字段個數爲71個,數據表在pg中的空間大小爲110G;pg中表沒有惟一主鍵,同一個id的數據可能會出現屢次,且都是業務容許的正常場景。node
hive -e " insert overwrite table target_table partition(dt = '$curr_date') select a.* from a where a.dt = '$curr_date - 1' and a.id not in (select id from b where b.dt = '$curr_date') union all select * from b where b.dt = '$curr_date' "
這種方式理論上是能夠實現的,實際執行中發現任務最後會生成不少的小文件。
1. 嘗試手動設定reduce的數量 set mapred.reduce.tasks = 64,實際執行中並未起做用。
2. 嘗試在map階段先進行文件合併 ,例以下面的設置,map的數量確實減小了,可是reducer數量仍是同樣沒變。同理設定reduce完成之後的文件合併,同樣不起做用。算法
set mapred.min.split.size=100000000; set mapred.max.split.size=100000000; set mapred.min.split.size.per.node=50000000; set mapred.min.split.size.per.rack=50000000; set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
hive -e " set mapred.reduce.tasks = 64; insert overwrite table traget_table partition (dt = '$curr_date') select a.* from a where a.dt = '$curr_date - 1' and not exists (select 1 from b where b.dt = '$curr_date' and a.id = b.id) union all select * from b where b.dt = '$curr_date' "
更新sql以下,加上 DISTRIBUTE by rand (),distribute by是控制在map端如何拆分數據給reduce端的,hive會根據distribute by後面列,對應reduce的個數進行分發,默認是採用hash算法。rand()方法會生成一個[0,1]之間的隨機數,經過隨機數進行數據的劃分,由於每次都隨機的,因此每一個reducer上的數據會很均勻。以下的這種設置,reducer會有64個,且每一個reducer上的數據量幾乎同樣。sql
hive -e " set mapred.reduce.tasks = 64; insert overwrite table traget_table partition (dt = '$curr_date') select a.* from a where a.dt = '$curr_date - 1' and not exists (select 1 from b where b.dt = '$curr_date' and a.id = b.id) union all select * from b where b.dt = '$curr_date' DISTRIBUTE by rand (); "
效果以下:數據庫