1前言
卷友们,大家好 ~ 我是梦想家 Alex 。自上一篇原创文章 HDFS,MapReduce,Yarn 的架构思想和设计原理发出之后,后台就不断有读者催更,那本篇内容,我们继续,来为大家介绍 Hive 架构思想和设计原理。
2Hive
我们在上一节讲到,MapReduce 虽然只有 map 和 reduce 这两个函数,但几乎可以满足任何大数据分析和机器学习的场景。不过,复杂的计算可能需要使用多个 job 才能完成,这些 job 之间还需要根据其先后依赖关系进行作业的编排,开发比较复杂。
在 Hadoop 出现之前,大部分的数据分析人员基本都用 SQL 语句分析数据库中的数据,如果让这些数据分析人员重新学习一下 Hadoop 支持的开发语言,将会耗费巨大的人力成本和学习成本。
所以,就有聪明的小伙伴想到,如果能根据 SQL 自动生成 MapReduce,就可以极大降低大数据技术在数据分析领域的应用门槛。
基于这样的一个需求场景,Hive 横空出世。
Hive的架构
首先让我们来看下 Hive 的架构 。
- Hive可以通过CLI,JDBC和 ODBC 等客户端进行访问。除此之外,Hive还支持 WUI 访问
- Hive内部执行流程:解析器(解析SQL语句)、编译器(把SQL语句编译成MapReduce程序)、优化器(优化MapReduce程序)、执行器(将MapReduce程序运行的结果提交到HDFS)
- Hive的元数据保存在数据库中,如保存在MySQL,SQLServer,PostgreSQL,Oracle及Derby等数据库中。Hive中的元数据信息包含表名,列名,分区及其属性,表的属性(包括是否为外部表),表数据所在目录等。
- Hive将大部分 HiveSQL语句转化为 MapReduce 作业提交到 Hadoop上执行;少数 HiveSQL 语句不会转化为MapReduce作业,直接从DataNode上获取数据后按照顺序输出。
知晓了架构,我们接下来通过一条常见的 SQL 语句,来看看 Hive 是如何将其转换成 MapReduce 来计算的。
MapReduce 实现 SQL 的原理
SELECT pageid,
age,
count(1)
FROM pv_users
GROUP BY pageid, age;
就像所展示的一样,这是一条很常见的 SQL 统计分析语句,用于统计不同年龄的用户访问不同网页的兴趣偏好,具体数据输入和执行的结果示例如图所示:
看这个示例我们就会发现,这个计算场景和 WordCount 很像。事实上也确实如此,我们可以用 MapReduce 完成这条 SQL 的处理。
这样一条很有实用价值的 SQL 就被很简单的 MapReduce 计算过程处理好了。
map 函数输出的 key 是表的行记录,value 是 1,reduce 函数对相同的行进行记录,也就是针对具有相同 key 的 value 集合进行求和计算,最终得到 SQL 的输出结果。
Hive要做的就是将SQL翻译成MapReduce程序代码。实际上,Hive内置了很多Operator,每个Operator完成一个特定的计算过程,Hive将这些Operator构造成一个有向无环图DAG,然后根据这些Operator之间是否存在shuffle将其封装到map或者reduce函数中,之后就可以提交给MapReduce执行了。
Operator 组成的 DAG 如下图 所示,这是一个包含 where 查询条件的 SQL,where 查询条件对应一个 FilterOperator。
值得注意的是,有些 HiveQL 语句不会被 Hive 转化成 MapReduce 作业,Hive 只会从 DataNode 将数据获取到了之后,按照顺序依次输出。
select * from user;
Hive 如何实现 join 操作
除了上面这些简单的聚合(group by)、过滤(where)操作,Hive 还能执行连接(join on)操作。
比如现在来了一个需求。
有 2 张表,一张 是 page_view 页面浏览记录表,一张是 user 用户表
如果我想收集到每个页面浏览用户的age信息,该如何获取。
很明显,这两张表都有一个相同的字段 userid,根据这个字段可以将两张表连接起来,生成我们最终想要的结果表 pv_users ,SQL 命令是
SELECT pv.pageid, u.age
FROM page_view pv
JOIN user u
ON (pv.userid = u.userid);
同样,这个 SQL 命令也可以转化为 MapReduce 计算,连接的过程如下图所示。
从图上看,join 的 MapReduce 计算过程和前面的 group by 稍有不同,因为 join 涉及两张表,来自两个文件(夹),所以需要在 map 输出的时候进行标记,比如来自第一张表的输出 Value 就记录为 <1, X>,这里的 1 表示数据来自第一张表。这样经过 shuffle 以后,相同的 Key 被输入到同一个 reduce 函数,就可以根据表的标记对 Value 数据求笛卡尔积,用第一张表的每条记录和第二张表的每条记录连接,输出就是 join 的结果。
所以我们如果打开 Hive 的源代码,看 join 相关的代码,会看到一个两层 for 循环,对来自两张表的记录进行连接操作。
Hive命令说明
在 Hive 提供的所有连接方式中,命令行界面是最常见的一种。用户可以使用 Hive 的命令行对 Hive 中的数据库,数据表和数据进行各种的操作。
关于 Hive 命令使用的小技巧,可以看之前写的文章
标签:架构,函数,MapReduce,Hive,SQL,原理,数据 From: https://blog.51cto.com/u_15105906/5901843