在工做中须要同步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 (); "
效果以下:数据库