一 Sql转换mr过程
二 基本sql原则
三 map
四 join
五 reduce
一 Sql转换mr过程
这里借用一下美团技术文章:https://tech.meituan.com/2014/02/12/hive-sql-to-mapreduce.html
二 基本sql原则
•
1:
尽量早的过滤数据(谓词下推
hive.optimize.ppd
、避免空值),同时列裁剪
hive.optimize.cp
。
•
https://blog.csdn.net/ccstargazing/article/details/104461226
(
ORC
存储文件探究)
•
2:
尽量原子操作,避免一个
sql
包含复杂的逻辑。(偏好价格层级案例)
•
3:join
操作,小表放在左边。
•
4:union all
的部分可以一次读取多次插入,或者设置参数
hive.exec.parallel.thread.number
=n
;
hive.exec.parallel=true
•
5:group by
和
count(distinct)
的使用场景。
Mapreduce
个数,
map
处理方式不同,
•
6:
尽量减少
map
、
join
。
•
7:join
之前对关联键进行
group by
检测,避免数据膨胀。
•
8:group by
有热点值
.
hive.groupby.mapaggr.checkinterval
默认值
100000
,超过就新起
job
。
三 map
map任务数量调整:
•
1
:
mapred.map.tasks
(2)
设定
mapper
的期望数,但不一定会生效。
•
2:default_mapper_num =
total_input_size
/
dfs.block.size
•
3:split_size = MAX(
mapred.min.split.size
(1B),MIN(
mapred.max.split.size
(64MB)
,
dfs.block.size
))
•
4:split_num =
total_input.size
/
split_size
.
•
Mapper_num
=MIN(
split_num,MAX
(
defult_mapper_num,mapred.map.tasks
))
•
总结:减少
mapper
数量,调高
mapred.min.split.size
;
•
增加
mapper
数量,降低
mapred.min.split.size
,调高
mapred.map.tasks
.
map倾斜:
•
问题:
•
一:上游表大小不均匀,小文件多,导致当前的表的
map
端读取数据分布不均匀。
•
二:
map
端做
聚合
时,某些
map
读取到某个值特别多,主要指
count distinct
。
•
方案:
•
一:合并上游小文件;调整参数合并小文件。
•
二:
distribute by rand()
让数据随机分布。
Distribute by
控制在
map
端如何拆分数据给
redce
端。
Hive
会根据
distribute by
后面的列,根据
reduce
的个数进行数据分发,默认采用
hash
算法。
•
避免
map
数据倾斜的参数
•
hive.map.aggr = true
;
(shuffle
之前预聚合,默认
true)
•
hive.groupby.skewindata
= true
;
(
控制生成两个
MR Job
,默认
false)
四 join
•
问题:
•
1:join
的某路输入比较小(别的输入较大),引起长尾。
•
2:join
的每路输入都很大,长尾是空值导致的。
•
3:join
的每路输入都很大,长尾是热点值导致的。
•
解决方案:
•
1:
采用
map
join
。
set
hive.auto.convert.join
=true;
hive.mapjoin.smalltable.filesize
默认
25m
。
•
2:
空值处理成随机值,避免聚集。
•
3:
热点值和非热点值分别进行处理(
map join
),再
union all
。
或者set hive.skewjoin.key=100000;--set hive.optimize.skewjoin=false;(默认值)
五 reduce
reduce任务数量调整:
•
1:hive.exec.reducers.bytes.per.reducer
设定每个
reducer
能够处理的最大数据量,默认
259M
。
•
2:hive.exec.reducers.max
设定每个
job
的最大
reducer
的数量,默认
1009
•
reducer_num
=MIN(
total_input_size
/
hive.exec.reducers.bytes.per.reducer
,
hive.exec.reducers.max
)
•
总结:调大
reducer
数量,调小
hive.exec.reducers.bytes.per.reducer
,调大
hive.exec.reducers.max
。
•
注意事项:
reducer
数量与输出文件数量相关。
Reducer
数太多,产生大量小文件,对
HDFS
造成压力,
reducer
太少,每个
reducer
要处理很多数据,拖慢运行时间或者造成
OOM
。
reduce倾斜:
问题:
•1:对同一个表按照不同维度进行count distinct,造成map端数据膨胀,从而使得下游join和reduce
出现链路上的长尾。
•2:map端直接做聚合时出现key值分布不均匀,造成reduce端长尾。
•3:动态分区过多时造成小文件过多,从而引起reduce端长尾。
解决方案:
•
1:
嵌套编写,先
group by
再
count(*)
;也可以采用
sum(case when)
•
2:
对热点
key
进行单独处理,再
union all
。(使用
map
join
的例子)
•
3:
把不同条件的数据放入到不同的分区,避免通过多次“
Insert Overwrite”
写人表中。
补充:
•
关联
优化器
set
hive.optimize.correlation=
true
https://cwiki.apache.org/confluence/display/Hive/Correlation+Optimizer
对于多次取一份数据进行不同的计算很有效。
•
JVM
重用
set
mapred.job.reuse.jvm.num.tasks
= 5
例如将这个参数设成5,那么就代表同一个MR job中顺序执行的5个task可以重复使用一个JVM,减少启动和关闭的开销。但它对不同 MR job中的task无效。
如果在工作中或者学习过程中,遇到sql跑的比较慢,可以联系我,[email protected],大家一起解决。