先讲方法论
性能优化分为3个层面的优化思路
- 数仓层面,有导出模式、聚集模式
- 存储层面,有分表分区设计、文件压缩、索引设计
- 计算层面,就是MR、spark、hive等等的优化,往往技术面会涉及到这点
实践上来说,性能优化对象有2个:单个任务和任务链。单个任务,就是从方法论上从3个层面择优实现;任务链,就涉及到优化目标以及相应的策略。
- 目标是更快完成:分析任务链上所有任务的耗时,针对最大收益的任务进行优化
- 目标是更早完成:分析任务链在最晚开始的任务,并尝试提前或缩短
再讲落地
做大数据和Hadoop生态圈相关的情况下,需要了解MR的原理。
数仓的主力开发语言是SQL,并且现在的技术趋势是流批一体。所以为什么需要了解MR的原理呢,Hadoop生态圈中sql的作用是什么,以hive为例
hive是一个SQL执行引擎,它负责将Hadoop集群中的文件映射为矩阵表,然后保存元数据,将查询矩阵表的sql翻译为MR任务。所以,我们需要了解的是
-
sql翻译后会得到怎样的MR任务;
-
如果这些MR任务存在性能问题,如何定位到我们的sql中
学会看执行计划
如果所有的性能问题都直接定位到MR的调优,那么用SQL作为数仓主要开发语言的意义就丢失了
MR算法在Hadoop中,完整的步骤是,input 、map、shuffle、reduce、output,再往细了讲,就需要针对一条sql进行拆解,会涉及到哪些MR步骤
技术层面的优化手段分3个:
- Map优化:map任务数和数据量需要达到一个平衡点才能达到性能最优,所以优化的方向就是增加或者减少map的个数;map个数,和文件数(展开来说,可以在hive里设置输入合并和输出合并)、文件块大小的配置、map个数的自定义配置相关,可通过调整这些来控制map个数,达到优化目标
- Join优化:join操作是一个reduce操作,所以有部分优化是可以和reduce优化合并来说的,不过hive层面和sql层面有针对性的性能优化,比如mapjoin(是大表join小表的情况,25M),长尾空值和热值的情况下,需要通过改写sql来优化
- reduce优化:个数,可通过任务配置来自定义;也和单个reducer任务可处理的数据量(一般配置是1g)、还有单任务最大reducer个数的配置有关
- shuffle优化:我们知道shuffle分为collect、sortAndSpill、merge、copy、merge,最受诟病的sort可去掉
数据倾斜
什么是数据倾斜:某个mapper/reducer的数据量远大于其他,导致任务串行,甚至OOM。
实际上,性能问题有2种:阻断和可接受,如果数据量不大、集群资源足够,所有的任务都会按预期的产出,往往也很难觉察到数据倾斜问题。
所谓的阻断性质的数据倾斜问题,会导致任务无法产出或者偶发的出现失败现象。这个时候,就真正触及到MR原理的本质。要解决数据倾斜问题,首先要确定的是,mapper or reducer,能不能通过增加个数来解决,如果不能就需要根据数据特征进行额外处理