Hive on tez中map任务数的计算

举报
lihz 发表于 2021/09/30 11:05:50 2021/09/30
【摘要】 Hive on tez任务计算map任务是在AM中计算,而不是在hiveserver中计算,有别于hive on mr任务。hive on tez中计算map任务个数主要分为两个步骤:一是计算splits个数;二是将splits分组,分组数即为map数量1.​ 先通过HiveInputFormat.getSplits 初步计算split的个数,实际上是调用FileInputFormat.ge...

Hive on tez任务计算map任务是在AM中计算,而不是在hiveserver中计算,有别于hive on mr任务。

hive on tez中计算map任务个数主要分为两个步骤:一是计算splits个数;二是将splits分组,分组数即为map数量

1.​ 先通过HiveInputFormat.getSplits 初步计算split的个数,实际上是调用FileInputFormat.getSplits计算split个数

计算split的个数需要确定分片大小splitSize,分片大小涉及的参数:数据块大小blockSize,默认值128M;最小分片大小minSize

其中minSize = min(blockSize/2,tez.grouping.min-size)

tez.grouping.min-size默认值为50M, 因此minSize默认为50M

splitSize = max(minSize, min(goalSize, blockSize), 其中goalSize是所有文件大小总和。

备注:goalSize = totalSize / (numSplits == 0 ? 1 : numSplits); 在笔者的环境中计算的numSplits 0,所以goalSize是所有文件大小总和。

在默认参数情况下, 即blockSize=128M, minSize=50M

当文件总大小 goalSize<50M,splitSize=minSize=50M

当文件总大小 50M<goalSize<128M, splitSize=goalSize

当文件总大小 goalSize>128M,splitSize=128M

计算split个数的流程

遍历输入目录的每个文件:

如果文件大小fileSize>1.1*splitSize, 就划分一个split,大小为splitSize,一直循环直至最后剩余的大小<1.1*splitSize,作为一个split

如果文件大小fileSize<1.1*splitSize, 就直接作为一个split,大小就是文件大小。

--在默认情况下可以近似于一个block就是一个split,如果文件大小小于blockSize,也是一个block

例如: select count(*) from text;

其中text的文件如下:存在3个文件其中一个大小约为45M, 一个约为182M,一个约为320M

根据以上计算,000000_0文件就分为1个split,000000_1文件分为2个split, 000000_2分为3个split,总共6个splits

查看日志打印,在HiveInputFormat.split阶段确实分成6个splits

2.​ 计算split个数之后,再调用TezSplitGrouper.getGroupedSplits计算map个数。

getGroupedSplits的作用是将步骤1分好的splits进行分组,每组就是一个map,分成多少组就有多少个map。

其分组过程中重要的参数:tez.grouping.split-count(默认值0),tez.grouping.max-size(默认值1G), tez.grouping.min-size(默认值50M)

下文中将这三个参数简称为split-count,max-size,min-size,由该3个参数计算期望的分组数

如果tez.grouping.split-count>0 表示期望分组的个数为split-count, 计算分组就不受max-size和min-size的影响

如果tez.grouping.split-count<=0 期望分组默认为1(由计算得来,集群获取不到yarn资源默认为1),这时计算分组就受 max-size和min-size的影响

期望分组数desiredNumSplits计算规则如下:

如果split-count>0;desiredNumSplits=split-count;

如果split-count<=0;默认desiredNumSplits=1,每组的读入的数据大小lengthPerGroup为总文件大小totalLength

如果lengthPerGroup>max-size; 则重新调整desiredNumSplits=totalLength/max-size +1

如果lengthPerGroup<min-size;则重新调整desiredNumSplits=totalLength/min-size +1

 

得到期待的分组后,计算实际分组数

1)当desiredNumSplits >= split个数,就不用分组,按照原来的split个数,有多少split,map任务是就有多少

上述例子 select count(*) from text; 执行前set tez.grouping.split-count=10,那么输出是按照原split个数

2desiredNumSplits < split个数, 实际分组计算如下

计算每个分组的处理的数据大小 lengthPerGroup =totalLength/desiredNumSplits;即总大小除以期待分组数

遍历所有splits,累加文件大小记为groupLength,

如果groupLength+下个split大小>lengthPerGroup ;当前已遍历的split就作为一个分组。直至所有split都遍历完毕,计算出所有分组。

上述例子 set tez.grouping.split-count=3; select count(*) from text; 最终计算分组个数为4

 

 

 

 

 

 

 

 

 

 

 

 

 

 

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。