一、前言:
非常感谢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 <= 13
ORDER BY severity DESC, hour, min, sec, msec;
在表单13-3中的语法对于任何一个熟悉SQL的人来说是非常直观的,而相反,通过MapReduce的JAVA的API来写这个查询是非常具有挑战性的,因为实现ORDER BY的子句可能需要掌握专业编程语句。
在这个例子中,需要注意的是日志的查询区间永远是波动的,如下所示,WHERE子句的边界时间戳范围敏感,因为数据已经按照年,月,日分隔,Hive知道只需要扫描子集目录(在这个例子中为4月13日)从而提供了相对快速的查询结果,即使是一个涵盖许多年达到TB级别的日志数据集。
正如HiveQL这样的一个好的DSL应该做到:
提供一个简洁的,声明性的方法来陈述信息结构和工作方式
对于特定领域专家(即数据分析师)直观的语言,Hive隐藏了数据存储和查询的复杂性
很容易指定数据的组织方式(在这个实例下,通过时间戳分区)来提高查询速度
相比手写Java的MapReduce,HiveQL代码更小的开销
提供了扩展钩子,能够插入不同的格式和功能
Hive能够使您通过不同的方式扩展它的功能:
允许您指定不同输入和输出格式
允许您使用自定义的序列化器和反序列化器(称为SerDe)进行格式化
440
允许您创建用户自定义函数(udf),可以用Java编写并在HiveQL中声明
允许在您的查询中自定义mappers和reduces
让我们来看看如何扩展Hive的一些示例,如果您回顾13-1表单中的DDL语句,它指示Hive存储中的数据序列,使用SequenceFile格式化输入。对于灵活性和可扩展性,Hive允许开发人员轻松的插入自己的输入格式,允许在各种不同的格式和业务中读取数据,它还使您可以插入自己查询结果的输出格式,这个钩子已经被整合在Hive在Hbase的数据存储,Cassandra和其他数据存储的应用中。
如前所述,Hive还可以通过指定SerDe支持独特的记录格式(串行器/解码器),知道如何将输入记录解析成列,并选择性的以相同的格式输出。注意,Hive简化输入和输出的格式化,清楚记录的存储方式(或字节流),而SerDe了解每个记录是如何解析成列的。
一个流行的记录格式的例子是JavaScript的对象表示法(JSON),列表13-4中,修改声明JSON为存储数据的格式,其中每个JSON记录存储一行。
表单13-4:使用JSON定义的记录表
CREATE TABLE logs ( -- the
severity STRING,
...,
hour TINYINT,
...)
PARTITIONED BY (...)
STORED AS ROW FORMAT SERDE
‘org.apache.hadoop.hive.contrib.serde2.JsonSerde‘
WITH SERDEPROPERTIES (
"severity"="$.severity",
...,
"hour"="$.timestamp.hour",
...);
在此表中的例子,JsonSerde实现了Hive的SerDe API ,这是Hive的一个重要特征,指导您使用Hive处理记录。在这个示例中,Hive将调用JSON SerDe解析每个JSON记录成列,在表中声明的SERDEPROPERTIES, SERDEPROPERTIES是Hive的一个功能,通过特殊的键--值对指定定义SerDe接口,在这种情况下,使用$引用JSON的文档,所以变量$.timestamp.hour
意味着“使用小时单位时间戳内的记录”将被用于小时列。
最后,Hive支持UDF来扩展或者聚合记录和操作列,通过UDFs,您可以编写JAVA函数由HiveQL声明,对于Hive本身不支持
441
的功能是非常有用的。例如,Hive不提供窗口的功能,像大部分关系型数据库管理系统那样,将记录聚合在一个提供的可移动的窗口中,一个典型的例子股票交易员使用收集若干天的股票收盘价的趋势走向,很明显的揭示当前的最新趋势,这些通过自定义的UDF来提供。
Hive是Hadoop的DSL中非常好的一个例子,隐藏了MapReduce的复杂性并为Hadoop的数据处理提供了一个可广泛理解的语言,多数的情况下,它把JAVA手写MapReduce代码的开销降低到最小,并且提供了扩展点能够自定义代码解决大部分Hive尚未涉及到的部分。这种在MapReduce中抽象的方法来源于数据库工程师,使他们能够专注于自己的数据问题,而不是编程。
当然还有其他基于SQL的DSL在使用,特别是Hadoop的实时查询引擎,在第9章(Cloudera的Impala以及Apache的Drill)使用基于SQL的DSLs作为编程语言。
数据流和相关的DSLs
轻量级的DSL使开发人员能够通过管道,转换和聚合的方式处理大型数据集。例如,众多的DSLs最广为人知的是Pig,一个与大多数的Hadoop发行版捆绑在一起的工具,使用轻量级语言,抽象MapReduce框架,作用在MapReduce的底层。
Pig
Facebook发明了Hive,使分析人员熟练的使用Hadoop的数据进行工作,雅虎发明了Pig,更适合于转换和聚合数据,它有一个叫做PigLatin的定制语言,不是基于SQL,意味着它更适合于开发人员,而不是经验丰富的SQL用户。
Hive主要介绍了数据的查询,Pig主要介绍了提取,转换和加载(ETL)处理。使用PigLatin,开发人员能够指定如何加载数据,在管道中创建数据的检查点,并且它是高度可定制的,然而Pig和Hive的部分功能是重叠的,以致于您可以使用两种语言来查询和ETL(注:Extraction-Transformation-Loading数据提取,转换和加载)
为了证明Pig和Hive之间功能的相似点,让我们尝试一个实例查询,一个苹果公司的年度股票记录,与去年同期相比的平均收盘价格,表单13-5展示了一个Hive查询例子,这是一个简单的SQL
表单13-5:使用Hive的有关苹果公司的查询
442
SELECT year(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中,您可以看到熟悉的GROUP BY的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...
public class WordCount {
public static void main(String[] args) {
// Set up app properties.
Properties properties = new Properties();
FlowConnector.setApplicationJarClass(properties, WordCount.class);
// Define the input and output "taps".
Scheme sourceScheme = new TextLine(new Fields("line"));
Scheme sinkScheme = new TextLine(new Fields("word", "count"));
String inputPath = args[0];
String outputPath = args[1];
Tap source = new Hfs(sourceScheme, inputPath);
Tap sink = new Hfs(sinkScheme, outputPath, SinkMode.REPLACE);
// Connect the pipes for the data flow.
Pipe assembly = new Pipe("wordcount");
// Regular expression to tokenize into words.
String regex = "(?<!\\pL)(?=\\pL)[^ ]*(?<=\\pL)(?!\\pL)";
Function function = new RegexGenerator(new Fields("word"), regex);
assembly = new Each(assembly, new Fields("line"), function);
assembly = new GroupBy( assembly, new Fields("word"));
Aggregator count = new Count(new Fields("count"));
assembly = new Every(assembly, count);
FlowConnectorflowConnector = new FlowConnector( properties );
Flow flow = flowConnector.connect( "word-count", source, sink, assembly);
flow.complete();
}
}
该代码通过设置应用程序的属性和源,控制开关,通过管道汇集数据创建数据流,需要注意SQL包含一些关键字操作例如GroupBy和Projection(映射)和函数计算,Cascading将这些封装成了JAVA类。像Pig的脚本(表单13-7),您遍历每一行,标记关键字(使用正则表达式)进行分组,计算每组大小,最后将结果输出。
445
这个实例展示了Cascading关系操作的算法
这样的框架模板比单纯的展示MapReduce的字数统计如何工作的模板少很多
注意:这是一个更加复杂的数据流实例,参阅CMU Workshop on CoPA(Cascading + City of Palo Alto Open Data)在https://github.com/Cascading/CoPA/wiki,展示了如何使用Cascading和Hadoop清理未加工的和非结构化的数据,例如公园,街道开放数据和树的数据信息。Workshop建立多个应用程序,利用这些数据提供一个示例应用。
虽然Cascading是一个JAVA API,但是APIs当前允许使用其他的语言,列表包括Scala的Scalding, Clojure的Cascalog, Python的PyCascading以及其他。它们当中还包括一些JAVA API中所没有的功能性的增强。例如,Cascalog增加了基于数据日志的逻辑查询功能,而Scalding增加了有关遍历问题以及许多机器算法的数学模型。
表单13-9展现了一个版本的使用遍历的数字统计
表单13-9Scalding实现数字统计
importcom.twitter.scalding._
classWordCountJob(args: Args) extends Job(args) {
TextLine(args("input"))
.read
.flatMap(‘line -> ‘word) {
line: String =>
line.trim.toLowerCase.split("\\W+")
}
.groupBy(‘word) { group =>group.size(‘count) }
}
.write(Tsv(args("output"))) // tab-delim. output
}
正如表单13-9中的说明里的内容,Scalding是从Twitter中发展出来的。让我们注意一些重要的事情而不去关注Scala语法的细节。
首先,简洁的代码—明显优于JAVA,有些例外的是,这段代码看起来像典型的Scala代码为了更小以及内存数据集合设置的内置API。
其次,关系运算(如分组)是函数调用而不是类。.groupBy(‘word) { group =>group.size(‘count)这行意味着之间的输出函数调用GroupBy函数。分组在这种情况下,跨越域命名。此外一个匿名函数传递给GROUPBY需要每个组作为参数,并返回该组的大小,标记值作为域的命名计数。这一步的数据输出(加入制表分隔符的输出)包含每个词和它的计数。
446
在表单13-9中flatMap做了些什么?它代表了MapReduce的map阶段。在数学领域,map实际上总是一一对应的,也就是说每个输出元素对应一个输入元素。MapReduce放宽了这个约束,允许0对多的输入/输出对应关系。这正是flatMap的实际意义。这个匿名函数从原始的数据集合输入元素对应0对多的关系到输出元素。然后flatMap”flattens”嵌套的集合到一个”flat”集合。因此,您一直在使用Flat MapReduce。
Crunch和Scrunch
另一个MapReduce的DSL被应用于MapReduce中的被称为Crunch,仿照谷歌的JAVA池的设计,使用小型的原始操作巨大的数据流。Crunch拥有三种数据抽象:PCollection<T>(用于并行数据类型为T的数据集合),PTable<K,V>(分别键值对关系的并行表的拆分),PGroupedTable<K,V>(分组的操作输出),在集群中也存在并行结构实现业务处理。
表单13-10展示Crunch实现字数统计
// import statements...
public class WordCount {
public static void main(String[] args) throws Exception {
// Setup the pipeline and the input.
Pipeline pipeline = new MRPipeline(WordCount.class);
PCollection<String> lines =
pipeline.readTextFile(args[0]);
// Tokenize the lines into words in parallel.
PCollection<String> words = lines.parallelDo(
"my splitter", new DoFn<String, String>() {
public void process(
String line, Emitter<String> emitter) {
for (String word : line.split("\\s+")) {
emitter.emit(word);
}
}
}, Writables.strings());
// Count the words.
PTable<String, Long> counts = Aggregate.count(words);
pipeline.writeTextFile(counts, args[1]);
pipeline.run();
}
}
从表单13-10中可以发现,Crunch是开发人员能够使用更多底层的Hadoop JAVA API(例如,使用Avro的类写入数据,使用起来非常便捷,对于熟悉JAVA的程序员非常容易学习)
447
Crunch的Scala版本叫做Scrunch,表单13—11将展示使用Scrunch进行的数字统计
表单13-11 使用Scrunch进行数字统计
// imports...
classWordCountExample {
val pipeline = new Pipeline[WordCountExample]
defwordCount(fileName: String) = {
pipeline.read(from.textFile(fileName))
.flatMap(_.toLowerCase.split("\\W+"))
.filter(!_.isEmpty())
.count
}
}
表单13-11如同Scalding DSL一样展示了优雅,简洁的操作数据流,Cascading和Scalding这组例子在量级和复杂度上非常相似
如上所示,Crunch 和 Scrunch更加侧重模式和Cascading中的静态数据类型,当前静态和动态数据类型彼此之间的优势并不明显,差异取决于您的工具的选择和喜好。
图形处理
最后讨论的这个DSL虽然在今天应用不是很广泛,但您将在未来的一段时间内更多的接触到使用图形化算法的DSLs。这样的使用需求是巨大的。
在线社交图化正在迅速的发展,并且将有越来越多的需求去分析它们。在线社交网站,如:Facebook, LinkedIn, Google+和Twitter像Yahoo和Google这样的电子邮件网站有着数以亿计的用户,在广告和个性化中分析人以及他们的关联角色扮演着非常重要的角色。Google是率先发现图表分析的重要性,并将网页排名(PageRank)算法应用于其搜索引擎中的公司其中之一。Larry Page 和Sergey Brin(谷歌的创始人)将该算法应用在搜素订单结果的“链接热度”将更多的网站链接到一个网页上。虽然决定排名的相关性因素众多,不过该算法是应用于Google的网络搜索工具当中。
其他一些问题依赖于链接,图形和网络分析,今天,Facebook在Hadoop的这个领域一路领先,在Hadoop的未来发展中图形化的DSL将是一个飞速发展的领域。
到目前为止,图形化的处理系统对于Hadoop来说是新兴领域,因为可扩展的计算机集群图形化处理出于研究领域的前沿,尚且存在着一些问题,比如接下来的调查主题中所展现的:
448
如何在集群中绘制分区的密度图
如何跨集群拆分图从而最小化链接主机的数量
如何跨机器链路完成信息的更新
目前很多积极的工作和越来越多的应用投入到Hadoop的图形处理中来,本章只探讨目前提到的方法以及在“DSL 空间”项目计划中内容,更多您应该自己进一步调查。
像以往一样,谷歌的论文作为先驱,Apache紧随其后。Pregel是Google用于数据分析的大型图形分析系统(http://googleresearch.blogspot.com/2009/06/large-scale-graph-computing-at-google.html),Giraph(将在本章稍后介绍)是APACHE对应Hadoop的Pregel开源版。其被Facebook用来分析用户的社会以及朋友团体中的图形化关系。
图形化处理系统,如Pregel和Giraph基于并行处理模型称作Bulk Synchronous Parallel散装同步并行 (BSP),能够同步图形处理节点之间的通信。为了演示BSP的工作方式,在t0时刻,所有节点在同一时刻向其他连接着的节点发送信息。所有的节点在t1时刻,根据需要,更新它们的状态,以此类推。障碍同步发生在每次的数据发送之后。
建立的并发通信模型的基础上,您可能认为MapReduce将会缺少高度迭代模型—您的假设是正确的。在MapReduce中本机执行的BSP依赖于单独的MapReduce任务每个迭代的BSP将带来可怕的开销。
然而,图形处理系统开始应用于Hadoop的数据存储以及MapReduce的BSP并行计算操作中,一系列图形处理系统涌现,让我们关注两个这个类型的Hadoop开源系统:
Giraph是Apache的一个项目,类似于Google的Pregel,实现HDFS上的BSP。在Giraph上,您提交一个MapReduce任务,但其在内部处理迭代步骤使用Vertex的环境,保存状态图在内存中并不联动MapReduce任务。Giraph利用了Hadoop和MapReduce的数据存储的基础资源管理,但与在MapReduce中使用BSP不同的是,Giraph还引入了ZooKeeper进行容错以及集中的调度服务
Hama也是Apache的一个项目,类似于Giraph,是一个BSP的计算框架,该框架应用于HDFS的顶层。然而,Hama绕过了MapReduce,独立了自己的一套跨集群的计算过程,Hama避免了Hadoop的MapReduce资源调度和工作模式的局限性。与试图引入该框架相比组织往往不愿引入一套新的集群的处理方式与MapReduce争夺资源,出于这个原因,Hama的使用往往独立于集群专门做这类的分析。
449
在未来Hadoop的图形化DSLs具有飞速发展的潜力。
这个有关Hadoop的DSLs的简短的总结表明,除了基础的MapReduce框架,一组丰富的dsl可以使编写Hadoop的任务更有成效,更加适合用户的需求。新的Hadoop DSLs会定期的涌现,例如,Cascading刚刚推出了两款新的DSL。
Lingual–一个新的SQL类型的DSL
Pattern–一个新的机器学习类型的DSL
现在,您知道DSL如何帮助您简化MapReduce的用法,下一节将看到MapReduce本身的改进,使其能够更快,更高扩展性的进行程序处理
正如本书所讨论的,MapReduce基本架构实现是非常庞大的,而实现这个的重要组成部分是JobTracker(在第三章中详细介绍的),负责资源管理,作业调度以及监控。除此之外,实施者已经发现,JobTracker的实现过于复杂可能会导致一些问题,包括内存消耗,严格的线程模型以及扩展性,可靠性和性能问题。
这个分析结果导致,Hadoop将在MapReduce上做一次彻底的变革,有时候称为“次世代的MapReduce”,“MapReduce2.0(MRv2)”或者本节中另一种资源的代表(YARN),在提出了这种变革之后,一个称为”Tez”(印度语中的速度)的新项目被引入了Apache孵化器。并声称能够大大提高Hadoop的性能,您在本章中将详细的了解它们。
需要重点注意的是,虽然在下一节中的相关描述中被称为MapReduce2,但不会改变MapReduce实际的编程模型,或者本书中描述的开发人员使用的这些APIs
Apache YARN
Hadoop的开发委员会决定,解决方案是在原有的MapReduce的基础上分裂资源管理和作业调度到单独的守护进程,一个全新的全局资源管理器叫做YARN将JobTracker的功能拆分为两个独立的守护进程。
一个全局资源管理器(RM),由一个调度程序和一个应用管理程序组成
一个应用程序主节点(AM)提供应用程序支持,一个在传统意义上的MapReduce任务中添加一个常规任务的应用,或者一个定向非周期任务(a Directed Acyclic Graph (DAG) of jobs)(与6~8章中的Oozie相比较)。拆分JobTracker提供了更高的灵活性和更好的功能。
450
YARN的资源管理是基于非常普遍的资源应用模型,提供特定数量的资源(内存,CPU等等),正如Hadoop中的其他部分一样,YARN的资源管理和执行框架也是利用主从架构来实现的。子节点或者节点管理器(NMS),运行在每个节点。他们管理一个特定节点上的容器,检测节点的执行状态,将资源的可用性报告给主节点,被称之为资源管理器。主节点负责协调系统中的所有应用程序资源(与第二章中的HDFS体系结构类似)
具体的应用程序的执行是由主应用程序控制,主应用程序是完全分布式的,每个节点上都有主应用程序的实例。主应用程序负责拆分多个任务以及与应用资源管理器(容器)进行协调。当一个资源被分配时,主应用程序与节点管理器(们)相互作用去放置,执行,监控应用程序任务。
整体的应用流程如图13-2所示:
分为以下步骤
图13-2:YARN的体系结构
451
- 客户端程序提交申请,向特定的应用程序主节点引入必要的规范,作为应用程序的一部分提交,必须提供充分的信息到资源管理器去启用应用程序的第一个容器—主应用程序。依赖的信息(应用程序提交的)包括应用程序运行所需的本地文件或者jar包,实际必须执行的命令(必要的命令参数),任何UNIX环境变量(可选)等等.以此类推,由主应用程序描述UNIX 进程(们)是非常重要的。
- 资源管理器分配必要的容器给主应用程序,然后启动主应用程序
- 启动时,主应用程序注册到资源管理器,允许客户端去查询资源管理器获得主应用程序的细节,包括它的地址。得到这些细节后,客户端可以直接与自己的主应用程序通信
- 一旦主应用程序启动并运行,它会检查应用程序的请求,并协调应用程序执行的资源空间
- 资源空间被分配后,主应用程序将资源信息发布到节点管理器上
- 执行的过程中,应用程序代码提供必要的信息(进度,状态等等)到主节点,这些信息对于与应用程序通信的客户端也是可获取的
- 一旦应用程序完成后,主应用程序释放资源,注销,关闭并释放自己的容器
对于YARN需要注意的是,它不会改变实际的MapReduce编程模型(YARN使用的MapReduce2的名字容易造成误导)和开发人员使用的API,它只提供了一个新的资源管理模式和实现应用于执行MapReduce任务。因此在最简单的情况下,现有的MapReduce将正常工作仅需要重新编译
YARN可用于创建新的框架和执行模型(除了MapReduce的),利用Hadoop集群的并发计算能力和丰富的数据存储模型,以解决具体的新问题。这种新的框架可以利用YARN的资源管理,提供一个新的应用程序管理器。在撰写本文的时候,这些项目或多或少的都是移植YARN实现的:
Spark(一个开源的集群计算系统)
Apache Hama(本章前面描述过的图形分析框架)
Apache Giraph(同上)
Open MPI(一个高性能计算的开源项目)
452
Storm(一个第九章描述的开源,分布式实时计算系统)
Apache S4(一个类似Storm的Apache项目,提供实时的事件处理)
YARN结构允许多个应用程序管理器共享相同的Hadoop集群以及集群上的数据,这样简化了驻留在Hadoop集群上的多个框架之间的数据级别。
使用YARN执行MapReduce应用提高了可扩展性,但是MapReduce的编程模型并没有充分利用YARN的能力,特别是内置的DAG的支持。MapReduce的使用通常伴随Oozie编排的个体MapReduce任务。虽然这种方法很好的应用于批量的运行程序,但是给传递数据到HDFS以及应用程序的启动时间方面带来很大的开销。
其中的一些不足之处在一个叫做Tez的新的Hadoop框架中被去除
Tez
Tez提供了一个通用的,高可用的框架,支持编排定制任务到DAG中,Tez不仅是为了个别的MapReduce任务,而是整体任务,从而获得比Oozie更快的性能。Tez的高性能是依靠消除多个任务带来的开销从而满足人机交互的响应时间需求以及PB级别的高吞吐量(第9章中的实时处理)。
最初由Stringer创建并支持,目标是Apache 的Hive的100倍的性能。Tez提供了一个单一的框架支持延时和吞吐量敏感的应用。因此,它消除了多个框架和系统的安装,维护,支持的必要性,从而为企业节省了大量的成本。
Tez是2013年出由Hortonworks贡献给Apache并进入孵化阶段的。它是一个有很多程序员参与的非常活跃的项目,在Hadoop的实时应用方面有着非常光明的前景。
安全性强化
如第10章介绍的,Hadoop社区正在致力于安全性方面的增强。增加了新的加密编解码器,新的基于令牌的认证协议,支持属性的统一认证系统,基于角色的访问控制(ABAC),执行策略支持开放标准和XACML,改变hbase允许授权。Hadoop可以从集群环境和周边级别环境中分离,从而满足高度安全的环境要求。
453
注意:想要了解更详尽的信息,请参考第10章中的“安全性增强计划Rhino”
新的趋势
这本书已经涉及到了许多Hadoop的相关趋势,虽然作者没有水晶球,但他们认为以下将成为关键领域将在未来飞速发展。
实时的Hadoop—这种趋势今天正在发生,并将持续下去,将Hadoop看做是一个批量处理模式的系统,Hadoop在未来(特别是近期出现的性能和伸缩性的改进)伴随着人为响应时间进行实时分析。您可能会习惯于很长时间才能完成的任务迅速的执行完成,这将在几个不同的方面—欺诈检测,事务分析,安全漏洞分析和实时事件的异常检测以及和Hadoop生态系统中的其他工具的根据需求的分析处理。
图表分析和超越MapReduce的新算法—如果您伴随着Hadoop发展的历史,您将发现Google的影响力,Google的新的可伸缩分布式图形化分析算法引发了比MapReduce更大的兴趣。因为Apache 的Giraph(本章前面讨论过)是Google的高性能图形化分析平台(Pregel)的开源实现,并且Facebook应用Griaph的图形分析于其社交网络上,毫无疑问这将是Hadoop中飞速发展的领域。Apache的Hama(也在本章前面讨论过)利用HDFS存储以及其他的图形化算法在Hadoop上,这种趋势将会继续。
机器学习—虽然本书中没有过多的介绍,这是一个发展中的话题。伴随着Apache Mahout 和 Pattern这样的项目,机器学习的Cascading的DSL,预测建模和机器学习将越来越多的用于Hadoop的常见用例,类似推荐,欺诈检测和安全漏洞检测。
更高层次的抽象以及本章之前介绍的DSLs,您已经了解到Hadoop的DSL的强大,以及它们是如何的简化编程。使用这种语言或者工具将大大的减少Hadoop和MapReduce的使用的学习难度,而这一趋势将会继续增长。虽然使用一些工具肯定会有性能上的损失,但更多的科学家和领域专家在专门的领域中使用Hadoop的工具集消除了屏障,使处理的速度变得更快。甚至有些数据专家不知道自己正在使用Hadoop!
Hadoop正在不断的快速发展,拥有一个光明的未来,正如持续改进的领域所展示的,新的项目在扩散,性能的改进,安全性和DSLs的发展和增长,新的方向迅速的开展对于每一个Hadoop的开发者来说是多么的激动人心!
454
总结
本章强调了利用DSL简化MapReduce的增长趋势,您了解到了YARN和Tez对于Hadoop扩展性能的提升,以及安全性方面的改进提升以及Hadoop未来发展的新兴趋势。