|
一、前言:
非常感谢Hadoop专业解决方案群:313702010,兄弟们的大力支持,在此说一声辛苦了,经过两周的努力,已经有啦初步的成果,目前第13章 Hadoop的发展趋势小组已经翻译完成,在此对:hbase-深圳-18361、旅人AQUARION表示感谢。
二、意见征集:
本章节由《Hadoop专业解决方案群:313702010》翻译小组完成,为小组校验稿,已经通过小组内部校验通过,特此面向网络征集意见,如果对本章节内容有任何异议,请在评论中加以说明,说明时,请标明行号,也可以以修订的方式,发送给我。非常感谢。
三、原书说明
英文原书《Wrox.Professional.Hadoop.Solutions》第十三章,请参照英文原文。
四、翻译原稿
4.1 章节目录
页码-435
这个章节将介绍的内容:
了解当前以及新兴的MapReduce的DSLs
了解更高效,高扩展性的程序改进
回顾安全性方面的功能改进
了解最新的趋势
Hadoop在迅速的发展变化,似乎每个星期业界新闻上都能看到新的发行版以及基于hadoop的开源项目的发布,并且能够提供更加强劲的功能。如果您看到Apache的JIRA对于Hadoop的请求优化(部分在第10章中讨论的内容),您将发现hadoop的明天将会拥有更多的功能。
在过去的几年中,新的特定领域语言(DSLs)众所周知简化了hadoop的mapreduce编程,而且是hadoop中快速发展的领域,特别是在图形处理方面。实时的hadoop(作为第9章的讨论内容)在今天呈现一个不断增长的趋势,并且在未来会不断的发展。正如第10章和第12章的内容,安全性将不断的发展和变化。虽然本书涉及到了很多未来将会改变和发展的内容,而您应该去了解更多本章没有涉猎的领域。
本章开篇DSLs简化mapreduce编程为当前的发展趋势,这种方法是通过在特定的问题领域引入更高级别的概念以及使用一个简易的API缩短代码的开发周期,您将了解到在hadoop2.0版本执行时间的新的实现(优化),从而为mapreduce提供了更高的扩展性和可伸缩性。
页码-436
在本章中您还将了解到Tez-一个崭新健壮的hadoop和Oozie框架,且支持通用性和实时性,本章还突出探讨了即将实现的安全性更改。最后,您将了解到hadoop应用的新趋势。
在本书中已经被证实,hadoop可以用来解决很多不同的问题。本章重点集中在当下更多的组织选择使用hadoop,以及在未来这些组织如何来使用它。让我们开始讨论DSLs以及它们在hadoop编程中扮演的角色。
4.2 正文
DSL简化mapreduce编程
到目前为止,本书重点集中于mapreduce-允许在机器的集群中拆分任务执行的hadoop编程模型,mapreduce赋予开发人员能够充分利用hadoop的权限,甚至是自定义执行(见第四章)从而更好的利用hadoop。Mapreduce是一个底层的模型,提供的权限对用开发者来说是一个新的挑战。DSLs提供了一种简化hadoop编程的方法,尽管本书可以介绍每一个hadoop的DSL,但本节仅快速”品味”他们其中的一些,展示在hadoop的这个发展的领域中如何降低了用户的入门难度。本节重点介绍一些成熟的,已经被广泛应用的DSLs(例如HiveQL和PigLatin)以及一些新生和发展中的DSLs。
DSL是什么?
DSL是一种编程语言,设计用来提供特定领域问题的解决方案。模仿其他领域的术语和概念,例如:结构化查询语言(SQL)可以认为是DSL的关系模型,DSLs尝试解决实时系统中特定领域和底层实现中的差距。
一些精心设计的DSL让一些非程序员能够编写自己的程序,许多临时的SQL使用者能够使用SQL查询来获取他们需要的信息,却对关系型数据库的底层结构知之甚少。另一个关于广泛使用DSL的很好的例子是,Microsoft Excel的脚本语言,称为Visual Basic(VBA)。
虽然DSL是专门针对非程序员,但是对于开发人员依然是一种财富,因为DSL使开发人员成为了特定语言领域的专家。在实践中,DSLs与底层架构工作相比使程序员更加有效率。
DSL往往不一定完备,实际上意味着它们不能用于写任意复杂的算法,或者是作为通用的编程语言。相反,它们通常是声明用户的预期成果并实现这一结果。例如,在SQL中,可以通过查询来操作数据表中的数据。在大多数。
页码-437
关系型数据库中,实时运行的系统将决定如何存储数据和满足您的查询
DSLs也被分类为内部和外部:
外部DSL的应用与其它编程语言使用相同工具,设计独特的语法以及用于解析程序语言的自定义编译器
内部DSL(有时称为嵌入DSL)是“托管”在另一个更通用的编程语言(或者DSL)上,这意味着它使用程式化的主机语言的语法,而不是具有其独特的语法
早期的hadoop的开发者开发DSL非常迅速,您可能听说过它们中的一些:
Hive, Pig, Clojure-Hadoop, Grumpy(Groovy Hadoop), Sawzall, Scoobi, Lingual, Pattern, Crunch, Scrunch
而且这个队伍还在不断的壮大
Hadoop的DSLs
Hadoop的DSL一般可以分为几个大类:
? 基于SQL的DSL—DSL基于SQL(开放性的基于SQL和“类似于SQL”)对于拥有后台数据库的非程序员最实用,运用这些DSLs,人们“认为”在数据库语言可以完成数据分析任务而不必去想MapReduce
? 数据流DSL—这些DSL通过数据管道筛选和转换,处理数据和聚合数据流
? 特殊问题的编程语言—这些DSL重点放在一个特定的问题域,有时使用不同的模型来处理数据。图形处理就是其中的一个例子,模型数据图(例如:社交网络中的好友连接)和数据计算类型的图。
Hive 和基于SQL的DSLs
您可能已经熟悉了Hive,它采用HiveQL,Hadoop中一种基于SQL的DSL,以SQL为导向从而使非程序员易于使用,当然这只是其中一个例子。类似于基于HDFS数据的SQL类查询工具,它允许用户访问您的表模式的数据,并在内部实现了使用MapReduce的查询。Hive不是一个关系型数据库管理系统(RDBMS),因为它没有事务的概念或者记录级的CRUD(创建,查找,更新和删除),但是它切实提供了一种语言(叫做HiveQL),很容易被数据库的用户理解。它把重点放在查询—请求数据和进行汇集操作。
尽管新接触Hadoop的用户倾向于使用Hive作为一个关系型数据库,但是需要重视的是MapReduce任务批量的使用HiveQL的命令,这使得Hive不适合满足快速查询的需求(尽管正在进行中的工作能够使Hive更快的从Mapreduce中解耦,将在本章后面的内容中讨论),Hive从来没有
页码-438
要取代一个企业级的数据仓库,但作为一种简化和合作数据集合的方法,让未必是JAVA开发人员的其他人能够处理数据集并获得价值。
Facebook发明了Hive并将它在2008年开源贡献给了Apache基金会,Facebook的数据分析师需要友好的生产工具去操作在Hadoop集群中的数据,因为SQL是如此的普遍,一个基于SQL的工具是一个合乎逻辑的选择,Hive也许是推动Hadoop采用的最重要的工具,因为它为刚接触Hadoop的使用者降低了门槛。
Hive使用外部DSL(正如前面分类),HiveQL拥有自己的语法,编译器和运行环境。大多数的Hive查询被转换成MapReduce任务,但数据定义语言(DDL),用于创建和修改数据库,表和视图不需要Mapreduce。Hive存储这些元数据信息在一个单独的数据库(例如,Mysql),在读取或处理HDFS上的数据或者其他数据存储的时候,大多数的查询会触发一个或者多个MapReduce任务,通过Hive的查件支持不同的数据格式。
让我们探讨Hive作为一个DSL的概念,并获取到按照年,月,日分隔的HDFS的服务的数据作为一个例子。具体发生了什么的任何特殊细节不在这里讨论,只为了说明一个强大的DSL的价值。表单13-1提供了服务器日志数据的DDL实例表:
表单13-1:日志表定义
表内容…….
表单13-1中所示由3个主要部分组成。该第一部分包含文件及它们的类型(类似于一个普通的数据库表),第二部分是对Hive的特殊设计,特殊的数据分区。在表单13-1的数据分区说明:表将包括几个部分,其中之一用于记录每天的日志,最后的第三部分每个分区存储作为一个单独的序列。
Hive组织分区数据到不同的目录,如果仓库目录在HDFS中被配置为一个仓库的话,那么这个分区表的外观目录结构就如同在表单13-2:
439
表单13-2:分区目录
...
/warehouse/logs/year=2013/month=4/day=13
/warehouse/logs/year=2013/month=4/day=14
/warehouse/logs/year=2013/month=4/day=15
...
如上所示,所有的数据将在4月13日的目录中,现在,考虑使用一个例子进行查询(表单13-3),在4月13日中午到下午一点之间发生了什么
表单13-3
SELECT hour, min, sec, msec, severity,message
FROM logs
WHERE year = 2013 AND month = 4 AND day =13 AND
hour>=12 AND hour Hive主要介绍了数据的查询,Pig主要介绍了提取,转换和加载(ETL)处理。使用PigLatin,开发人员能够指定如何加载数据,在管道中创建数据的检查点,并且它是高度可定制的,然而Pig和Hive的部分功能是重叠的,以致于您可以使用两种语言来查询和ETL(注:Extraction-Transformation-Loading数据提取,转换和加载)
为了证明Pig和Hive之间功能的相似点,让我们尝试一个实例查询,一个苹果公司的年度股票记录,与去年同期相比的平均收盘价格,表单13-5展示了一个Hive查询例子,这是一个简单的SQL
表单13-5:使用Hive的有关苹果公司的查询
442
SELECTyear(s. YYYY-MM-DD), avg(s.close)
FROM stocks s
WHERE s.symbol = 'AAPL'
GROUP BY year(s. YYYY-MM-DD);
与Hive不同的是,Pig没有一个DDL(Data Definition Language数据库定义语言),就像表单13-6中所示的Pig样例展示,启动时通过文件读取数据。
表单13-6:使用Pig的有关苹果公司的查询
aapl =load '/path/to/AAPL.tsv' as (
YYYY-MM-DD: chararray,
...,
close: float,
...);
by_year= group aapl by SUBSTRING(YYYY-MM-DD, 0, 4);
year_avg= foreachby_year generate
group,AVG(aapl.close);
-- Dump to console:
dumpyear_avg;
在表单13-6中,您可以看到熟悉的GROUPBY的SQL操作,对于每一个a,b是一个映射,相当于使用SQL在a中选择b。请注意,在分组aapl中,生成一个名为by_year的新关系,Pig命令irstield组,从你的分组信息中取出包含年份键值的信息。Pig命名的第二个领域aapl(已经定义好的分组)保存分组记录。因此,使用表达式foreach by_year生成组,AVG(aapl.close)的真正含义是,遍历每年的平均值通过by_year。
Pig被描述为一个轻量级的语言,因为你定义的语句描述每个步骤的数据处理,从原始模式来源到输出。
表单13-7展示一个用Pig实现字数统计的程序
inpt = LOAD '/path/to/input' using TextLoader AS (line:chararray);
words =FOREACH inpt GENERATE flatten(TOKENIZE(line)) AS word;
grpd =GROUP words BY word;
cntd =FOREACH grpd GENERATE group, COUNT(words);
STORE cntd INTO '/path/to/output';
看起来像是执行“变量=值”的语句序列,实际上,每一行右边的deines关系(这个词的关系模型的定义)是左边创建的别名(或者名字)
这个实现首先加载数据,在输入模式中将每一行的文本作为一条记录,命名类型为字符串类(一个字符串),然后遍历每条记录,对文本分词,将每个单词形成单一记录。将单词分组,然后每一组统计所给单词的出现信息,最后,将每个单词(拥有这个词的字段现在被命名为group)和每组(拥有这个组的分组信息关系内容的字段命名为单词)的大小进行分项
443
您的结果将输出到一个路径下。
Pig是一种天然数据流,但它也包括所有的传统关系型业务,如同Hive所包含的(存在一些例外),包括GROUP BY,JOIN,PROJECTION,FILTERING(WHERE子句),限制等等
像Hive一样,Pig是一种拥有自己的语法和编译器的外部DSL。它不是一个真正严谨的语言,因此,例如不支持一般的循环(除了信息的迭代),此外,像Hive和Pig支持插件的格式化和UDFs,但是Pig支持多种语言编写UDF,包括Python,Ruby和JAVAScript,除了JAVA
Pig的好处在于比Hive更高的灵活性和逐步规范的数据流,数据库的用户喜欢用Hive,程序员喜欢用Pig,因为它看起来感觉更像传统的编程语言
现在让我们来谈谈比MapReduce相关的Hadoop的JAVA的API和更高层次基于JAVA虚拟机(JVM)的DSL。需要注意的是在JVM上而不是依托JAVA。因为,您会看到一些DSL在JVM上的使用,是基于JAVA以外的其他语言。
Cascading和 Scalding
Cascading是在低级别的MapReduce API上最流行的JAVA的DSL,根据介绍,在2007年末的DSL实现大规模数据的函数编程中,Cascading是MapReduce是真正最完备的内部或嵌入式的DSL,在数据流中的明确的象征性的排序管道,隐藏和许多底层的API的细节,使开发人员能够专注于手上的工作。
Cascading是基于“管道”来进行分割和合并数据流,对它们进行操作。在Cascading中,数据记录称为元祖,管道被称为组件,穿越管道的记录被称为元祖流,Cascading定义工作流管道元素,例如pipes(管道), taps(开关), and traps(陷阱)。
一个管道连接工作流(或管道)的主要内容,并定义哪些元祖穿越它完成工作,
管道由每个类型(应用函数或过滤器)GroupBy(元祖字段流),CoGroup(加入一组常见的值),Every(适用于每一个聚合器或滑动窗口)和组件(集成其他的)。
一个开关(tap)代表一个资源,或者轻量级的数据源的连接,一个数据源开关通常是输入开关(在哪里读数据)一个池开关通常是输出开关(在哪里写数据)
一个陷阱(a trap)是一个池开关—这是写入数据导致操作失败的地方,使您能够继续处理您的数据而不会因为数据的丢失出错。
表单13-1展示Cascading管道的一个例子,即大家熟悉的字数统计
444
图13-1中有两个开关,输入开关(接收文档的集合)和输出开关(产生字数)。管道也有两个功能----一个标记和计数功能(聚合器),和数据流的分组组件。
表单13-8显示了一个使用Cascading实现字数统计的方法
importorg.cascading.*;
// other imports...
publicclass WordCount {
publicstatic void main(String[] args) {
// Set up app properties.
Properties properties = newProperties();
FlowConnector.setApplicationJarClass(properties,WordCount.class);
// Define the input and output"taps".
Scheme sourceScheme = newTextLine(new Fields("line"));
Scheme sinkScheme = newTextLine(new Fields("word", "count"));
String inputPath = args[0];
String outputPath = args[1];
Tap source = newHfs(sourceScheme, inputPath);
Tap sink = new Hfs(sinkScheme, outputPath, SinkMode.REPLACE);
// Connect the pipes for thedata flow.
Pipe assembly = newPipe("wordcount");
// Regular expression totokenize into words.
String regex ="(? |
|
|