环境
cdh6.3.2
hive2.1
场景
最近发现有一个简单的spark on hive on yarn的 hql逻辑的map阶段需要跑很久很久,
27MB,有shuffle 10MB的情况下, 居然要执行七个多小时
原因
根据yarn界面定位到这张读的很慢的表, 并且去9870页面观察这张表的分区和数据分布情况还有这张表的生成sql情况, 发现这张表其实是一张宽表,只是比较小,但是由于是宽表并且hql逻辑中有很多unionall联合小表的操作, 导致这个表在触发hive的orc小文件合并的时候, 最后生成的这个27M的文件块内,有茫茫多的stripe信息 ,搜索文件内的stripe信息发现几十行数据就会有一个stripe
本质原因:
一般单个文件根据spark /yarn的默认分区并行度,比如我们集群是1099个分区,那么reduce后这个orc文件内应该是1099个stripe信息
单个文件存在大量stripe信息,导致每个文件读取很慢
处理方案
1.调整全局参数
hive.merge.file.stripe.level=false
2.并对历史分区进行自己覆写自己
这个很重要
inserverwrite tb (分区)
select * from tb自己
where 分区
作用:
解决当前orc文件下小文件合并导致文件读取速度异常,并设置全局生效
后果:
加工节点的orc spark merge file阶段速度会有下降,但是大多数情况下生成的orc文件的读取速度会有明显提升
即使读全表也会很快
PS
新增了orc合并参数以后,就不会根据orc文件进行合并,而是基于file大小进行合并,这一点需要注意,
一般会遵循1W行一条
目前表的stripe看起来是10-100条一个