用 Hadoop 进行分布式数据处理第 3 部分.docx
- 文档编号:25103567
- 上传时间:2023-06-05
- 格式:DOCX
- 页数:15
- 大小:56.48KB
用 Hadoop 进行分布式数据处理第 3 部分.docx
《用 Hadoop 进行分布式数据处理第 3 部分.docx》由会员分享,可在线阅读,更多相关《用 Hadoop 进行分布式数据处理第 3 部分.docx(15页珍藏版)》请在冰豆网上搜索。
用Hadoop进行分布式数据处理第3部分
用Hadoop进行分布式数据处理,第3部分:
应用程序开发
为Hadoop开发RubyMapReduce应用程序
M.TimJones,自由作者
简介:
通过已经获得的在单节点和多节点体系结构中Hadoop的配置、安装以及使用的经验,您现在可以转到在Hadoop基础设施内开发应用程序的任务上。
本文是系列文章的最后一篇,其通过简单的mapper和reducer应用程序探索了HadoopAPI和数据流并演示了它们的使用。
查看本系列更多内容
本文的标签:
distribution,hadoop,mapreduce,存储,应用开发,进行分布式数据处理
标记本文!
发布日期:
2010年8月09日 级别:
中级 其他语言版本:
英文 访问情况:
8550次浏览 评论:
1 (查看 | 添加评论-登录)
平均分(14个评分)
为本文评分
联系Tim
Tim是我们最受欢迎、最多产的作者之一。
浏览developerWorks上Tim的所有文章。
查看Tim的个人信息,并在MydeveloperWorks中与Tim、其他作者和各位读者联系。
此系列的前两篇文章专注于单节点和多节点集群的Hadoop安装及配置。
最后这篇文章探索了Hadoop编程—特别是在Ruby语言中map和reduce应用程序开发。
我之所以选择Ruby,首先是因为,它是一个您应该知道的很棒的面向对象的脚本语言,其次,您将在参考资料部分发现很多参考,其中包括解决Java™和Python语言的教程。
通过这种MapReduce编程的探索,将向您介绍流式应用程序编程接口(ApplicationProgrammingInterface,API)。
此API提供方法以便在Java语言以外的多种语言中开发应用程序。
让我们开始简要介绍一下map和reduce(从功能的角度考虑),然后再进一步钻研Hadoop编程模型及其体系结构和用来雕刻、分配、管理工作的元素。
map和reduce的起源
是什么功能性元素激发了MapReduce编程范例的创立?
在1958年,JohnMcCarthy发明了名为Lisp的语言,其实现了数值和符号计算,但在递归形式下此语言非常不同于现在所使用的大多数语言。
(在维基百科全书上记述着Lisp那段迷人的历史,同时包括一个有用的教程—值得您花费时间来阅读。
)Lisp最先是在IBM®704中实现的,IBM®704是第一种大规模生产的计算机,也支持其他旧的语言,如FORTRAN。
map函数,源于功能性语言(如Lisp)但如今在其他语言中也很常见,其中包含了一系列元素的函数的应用程序。
这意味着什么?
清单1通过SchemeShell(SCSH)提供解释会话,即一个Lisp衍生。
第一行定义一个名为square的函数,该函数可接受参数并发出其平方根。
下一行说明map函数的使用。
如图所示,通过map,为已应用的函数提供您的函数和一系列元素。
结果是一个包含平方元素的新列表。
清单1.SCSH上的map函数演示
>(definesquare(lambda(x)(*xx)))
>(mapsquare'(1357))
'(192549)
>
Reduce也适用于列表但是通常将列表缩减为标量值。
清单2中提供的示例说明用于将列表缩减为标量的其他SCSH函数—在这种情况下,用(1+(2+(3+(4+(5)))))的格式汇总值的列表。
请注意这是典型的功能性编程,取决于迭代上的递归。
清单2.SCSH上的reduce演示
>(define(list-sumlis)(if(null?
lis)0(+(carlis)(list-sum(cdrlis)))))
>(list-sum'(12345))
15
>
有趣的是要注意递归与迭代在命令性语言中同样高效,因为递归在幕后被转化成迭代。
回页首
Hadoop的编程模型
Google引用MapReduce的概念作为处理或生成大型数据集的编程模型。
在规范模型中,map函数处理键值对,这将得出键值对的中间集。
然后reduce函数会处理这些中间键值对,并合并相关键的值(请参考图1)。
输入数据使用这样一种方法进行分区,即在并行处理的计算机集群中分区的方法。
使用相同的方法,已生成的中间数据将被并行处理,这是处理大量数据的理想方法。
图1.MapReduce处理的简化视图
对于快速刷新器来说,查看图1的体系结构,从map和reduce角度来进行字数统计(因为您将在本文中开发map和reduce应用程序)。
在提供输入数据时(进入Hadoop文件系统[HDFS]),首先分段,然后分配给map工作线程(通过作业跟踪器)。
虽然图2中的示例显示了一个被分段的简短语句,但是分段的工作数量通常在128MB范围内,其原因是建立工作只需要很少的时间,因为有更多的工作要做,以便最大限度地减少这种开销。
map工作线程(在规范的示例中)将工作分割成包含已标记单词和初始值(在此情况下是1)的单个矢量。
在map任务完成时(如通过任务跟踪器在Hadoop中所定义的),提供工作给reduce工作线程。
通过代表所发现的键的数量的值,reduce工作线程将许多键缩减为一个惟一的集合。
图2.简单的MapReduce示例
请注意此过程可在相同的或不同的计算机中出现或者使用不同的数据分区来按顺序或并行完成,且结果仍然是相同的。
虽然规范的视图(用于使用字数统计生成搜索索引)是一种用来查看Hadoop方法,但结果是此计算模型被常规地应用到可计算问题上,正如您将要看到的那样。
回页首
Hadoop的灵活性
从图2中所示的简单示例看,需注意map和reduce过程这两个主要元素。
虽然这里存在一个这些过程如何工作的传统视图,但是它不是map和reduce体系结构所需要的。
这就是Hadoop的真实力量—其灵活性用来实现在某种程度上活动的map和reduce过程,这解决了一个特定的应用程序。
虽然字数统计示例对于大量的问题是有用且适用的,但是其他的模型仍然在此总体框架内适用。
所需的就是使map和reduce应用程序的开发过程对于Hadoop可见。
在其他的应用程序中,Hadoop已经被用于实现包括神经网络算法的计算机学习应用程序,支持矢量计算机以及k-means集群(要获得更多信息,请参考参考资料部分)。
回页首
数据流
虽然Hadoop是一个基于Java的框架,但是其有可能在Java语言以外的语言中编写msp和reduce应用程序。
Hadoop内的流实用工具实现了一种数据流胶的类型。
通过流实用工具,您可以定义您自己的可执行map和reduce(使用每一个从标准输入[stdin]提取的输入和每一个通过标准输出[stdout]提供的输出),且流实用工具可适当地读取和写入数据,根据需要调用您的应用程序(请参考清单3)。
清单3.使用Hadoop流实用工具
hadoopjar$HADOOP_HOME/hadoop-流.jar\
-inputinputData
-outputoutputData
-mappermap_exec
-reducerreduce_exec
清单3说明如何在Hadoop内使用流实用工具,图3图形化地显示了如何定义流。
请注意这是一个流使用的简单示例。
大量的选项可用于制定如何解析数据、制定如何调用图像、为分区器和合成器指定替换图像以及调整其他配置(要获得更多信息,请参考参考资料部分)。
图3.图形流示例
回页首
Ruby示例
通过已经获得的在流实用工具基本理解上的经验,您已经准备编写一个简单的Rubymap和reduce应用程序并查看如何在Hadoop框架中使用过程。
虽然此处的示例伴随着规范的MapReduce应用程序,但是稍后您将看到其他的应用程序(取决于您将如何用map和reduce格式实现它们)。
首选是mapper。
此脚本从stdin提取文本输入,首先标记它,然后将一系列键值对发送到stdout。
像大多数面向对象的脚本语言一样,这个任务几乎太简单了。
如清单4中所示的mapper脚本(通过一些注释和空白区域可给与其大一点的大小)。
此程序使用一个迭代器来从stdin中读取一行,同时另一个迭代器将该行分割成单个的标记。
使用为1的相关值(通过选项卡分隔)将每一个标记(单词)发送到stdout。
清单4.Rubymap脚本(map.rb)
#!
/usr/bin/envruby
#OurinputcomesfromSTDIN
STDIN.each_linedo|line|
#Iterateovertheline,splittingthewordsfromthelineandemitting
#asthewordwithacountof1.
line.split.eachdo|word|
puts"#{word}\t1"
end
end
下一步,查看reduce应用程序。
虽然此应用程序稍微有些复杂,但是使用Rubyhash(关联阵列)可简化reduce操作(请参考清单5)。
此脚本可通过来自stdin(通过流实用工具传递)的输入数据再次工作且将该行分割成一个单词或值。
而后该hash会检查该单词;如果发现,则将计数添加到元素。
否则,您需要在该单词的hash中创建新的条目,然后加载计数(应该是来自mapper过程的1)。
在所有输入都被处理以后,通过hash可简单迭代且将键值对发送到stdout。
清单5.Rubyreduce脚本(reduce.rb)
#!
/usr/bin/envruby
#Createanemptywordhash
wordhash={}
#OurinputcomesfromSTDIN,operatingoneachline
STDIN.each_linedo|line|
#Eachlinewillrepresentawordandcount
word,count=line.strip.split
#Ifwehavethewordinthehash,addthecounttoit,otherwise
#createanewone.
ifwordhash.has_key?
(word)
wordhash[word]+=count.to_i
else
wordhash[word]=count.to_i
end
end
#Iteratethroughandemitthewordcounters
wordhash.each{|record,count|puts"#{record}\t#{count}"}
随着map和reduce脚本的完成,需从命令行测试它们。
记得要使用chmod+x将这些文件更改为可执行。
通过生成输入文件来启动,如清单6所示。
清单6.生成输入文件
#echo"Hadoopisanimplementationofthemapreduceframeworkfor"\
"distributedprocessingoflargedatasets.">input
#
通过单词输入,现在您可以测试您的mapper脚本,如清单7所示。
回想此脚本简单地将输入标记到键值对,此处每个值都将是1(非惟一输入)。
清单7.测试mapper脚本
#catinput|rubymap.rb
Hadoop1
is1
an1
implementation1
of1
the1
map1
reduce1
framework1
for1
distributed1
processing1
of1
large1
data1
sets.1
#
到目前为止,一切都很顺利。
现在,在原始流格式中将整个应用程序一起调出。
在清单8中,通过map脚本传递您的输入、排序输出(可选步骤)、然后通过reduce脚本传递由此产生的中间数据。
清单8.使用Linux管道的简单MapReduce
#catinput|rubymap.rb|sort|rubyreduce.rb
large1
of2
framework1
distributed1
data1
an1
the1
reduce1
map1
sets.1
Hadoop1
implementation1
for1
processing1
is1
#
回页首
使用Hadoop的Ruby
在shell环境中您的map和reduce脚本按预期工作,通过Hadoop将它们放入测试中。
我将会跳过Hadoop安装任务(参考本系列的用Hadoop进行分布式数据处理,第1部分:
入门或用Hadoop进行分布式数据处理,第2部分:
进阶以便建立Hadoop并使其运行)。
第一步将要在HDFS内为您的输入信息创建输入字典,然后提供一个将测试您脚本的简单文件。
清单9说明了此步骤(有关这些步骤的更多信息,请参考本系列的用Hadoop进行分布式数据处理,第1部分:
入门或用Hadoop进行分布式数据处理,第2部分:
进阶)。
清单9.为MapReduce过程创建输入数据
#hadoopfs-mkdirinput
#hadoopdfs-put/usr/src/linux-source-2.6.27/Documentation/memory-barriers.txtinput
#hadoopfs-lsinput
Found1items
-rw-r--r--1rootsupergroup780312010-06-0417:
36/user/root/input/memory-barriers.txt
#
下一步,使用流实用工具,通过自定义脚本来调用Hadoop,简化输出的输入数据和位置(请参考清单10)。
在此示例中请注意-file选项会简单地告诉Hadoop来打包您的Ruby脚本作为部分作业提交。
清单10.通过RubyMapReduce脚本使用Hadoop流
#hadoopjar/usr/lib/hadoop-0.20/contrib/streaming/hadoop-0.20.2+228-streaming.jar\
-file/home/mtj/ruby/map.rb-mapper/home/mtj/ruby/map.rb\
-file/home/mtj/ruby/reduce.rb-reducer/home/mtj/ruby/reduce.rb\
-inputinput/*-outputoutput
packageJobJar:
[/home/mtj/ruby/map.rb,/home/mtj/ruby/reduce.rb,/var/lib/hadoop-0.20/...
10/06/0417:
42:
38INFOmapred.FileInputFormat:
Totalinputpathstoprocess:
1
10/06/0417:
42:
39INFOstreaming.StreamJob:
getLocalDirs():
[/var/lib/hadoop-0.20/...
10/06/0417:
42:
39INFOstreaming.StreamJob:
Runningjob:
job_201006041053_0001
10/06/0417:
42:
39INFOstreaming.StreamJob:
Tokillthisjob,run:
10/06/0417:
42:
39INFOstreaming.StreamJob:
/usr/lib/hadoop-0.20/bin/hadoopjob...
10/06/0417:
42:
39INFOstreaming.StreamJob:
TrackingURL:
http:
//localhost:
50030/...
10/06/0417:
42:
40INFOstreaming.StreamJob:
map0%reduce0%
10/06/0417:
43:
17INFOstreaming.StreamJob:
map100%reduce0%
10/06/0417:
43:
26INFOstreaming.StreamJob:
map100%reduce100%
10/06/0417:
43:
29INFOstreaming.StreamJob:
Jobcomplete:
job_201006041053_0001
10/06/0417:
43:
29INFOstreaming.StreamJob:
Output:
output
#
最后,通过hadoop实用工具使用cat文件系统操作来探索输出(请参考清单11)。
Listing11.ExploringtheHadoopoutput
#hadoopfs-ls/user/root/output
Found2items
drwxr-xr-x-rootsupergroup02010-06-0417:
42/user/root/output/_logs
-rw-r--r--1rootsupergroup230142010-06-0417:
43/user/root/output/part-00000
#hadoopfs-cat/user/root/output/part-00000|head-12
+--->|4
immediate2
Alpha)1
enable1
_mandatory_1
Systems1
DMA.2
AMD641
{*C,*D},2
certainly2
back2
this23
#
在不到30行的脚本中,您已经在Hadoop框架内实现了map和reduce元素并演示了它们的执行。
虽然是一个简单的示例,但是通过自定义的和专有的算法说明了Hadoop背后真实的力量以及为什么Hadoop正在成为一种用于处理大型数据集的流行框架。
回页首
Hadoop的其他应用程序
Hadoop可用于许多应用程序上,其已超越了为大型数据集简单计算字数的工作。
所有这一切的需要就是用矢量格式表达Hadoop基础设施可以使用的数据。
虽然规范的示例使用矢量表达作为键和值,但是并没有限制您如何来定义值(例如一些值的汇总)。
在更加丰富的应用程序集中此灵活性可以为Hadoop创造新的机会。
一个一直适合MapReduce字数统计模型的有趣的应用程序正在把Web服务器访问的频率制表(在开创性Google文章中讨论)。
对于此应用程序来说,URL作为键来服务(从Web服务器访问日志摄取)。
reduce过程的结果是基于Web服务器日志的给定Web站点的每次URL访问的总数。
在计算机学习用户程序中,Hadoop已经作为处理大量GA个体的规模遗传算法的一种方法(潜在解决方案)。
map过程执行传统的遗传算法,从本地池中搜索最佳单个解决方案。
然后reduce应用程序成为来自map阶段的单个解决方案的集成。
这会允许单个节点识别最佳解决方案,然后允许这些解决方案在最适于生存的分布式显示的reduce阶段中相互竞争。
另外一个有趣的应用程序被创建用于识别僵尸网络的垃圾邮件。
此过程的第一步将会为减少垃圾邮件为目的而对电子邮件按来自给定组织而进行分类(基于一组指纹)。
根据过滤的这些数据,对以特定方式(例如参考电子邮件正文中的相同链接)连接的邮件生成一个图表。
然后这些相关电子邮件会减少至主机(静态或动态IP地址)以识别有问题的僵尸网络。
在应用程序之外通过map和reduce基元来查看世界,Hadoop作为在计算机集群之间分配工作的方式非常有用。
Map和reduce并非必须强制某种特定类型的应用程序。
相反地,Hadoop可以被视为一种可以同时将数据和算法分配到主机以获得更快速的并行处理速度的方法。
回页首
Hadoop应用程序生态系统
虽然Hadoop提供了一个灵活的架构,但也可以使用其他应用程序转换与其他应用程序的界面。
一个有趣的示例称为Hive,它是一个具有自己特定查询语言(称为HiveQL)的数据仓库基础结构。
Hive使得Hadoop更加熟悉结构化查询语言(SQL)背景,同时还支持传统的MapReduce基础结构来进行数据处理。
HBase是另外一种位于HDFS顶部的有趣的应用程序。
它是一个类似于GoogleBigTable的高性能数据库系统。
代替传统的文件处理,HBase使数据库将MapReduce处理的输入和输出格式列表。
最后,Pig是Hadoop中用于分析大型数据集的平台。
Pig提供可编译map和reduce应用程序的高级语言。
回页首
进一步的学习
这是Hadoop系列的最后一篇文章,探索了在适用于Hadoop框架的Ruby中开发map和reduce应用程序。
希望从这篇文章您可以看到Hadoop的真正力量。
虽然Hadoop将您限制在一个特定的编程模型中,但是这种模型是灵活的且可被应用到大量的应用程序上。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Hadoop 进行分布式数据处理第 部分 进行 分布式 数据处理