经典的《Hadoop权威指南》中有这样的一幅图:
清晰的反映了Hadoop中MR的执行过程,map端对文件切割输入,reduce端对数据归并输出,shuffle作为MR的心脏,对map端输入的数据进行缓存、分区、排序,保证reduce的数据是有序的。
ETL的执行效率来自两方面的制约:一是,SQL逻辑的复杂度;二是,资源的大小及使用效率。提升ETL的执行效率需要我们写出精炼优质的SQL代码,也需要掌握调参充分高效的利用集群资源。
常见的ETL问题:
总结:数据量大,小文件多,数据倾斜
一,数据量大:建议核查SQL逻辑,限制分区,过滤冗余数据,拆解任务分批次执行。参数设置对大数据量进行分区裁剪、列裁剪、谓词下推
二,小文件多:小文件过多造成执行过程中的拉取文件的大量随机读,带来任务延迟。
三,数据倾斜:数据倾斜是最常见的问题之一,严重制约了ETL的执行效率,如下提供了常用的几种优化方案,仅供参考
1,可以舍弃热点数据,稀疏的key数据与密集的key数据分开计算,避免木桶效应,拖长任务执行时长。
2,mapjoin实现广播的小表链接大表,来提升链接的效率。
3,大表热点数据在key上拼接0~n的前缀/后缀,同时小表冗余扩大n倍数据,保证join到对应键值,然后去掉前缀/后缀。
4,a left join b 可以转换为:b left join a 加 union,基于维度对指标进行聚合函数封装。
5,谨慎使用笛卡尔积:需要过滤链接条件中的NULL值:NULL不参与关联或者NULL分配随机的key值。
6,多阶段聚合:通过过局部聚合,层层递进的聚合方式来完成全局聚合。
四,万能参数配置
代码语言:javascript复制set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.exec.parallel=true;
set mapred.max.split.size=64000000;
set mapred.min.split.size.per.node=64000000;
set mapred.min.split.size.per.rack=64000000;
set hive.exec.reducers.bytes.per.reducer=256000000;
set hive.exec.reducers.max=2000;
set hive.merge.mapredfiles=true;
set hive.merge.smallfiles.avgsize=128000000;
set hive.merge.size.per.task=128000000;