时隔两年多,趁晴朗闲暇,把这篇博文补上。
前言
我们知道了MapReduce的执行过程(MapReduce简介),也了解了Hive的基本原理(Hive简介),也了解了Hive在执行时是被转换为一个个MR任务去执行,这时,我们一定会好奇,某一条SQL是如何转化为MR的,又是如何执行的呢?
下面将从Hive中两个最基本的语法进行解析:GROUP BY
& JOIN
。
1、 GROUP BY
解析
1.1 初识
我们首先创建一个表TEST
,如下:
name |
---|
Java |
Java |
Hive |
Java |
对于如下一条简单的 Hive SQL,分析其原理,
SELECT
name
,count(1) AS cnt
FROM TEST
GROUP BY name;
Map阶段
将分组字段作为Key,Value为该分组下的记录数量(我们知道Map部分的逻辑可以程序员自己实现,计算相同Key的记录数很简单)。
这样Map的结果如下:
Shuffle阶段
该阶段会根据key进行sort排序(一般是字典排序),然后分配给不同的reduce去执行下一步操作,结果如下:
Reduce阶段
根据Shuffle出的不同key,可知会分配给两个Reduce,而这里我们不需要对结果做出进一步操作,因而直接输出即可,如下:
最终结合到一起,整个流程如下:
看到这里,也许你会有些疑问,整个结果,在Map阶段就已经出现了,Shuffle和Reduce的作用是什么呢?
1.2 深入
让我们来想象这样一种场景,首先,表多加一个字段rank
,同时,这张表非常的庞大,庞大到我们需要两个Map任务来计算(需要指出的是,Map任务数一般等同于数据所占Block的数量,而Reduce的数量是和Shuffle之后的Key的数量有关,切不可认为Map和Reduce任务数量一一对应),这里我们截取该表中的部分数据进行分析。
name | rank |
---|---|
Java | 1 |
Java | 2 |
Java | 1 |
… | … |
Hive | 2 |
Java | 1 |
Hive | 2 |
… | … |
对于如下一条Hive SQL,分析其原理,
SELECT
name
,rank
,count(1) AS cnt
FROM TEST
GROUP BY name, rank;
Map阶段
由于数据量比较多,调用两个Map任务,因而Map前的split操作结果和Map结果如下:
map阶段的Key是group by字段的组合(这里是name和rank,如果SQL中存在distinct,则是group by字段外加distinct字段的组合)。
Shuffle阶段
该阶段会根据key进行sort排序(一般是字典排序),然后分配给不同的reduce去执行下一步操作,结果如下:
Reduce阶段
根据Shuffle出的不同key,可知会分配给三个Reduce,而针对第二个reduce任务,我们需要进一步的合并计算,因而整个流程如下:
注意:从上述过程中,我们可以发现:
- Map阶段接收的数据量和计算量基本是恒定的,不会产生数据倾斜;
- 而Shuffle阶段我们基本不能控制,也不存在数据倾斜;
- Reduce阶段会根据该key对应的数据量的不同,进行不同的计算量,上例中,第二个reduce需要一次合并计算,而13不需要计算,每个reduce的计算量不同,这便是数据倾斜,而最终的计算时间,取决于最慢的那个reduce。
--------------------------------------------------------- 华丽的分割线 --------------------------------------------------------------
2、 JOIN
解析
话不多说,先来两个表和一条SQL;
学生成绩表t_student
student | rank_id |
---|---|
Arvin | 1 |
Jin | 1 |
Bob | 2 |
成绩维表t_rank
rank_id | rank |
---|---|
1 | good |
2 | bad |
SELECT
t.student
,tt.rank
FROM t_student t
JOIN t_rank tt
on t.rank_id = tt.rank_id;
Map阶段
将关联字段作为Key,Value Table标记(如用1表示t_student,2表示t_rank)和其他显示字段(student)。
这样Map的结果如下:
Shuffle阶段
该阶段会根据key进行sort排序,然后分配给不同的reduce去执行下一步操作,结果如下:
Reduce阶段
根据Shuffle出的不同key,可知会分配给两个Reduce,每个reduce会分遍历数据,将table标记不同的记录两两组合,并输出结果,如下:
注意:同group by的注意。
总结
了解Hive如何转化为MR任务是及其重要的,不仅有助于我们了解MR甚至Hadoop,更有助于我们写出高质量的Hive SQL,防止数据倾斜,希望这篇博文对大家有所帮助 😃