Hive处理25亿数据之性能优化

项目背景

有个关于分布式链路追踪呢项目,公司微服务460个左右,zipkin 日增数据约1.6T,约25亿左右数据。

通过清洗,输出不同5大维度维度,8种粒度的依赖视图,以及相关的报表汇总统计。过程遇到了不少坑。在一些数据量大的场景下,很容易把一些潜在的问题就容易暴露出来,现总结如下:

1. JSON的解析

通常,我们通过一下两种函数进行解析get_json_object()或json_tuple()。假如要从一张ods表中将json字符串解析成对相应的字符串,假设有10个字段,那么get_json_object()方法相当于一条记录使用10次函数,而json_tuple()方法只是使用了一次,进行了批量解析,这种方式明显更高(脑补下JVM的知识点)。

另外,确认是否所有的字段都有必要解析?解析的字段越多,意味着序列化和反序列化,以及解析的工作量,这都是很消耗CPU。而CPU核数越多,意味着并行处理的task的能力越强。

通过这种优化思路,生产环境解析json这张表的时间从4.5小时缩减到0.5小时。

2.分析函数

结论:5000千万以下或轻量级汇总表上随便用。其它数据量级慎用。

我应该算分析函数的重度用户,可以通过精简的代码解决复杂的报表问题,而且性能由于各种表Join。主要源于早期开发oracle报表时用上瘾。Hive也提供了跟oracle类似的分析函数。(mysql8支持分析函数,之前的版本不支持)。

为什么说慎用呢?

分析函数一般是作用每一行的,或者对维度分组并进行处理,如

row_number() over(partition by xxx  order by xxx)   ===>常用于去重

first_value(xxx) over (partition by xxx order by xxx) ===> 返回首个值(我有用它来采样)

还有sum(xxx) over() 、avg(xxx) over() 等等之类的 。

一旦涉及到partition by 就涉及到reduce ,涉及到order by 就涉及到排序,尤其是排序,经常涉及到全量排序,这个特别耗性能,能避免排序尽量。

由于在HQL语句使用了大量分析函数,导致有些报表跑了三、四个小时还没跑出来。解决方案:通过传统的group by 处理。

3.大表和大表join 

比如单表25亿,设计到父子关系,需要join自己,尽管通过where语句缩小了数据量,还是奖金有10亿之间的join,并在此之上进行汇总计算。我这里提供3中解决方案。

(1)临时表 :创建临时表,将join结果方法临时表,再从临时表取数据计算,若失败重试(默认3次)再从临时表取数据,跑完数据,删除临时表。

(2)动态分区:默认是按天分区,可以根据join的关键ID hash到不同分区中去(如10个)按分区join,再合并结果。

 (3)分桶:  跟动态分区有点像,根据cluster(xxId)

你可能感兴趣的:(Hive处理25亿数据之性能优化)