前面我们说过MapReduce的运算流程,整体架构方法,JobTracker与TaskTracker之间的通信协调关系等等。虽然知道我们只需要自己完成Map和Reduce就可以实现MapReduce的运算,但是还有很多人习惯使用SQL进行数据分析,MapReduce编程不是那么容易,因此就有了Hive的存在。
首先看看如何用MapReduce实现SQL数据分析。
先看一个简单的SQL语句:
SELECT pageid, age, count(1) FROM pv_users GROUP BY pageid, age;
先来看看MapReduce实现SQL的原理。
具体数据输入和执行结果请看下图:
左边是要分析的表,右边是分析结果。实际上把左边表相同的行进行累计求和,就能得到右边的表,看起来和WordCount计算很类似,确实也是这样。
来看看这条SQL语句的MapReduce的计算过程:
如下图:
在数据仓库中SQL是最常用的分析工具,既然一条SQL可以通过MapReduce程序实现,那么Hive也可以。
现在来看看一下Hive架构。
Hive能够直接处理输入的SQL语句,调用MapReduce计算框架完成数据分析操作。来看看架构图:
通过Hive的Client向Hive提交SQL命令。
如果是创建数据表的DDL语句。Hive就会通过执行引擎Driver将数据表的信息记录在Metastore元数据组件中,这个组件通常用一个关系数据库实现,记录表名、字段名、字段类型、关联HDFS文件路径等这些数据库的Meta信息。
如果提交的是查询分析数据的DQL语句,Driver就会将该语句提交给自己的编译器Compiler进行语法分析、语法解析、语法优化等一系列操作,最后生成一个MapReduce执行计划,然后根据执行计划生成一个MapReduce的作业,提交给Hadoop MapReduce计算框架处理。
对于一个较简单的SQL命令,比如:
SELECT * FROM status_updates WHERE status LIKE ‘michael jackson’;
对应的Hive执行计划如下图:
Hive内部预置了很多函数,Hive的执行计划就是根据SQL语句生成这些函数的DAG(有向无环图),然后封装进MapReduce的map和reduce函数中。这个例子中,map函数调用了三个Hive内置函数:TableScanOperator、FilterOperator、FileOutputOperator,就完成了map计算,而且无需reduce函数。
除了上面这些简单的聚合过滤操作,Hive还能执行连接(join on)操作。
SELECT pageid , age,count(1) from pv_users group by pageid,age;
这是文章开头的SQL语句,pv_users表的数据在实际中是无法直接得到的,因为pageid数据来自用户访问日志,每个用户进行一次页面浏览,就会生成一条访问记录,保存在page_view表中。而age年龄信息则记录在用户表user中。pv_user表是和另一张表关联的,我们select的数据也来自不同的表,那么就需要join操作了,先看我所说的两张表:
假设是靠userid关联的,然后来重新表达一下新的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的时间复杂度O(n²),对来自两张表的记录进行连接操作。
随着大数据SQL的应用市场多样化之后更多的大数据SQL引擎也很火。
Cloudera开发了Impala,这是一种运行在HDFS上的MPP架构的SQL引擎。和MapReduce启动Map和Reduce两种执行过程,将计算分成两个阶段进行计算不同,Impala在所有DataNode服务器上部署相同的Impalad进程,多个Impalad进程相互协作,共同完成SQL计算,在一些统计场景中,Impala可以做到毫秒级的计算速度。
后来SparkSql出现了,引擎是基于Spark的,由于速度很快,快于Hive,所以后来Hive也兼容了Spark,可以在Spark上计算Hive的执行计划。总的来说这么多集群,做到技术嫁接,还是很有创新性的。