MapReduce简化了大数据编程的难度,使得大数据计算不再是高不可攀的技术圣殿,普通工程师也能使用MapReduce开发大数据程序。但是对于经常需要进行大数据计算的人,比如从事研究商业智能(BI)的数据分析师来说,他们通常使用SQL进行大数据分析和统计,MapReduce编程还是有一定的门槛。而且如果每次统计和分析都开发相应的MapReduce程序,成本也确实太高了。
有没有更简单的办法,可以直接将SQL运行在大数据平台?
先看如何用MapReduce实现SQL数据分析。
常见的一条SQL分析语句,MapReduce如何编程实现?
SELECT pageid, age, count(1) FROM pv_users GROUP BY pageid, age;
统计分析语句,统计不同年龄用户访问不同网页的兴趣偏好,具体数据输入和执行结果:
把左表相同的行求和,即得右表,类似WordCount计算。该SQL的MapReduce的计算过程,按MapReduce编程模型
V就是左表中每行的数据,如<1, 25>
比如<<1, 25>, 1>
map函数的输出经shuffle后,相同的K及其对应的V被放在一起组成一个<K, V集合>,作为输入交给reduce函数处理。比如<<2, 25>, 1>被map函数输出两次,那么到了reduce这里,就变成输入<<2, 25>, <1, 1>>,这里的K是<2, 25>,V集合是<1, 1>。
在reduce函数内部,V集合里所有的数字被相加,然后输出。所以reduce的输出就是<<2, 25>, 2>
如此,一条SQL就被MapReduce计算好了。
在数据仓库中,SQL是最常用的分析工具,既然一条SQL可以通过MapReduce程序实现,那有无工具能自动将SQL生成MapReduce代码?这样数据分析师只要输入SQL,即可自动生成MapReduce可执行的代码,然后提交Hadoop执行。这就是Hadoop大数据仓库Hive。
Hive能直接处理我们输入的SQL(Hive SQL语法和数据库标准SQL略不同),调用MapReduce计算框架完成数据分析操作。
通过Hive Client(Hive的命令行工具,JDBC等)向Hive提交SQL命令:
对一个简单的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函数。
除了简单的聚合(group by)、过滤(where),Hive还能执行连接(join on)操作。
pv_users表的数据在实际中无法直接得到,因为pageid数据来自用户访问日志,每个用户进行一次页面浏览,就会生成一条访问记录,保存在page_view表中。而age年龄信息则记录在用户表user。
这两张表都有一个相同的字段userid,据该字段可连接两张表,生成前面例子的pv_users表:
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循环,对来自两张表的记录进行连接操作。
开发无需经常编写MapReduce程序,因为网站最主要的大数据处理就是SQL分析,因此Hive在大数据应用很重要。
随Hive普及,我们对在Hadoop上执行SQL的需求越强,对大数据SQL的应用场景也多样化起来,于是又开发了各种大数据SQL引擎。
本文系作者在时代Java发表,未经许可,不得转载。
如有侵权,请联系nowjava@qq.com删除。