背景
定义了一个udf,用于信息解密,请求的是公司内部解密服务,解密服务部署了两台机器,随机请求。调用udf时,传入密文,输出明文。数仓每天有在用,且批量调用,没有性能问题。
最近新上线一个数据需求,发现卡在了解密udf,要30-40分钟。
原因
1.看解密服务完全没有压力,跑批的时候cpu使用率可以达到4000-5000%,现在只有100%左右。
2.看yarn资源分配也没有问题,尝试参数调优有点效果,但非常有限,解密服务的cpu还是上不去。
3.也怀疑过原始数据和udf可能存在问题,比如传了一些异常的密文导致udf异常处理失败或者重试导致耗时长。查看原始数据是否异常,udf添加日志打印,也没有问题。
4.如果跳过解密udf,任务几分钟就跑完,可以确定是调用udf导致。
原表是个分区表,数据量1578671,udf实例调用次数674326。
看表分区所读文件分布如下,总共4个文件,每个文件在150-300M左右。
[[email protected] ~]$ hdfs dfs -ls /user/hive/warehouse/xy_snap.db/sms_db_t_sms_sended/xy_date=20191205
Found 4 items
-rwxrwxrwt 3 hdfs hive 296733124 2019-12-09 01:41 /user/hive/warehouse/xy_snap.db/sms_db_t_sms_sended/xy_date=20191205/part-00000-4d8da335-585c-4b1a-97ad-293d8cd1e9f6-c000
-rwxrwxrwt 3 hdfs hive 255201346 2019-12-09 01:40 /user/hive/warehouse/xy_snap.db/sms_db_t_sms_sended/xy_date=20191205/part-00001-4d8da335-585c-4b1a-97ad-293d8cd1e9f6-c000
-rwxrwxrwt 3 hdfs hive 249122911 2019-12-09 01:40 /user/hive/warehouse/xy_snap.db/sms_db_t_sms_sended/xy_date=20191205/part-00002-4d8da335-585c-4b1a-97ad-293d8cd1e9f6-c000
-rwxrwxrwt 3 hdfs hive 150442190 2019-12-09 01:40 /user/hive/warehouse/xy_snap.db/sms_db_t_sms_sended/xy_date=20191205/part-00003-4d8da335-585c-4b1a-97ad-293d8cd1e9f6-c000
由于小文件有各种问题,我们平时习惯做了小文件合并,所以一般文件比较大,排除了各种可能问题,最终怀疑是几个大文件导致,那就拆分文件试试看。
解决
尝试用pyspark对该表做大文件拆分,将4个大文件拆分成1000个小文件,然后再执行任务。
from pyspark import SQLContext
from pyspark import SparkContext
from pyspark.sql import SparkSessionsc.stop()
sc = SparkSession.builder.appName("pyspark3-demo2").getOrCreate().sparkContext
print('sparkContext create success')fileFormat = 'orc'
sqlContext = SQLContext(sc)
df = sqlContext.read.load(path='/user/hive/warehouse/xy_snap.db/sms_db_t_sms_sended/xy_date=20191205/', format=fileFormat)
df.rdd.getNumPartitions()df.repartition(1000).write.save(path='/user/hive/warehouse/xy_snap.db/sms_db_t_sms_sended_new/xy_date=20191205/', format=fileFormat, mode='overwrite')
sc.stop()
对比前后文件,4个变成1000个
验证sql
select
count(distinct crowd_mix_id) as num1,
count(distinct group_index) as num2
from
(
select
get_json_object(cast(unbase64(a.fstrparameter) as string),'$.BDDMP_mixId') as crowd_mix_id_enc
, xy_udf.userinfodecrypt(get_json_object(cast(unbase64(a.fstrparameter) as string),'$.BDDMP_mixId')) as crowd_mix_id --crowd_mix_id
, get_json_object(cast(unbase64(a.fstrparameter) as string),'$.BDDMP_group') as group_index_enc
, xy_udf.userinfodecrypt(get_json_object(cast(unbase64(a.fstrparameter) as string),'$.BDDMP_group')) as group_index -- crowd_mix 分组
from xy_snap.sms_db_t_sms_sended_new a
where a.xy_date='20191205'
and lower(fstroriginalorderid) like '%dmp%'
) a
;
对比
验证文件拆分前后任务耗时对比
资源不变的情况下,文件拆分后性能提升还是很明显的,每个小文件对应一个task,task数量增加,任务并发能力提升,从另外一个方面看,解密服务所有机器的cpu使用率提升也很明显。