spark 进行hms_大数据

1. 起因

日常大数据的处理,常见的数据输出就是最大最小值,求个和,求个平均数这种,常见的写法,写个hql,先分个组,再加一个max或sum就可以

SELECT id,name,
  max(score1),
  sum(score2),
  avg(score3)
  FROM table
  GROUP BY id,name

当然如果条件更复杂一些,比如加一个if判断,就是sql稍微长一些,但还是能写出来

本地测试,还OK,测试环境,勉强能行,感觉不错,无非就是怼资源的问题

但放到上产上,直接傻眼

snappy压缩,原始数据500G
280亿条数据
第一步Shuffle Write 800G
接下来的任务预估需要8个小时跑完

我可是用1.5T的内存,200个并发,内存经常溢出,超时,GC时间巨长

2.优化开始

sql有问题,首先肯定第一反应就是优化资源分配和使用

--conf spark.storage.memoryFraction=0.7

有很多任务心跳超时

--conf spark.executor.heartbeatInterval=240

任务序列化时间过长

--conf spark.locality.wait=60

发现GC时间过长,优化jvm参数

-XX:+UseG1GC

发现spark有任务合并,在特殊位置增加reparation,强制任务分隔

dataset.repartition(20000)

经过一系列优化发现有效果,但收效甚微,最后一步执行还是要以小时计算

仔细分析了一下sql,是不是spark底层对多次的max,min这种,在数据量大的时候需要多次遍历数据

3. 问题解决

最后的决定,用代码写,再试一次

Dataset<Row> ds = spark.sql(sql);
dsTag0200.javaRDD().mapPartitionsToPair(
数据转型
分组当key做成tuple2
此处我缓存了一些需要后面聚合的差值
).reduceByKey(
判断最大最小
sum的聚合操作使用差值直接聚合
一遍就可以直接输出最终结果
)

激动的心颤抖的手,任务执行,下班走人,生死有命富贵在天,执行结果,大宝明天见

当然最终结果1个半小时结束,效率还可以接受而且这样内存比较受控,可以更高的增加executor等通过合理资源去提高并行度

4 总结

对于hql相对复杂的一些操作,尤其是对原始数据,一定要考虑数据量的问题,数据量大到一定程度,不是怼资源可以过去的了,而且这样优化的空间也会变得很少