Hive
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的原理
SELECTpageid,age,count(1)FROMpv_usersGROUPBYpageid,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*fromuser;
Hive如何实现join操作
除了上面这些简单的聚合(groupby)、过滤(where)操作,Hive还能执行连接(joinon)操作。
比如现在来了一个需求。
有2张表,一张是page_view页面浏览记录表,一张是user用户表
如果我想收集到每个页面浏览用户的age信息,该如何获取。
很明显,这两张表都有一个相同的字段userid,根据这个字段可以将两张表连接起来,生成我们最终想要的结果表pv_users,SQL命令是
SELECTpv.pageid,u.ageFROMpage_viewpvJOINuseruON(pv.userid=u.userid);
同样,这个SQL命令也可以转化为MapReduce计算,连接的过程如下图所示。
从图上看,join的MapReduce计算过程和前面的groupby稍有不同,因为join涉及两张表,来自两个文件(夹),所以需要在map输出的时候进行标记,比如来自第一张表的输出Value就记录为1,X,这里的1表示数据来自第一张表。这样经过shuffle以后,相同的Key被输入到同一个reduce函数,就可以根据表的标记对Value数据求笛卡尔积,用第一张表的每条记录和第二张表的每条记录连接,输出就是join的结果。
所以我们如果打开Hive的源代码,看join相关的代码,会看到一个两层for循环,对来自两张表的记录进行连接操作。
Hive命令说明
在Hive提供的所有连接方式中,命令行界面是最常见的一种。用户可以使用Hive的命令行对Hive中的数据库,数据表和数据进行各种的操作。
Hive函数使用
Hive内部支持大量的函数,可以通过SHOWFUNCTIONS查看Hive的内置函数。灵活地运用Hive提供的函数能够极大地节省数据分析成本。Hive函数主要包含数学函数,集合函数,类型转换函数,日期函数,条件函数,字符串函数,聚合函数和表生成函数等。
调优向来都非常重要,无论是面试复习,还是实际工作,都少不了和它打交道。
例如,从建表设计层面,我们可以考虑到利用分区表/分桶表优化,选择选择合适的压缩格式。
从HQL语法和运行参数层面,我们可以采用查看Hive执行计划,列剪裁,谓词下推,分区剪裁,合并小文件等方式...
从Hive架构层面,我们可以采用启用本地抓取,本地执行优化,JVM重用,并行执行等方式...
尾声
在实践中,工程师其实并不需要经常编写MapReduce程序,因为网站最主要的大数据处理就是SQL分析,也因此Hive在大数据应用中的作用非常重要。
后面随着Hive的普及,我们对于在Hadoop上执行SQL的需求越加强烈,对大数据SQL的应用场景也多样化起来,于是又开发了各种大数据SQL引擎。
例如Cloudera也开发了Impala,这是一种运行在HDFS上的MPP架构的SQL引擎。和MapReduce启动Map和Reduce两种执行进程,将计算过程分成两个阶段进行计算不同,Impala在所有DataNode服务器上部署相同的Impalad进程,多个Impalad进程相互协作,共同完成SQL计算。在一些统计场景中,Impala可以做到毫秒级的计算速度。
还有后面我会为大家介绍的SparkSQL,此外,大家还希望在NoSQL的数据库上执行SQL,毕竟SQL发展了几十年,积累了庞大的用户群体,很多人习惯了用SQL解决问题。于是Saleforce推出了Phoenix,一个执行在HBase上的SQL引擎....
Hive本身的技术架构其实并没有什么创新,数据库相关的技术和架构已经非常成熟,只要将这些技术架构应用到MapReduce上就得到了Hadoop大数据仓库Hive。但是想到将两种技术嫁接到一起,却是极具创新性的,通过嫁接产生出的Hive可以极大降低大数据的应用门槛,也使Hadoop大数据技术得到大规模普及。
文章转载来源于数据治理体系