利用开窗函数+spark.sql.shuffle.partitions避免小文件合并

遇到一个常见sql使用场景

insert overwrite table xxx(date='${hiveconf:date}')

select 

    *

from table1

union all 

select

     *

from table2

 观察发现任务耗时慢,大概30多分钟,其中主要耗时花在合并小文件——每次执行完spark etl任务还会执行hive合并小文件合并,解决小文件过多的问题。

ALTER TABLE xxx PARTITION (date='${date}')  concatenate

合并小文件前查看分区下的小文件数量,大概有4000-5000多个,看来是小文件太多,执行hive合并小文件命令的时候耗时了;合并完成后小文件数量40-50个。

解决方案:开窗函数+设置spark.sql.shuffle.partitions参数

1. 优化后的sql

insert overwrite table xxx(date='${hiveconf:date}')

select 

……

,max(id) over(partition by id) as id

from

(

select 

    *

from table1

union all 

select

     *

from table2

)

2. 启动时设置参数

--conf spark.sql.shuffle.partitions,其默认大小为200。

--conf spark.sql.shuffle.partitions=50

3. 外层对表的主键进行分组开窗,其实就是最后一步进行shuffle。由于是主键,所以不存在数据倾斜问题,性能影响不大,数据重新均匀打散,再spark.sql.shuffle.partitions参数生成指定分区数量。

优化后,开窗会带来一定的性能消耗,但避免了再直一个任务做小文件合并,耗时从30多分钟缩小到五六分钟,实际中遇到类似问题,可以尝试此方法。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值