深入理解Hadoop集群和网络

Posted on

深入理解Hadoop集群和网络

原文出处: bradhedlund 译文出处: kickxxx

本文侧重于Hadoop集群的体系结构和方法,以及它与网络和服务器基础设施的关系。文章的素材主要来自于研究工作以及同现实生活中运行Hadoop集群客户的讨论。如果你也在你的数据中心运行产品级的Hadoop集群,那么我希望你能写下有价值的评论。

Hadoop集群部署时有三个角色:Client machines、 Master nodes和Slave nodes。

Master nodes负责Hadoop的两个关键功能:数据存储(HDFS);以及运行在这个数据之上的并行计算,又称为Map-Reduce。Name node负责调度数据存储,而Job Tracker则负责并行数据处理的调度(使用Map-Reduce技术)。Slave nodes由大量的机器组成,完成数据存储以及运行计算这样的脏活。每个slave node都运行Data node和Task Tracker daemon,这些slave daemon和master nodes的相应daemon进行通信。Task tracker daemon由Job Tracker管理,Data node Daemon由Name node管理。

Client机器包含了Hadoop集群的所有设置,但是它既不是Master也不是Slave。Client的角色是向集群保存数据,提交Map-Reduce jobs(描述如何处理数据),获取查看MR jobs的计算结果。在小型集群中(40节点)你可能会发现一个物理机器扮演多个角色,比如既是Job Tracker又是Name node,在中等或者大规模集群中,一般都是用独立的服务器负责单独的角色。

在真正的产品集群中,不存在虚拟服务器和虚拟机平台,因为他们仅会导致不必要的性能损耗。Hadoop最好运行在linux机器上,直接工作于底层硬件之上。换句话说,Hadoop可以工作在虚拟机之上,对于学习Hadoop是一个不错的廉价方法,我本身就有一个6-node的Hadoop cluster运行Windows 7 laptop的VMware Workstation之上

上图是Hadoop集群的典型架构。机架服务器(不是刀锋服务器)分布在多个机架中,连接到一个1GB(2GB)带宽的机架交换机,机架交换机连接到上一层的交换机,这样所有的节点通过最上层的交换机连接到一起。大部分的服务器都是Slave nodes配置有大的磁盘存储 中等的CPU和DRAM,少部分是Master nodes配置较少的存储空间 但是有强大的CPU和大DRAM

本文中,我们不讨论网络设计的各种细节,而是把精力放在其他方面。首先我们看下应用的工作流程。

为什么会出现Hadoop? 它又解决了什么问题? 简单的说,是由于商业和政府有大量的数据需要快速分析和处理,如果我们把这些巨大的数据切分为小的数据块分散到多台计算机中,并且用这些计算机并行处理分配给他们的小块数据,可以快速的得到结果,这就是Hadoop能做的事情。

在我们的简单例子中,我们有一个大文件保存着所有发给客户服务部分的邮件,想要快速统计单词”Refund”被输入了多少次,这个结果有助于评估对退换货部门的需求,以指定相应对策。这是一个简单的单词计数练习。Client上传数据到集群(File.txt),提交一个job来描述如何分析数据,集群存储结果到一个新文件(Result.txt),然后Client读取结果文件。

没有加载数据,Hadoop集群就没有任何用途。所以我们首先从加载大文件File.txt到集群中以便处理。目标是能够快速并行处理许多数据,为了达到这个目的需要尽可能多的机器能够同时操纵文件数据。Client把数据文件切分成许多小blocks,然后把他们分散到集群的不同机器上。块数越多,用来处理这些数据的机器就越多。同时这些机器一定会失效,所以要确保每个数据块保存到多个机器上以防止数据丢失。所以每个数据块在存入集群时会进行复制。Hadoop的标准设定是集群中的每个block有三份copy,这个配置可以由hdfs-site.xml的dfs.replication 参数设置

Client把文件File.txt分成3块,对于每一块,Client和Name node协商获取可以保存它以及备份块的Data nodes列表。Client然后直接写block数据到Data node,Data node负责写入数据并且复制copy到其他的Data nodes。重复操作,直到所有的块写完。Name node本身不参与数据保存,Name node仅仅提供文件数据位置以及数据可用位置(文件系统元数据)

Hadoop引入了Rack Awareness的概念。作为Hadoop系统管理员,你能够手动定义集群中每一个slave Data node的rack号。为什么要把自己置于这种麻烦呢?有两个关键的原因:数据丢失和网络性能。记住每一个数据块都会被复制到多台Data node上,以防止某台机器失效导致数据丢失。有没有可能一份数据的所有备份恰好都在同一个机架上,而这个机架又出现了故障,比如交换机失效或者电源失效。为了防止这种情况,Name node需要知道Data nodes在网络拓扑中的位置,并且使用这个信息决定数据应该复制到集群的什么位置。

我们还假定同一机架的两台机器间相比不同机架的两台机器间 有更高的带宽和更低的网络延迟,在大部分情况下是正确的。机架交换机的上行带宽通常小于下行带宽。此外,机架内延迟通常低于机架间延迟。如果上面的假定成立,那么采用Rack Awareness既可以通过优化位置保护数据,同时提升网络性能,岂不是太cool了。是的,的确是这样,非常cool,对不对。

别急,Not cool的是Rack Awareness是需要手工定义的,并且要持续的更新它,并且保证这个信息精确。如果机架交换机可以自动提供它下面的Data node列表给Name node,那就更cool了。或者如果Data nodes可以自动告知Name node他们属于哪个交换机,一样很cool.

此外,让人感兴趣的是OpenFlow 网络,Name node可以请求OpenFlow控制器关于节点位置的拓扑情况。

Client准备写文件File.txt到集群时,把文件划分为块,块A为第一个块。Client向Name node申请写文件File.txt,从Name node获得许可,并且接收到一个Data nodes列表(3个表项),每一个Data nodes用来写入块A的一个copy。Name node使用Rack Awareness来决定这个Data nodes列表。规则是:对于每一个数据块,两个 copy存放在一个机架上,另外一个copy存放在另外一个机架上。

在Client写Block A之前,它要知道准备接受”Block A“ copy的Data nodes是否以及做好了准备。首先,Client选择list中的第一个节点Data Node1,打开一个TCP50010链接然后请求:“hey,准备接受一个block,这是一个Data nodes列表(2个表项),Data node5和Data node6”,请确保他们两个也准备好了“;于是Data Node1打开一个到Data node5的TCP500100连接然后说:”Hey,准备接受一个block,这是一个Data nodes列表(1个表项),Data node6”,请确保他准备好了“;Data Node5同样会问Data Node6:“Hey, 准备好接收一个block吗“

”准备就绪“的响应通过已经创建好的TCP pipeline传回来,直到Data Node1发送一个”Ready”给Client。现在Client可以开始写入数据了。

写入数据的过程中,在涉及写操作的Data nodes之间创建一个复制pipeline。也就是说一个数据节点接收数据的同时,同时会把这份数据通过pipeline push到下一个Node中。

从上图可以看到,Rack Awareness起到了改善集群性能的做用。Data node5和Data node6在同一个机架上,因此pipeline的最后一步复制是发生在机架内,这就受益于机架内带宽以及低延迟。在Data node1, Data node5, Data node6完成block A之前,block B的操作不会开始。

当三个Nodes成功的接收到Block A后,挥发送”Block received”报告给Name node,同时发送”Success”到pipeline中,然后关闭TCP事务。Client在接收到Success信息后,通知Name node数据块已经成功的写入。Name node更新File.txt中Block A的metadata信息(包含Name locations信息)

Client现在可以开始Block B的传输了

随着File.txt的块被写入,越来越多的Data nodes涉及到pipeline中,散落到机架内的热点,以及跨机架的复制

Hadoop占用了很多的网络带宽和存储空间。Hadoop专为处理大文件而生,比如TB级尺寸的文件。每一个文件在网络和存储中都被复制了三次。如果你有一个1TB的文件,那么将消耗3TB的网络带宽,同时要消耗3TB的磁盘空间存贮这个文件。

随着每块的复制pipeline的完成,文件被成功的写入集群。文件散落在集群内的机器上,每个机器保存文件的一小部分数据。组成文件的块数目越多,数据散落的机器就越多,将来更多的CPU和磁盘驱动器就能参与到并行处理中来,提供更强大更快的处理能力。这也是建造巨大集群的原动力。当机器的数变多,集群则变得wide,网络也相应的需要扩展。

扩展集群的另外一种方法是deep扩展。就是维持机器数据不便,而是增加机器的CPU处理能力和磁盘驱动器的数目。在这种情况下,需要提高网络的I/O吞吐量以适应增大的机器处理能力,因此如何让Hadoop集群运行10GB nodes称为一个重要的考虑。

Name node保存集群内所有文件的metadata,监督Data nodes的健康以及协调数据的存取。Name node是HDFS的控制中心。它本身并不保存任何cluster data。Name node知道一个文件由哪些块组成以及这些块存放在集群内的什么地方。Name node告诉Client需要和哪些Data node交互,管理集群的存储容量,掌握Data node的健康状况,确保每一个数据块都符合系统备份策略。

Data node每3秒钟发送一个heartbeats给Name node ,二者使用TCP9000端口的TCP握手来实现heartbeats。每十个heartbeats会有一个block report,Data node告知它所保存的数据块。block report使得Namenode能够重建它的metadata以确保每个数据block有足够的copy,并且分布在不同的机架上。

Name node是Hadoop Distributed File System(HDFS)的关键部件。没有Name node,clients无法从HDFS读写数据,也无法执行Map Reduce jobs。因此Name node 最好配置为一台高冗余的企业级服务器:双电源,热插拔风扇,冗余NIC连接等。

如果Name node收不到某Data node的heartbeats,那么Name node假定这个Data node死机并且Data node上的所有数据也丢失了。通过这台dead Data node的block report,Name node知道哪些block copies需要复制到其他Data nodes。Name node参考Rack Awareness数据来选择接收新copy的Data node,并遵守以下复制规则:一个机架保存两份copies,另一个机架保存第三份copy。

考虑由于机架交换机或者机架电源失败导致的整个机架Data node都失效的情况。Name node将指导集群内的剩余Data nodes开始复制失效机架上的所有数据。如果失效机架上服务器的存储容量为12TB,那么这将导致数百TB的数据在网络中传输。

Secondary Name node是Hadoop的一种服务器角色。一个很普遍的误解是它提供了对Name node的高可用性备份,实际上不是。

Secondary Name node偶尔会连接到Name node(缺省为每小时),同步Name node in-memory metadata以及保存metadata的文件。Secondary Name node合并这些信息到一个组新的文件中,保存到本地的同时把这些文件发送回Name Node。

当Name node宕机,保存在Secondary Name node中的文件可以用来恢复Name node。在一个繁忙的集群中,系统管理员可以配置同步时间为更小的时间间隔,比如每分钟。

当一个Client想要从HDFS获取一个文件时,比如job的输出结果。Client首先从Name node查询文件block的位置。Name node返回一个包含所有block位置的链表,每个block位置包含全部copies所在的Data node

Client选取一个数据块的Data node位置,通过TCP50010端口从这个Data node读取一块,在读取完当前块之前,Client不会处理下一块。

在某些情况下Data node daemon本身需要从HDFS读取数据块。比如Data Node被请求处理自身不存在的数据,因而它必须从网络上的其他Data node获得数据然后才能开始处理。

另外一种情况是Name node的Rack Awareness信息提供的网络优化行为。当Data node向Name node查询数据块位置信息,Name node优先查看请求者所在的机架内的Data nodes包含这个数据块。如果包含,那么Name node把这个Data node提供给请求的Data node。这样可以保证数据仅在in-rack内流动,可以加快数据的处理速度以及job的完成速度

现在File.txt分散到集群的机器中这样就可以提供更快更有效的并行处理速度。Hadoop并行处理框架称为Map Reduce,名称来自于并行处理的两个重要步骤:Map和Reduce

第一步是Map 过程,这个步骤同时请求所有包含数据的Data node运行计算。在我们的例子中则是请求这些Data node统计存储在他们上的File.txt数据块包含多少此Refund

要达到这个目的,Client首先提交Map Reduce job给Job tracker,发送请求:“How many times does Refund occur in file.txt”。Job tracker向Name node查询哪些Data nodes包含文件File.txt的数据块。然后Job Tracker在这些Data nodes上运行Java代码 在Data node的本地数据上执行Map计算。Task Tracker启动一个Map task监测这些tasks的执行。Task Tracker通过heartbeats向Job Tracker汇报task的状态。

当每一个Map task都完成后,计算结果保存在这些节点的临时存储区内,我们称之为”intermediate data”。下一步是把这些中间数据通过网络发送给运行Reduce的节点以便完成最后的计算。

Job tracker总是尝试选择包含待处理数据的Data node做Map task,但是有时不会这样。比如,所有包含这块数据的Data node已经有太多的tasks正在运行,不再接收其他的task.

这种情况下,Job Tracker将询问Name node,Name node会根据Rack Awareness建议一个in-rack Data node。Job tracker把task分配给这个in-rack Data node。这个Data node会在Name node的指导下从包含待处理数据的in-rack Data node获取数据。

Map Reduce 框架的第二部分叫做Reduce。Map task已经完成了计算,计算结果保存在intermediate data。现在我们需要把所有的中间数据汇集到一起作进一步处理得到最终结果。

Job Tracker可以在集群内的任意一个node上执行Reduce,它指导Reduce task从所有完成Map trasks的Data node获取中间数据。这些Map tasks可能同时响应Reducer,这就导致了很多nodes几乎同时向单一节点发起TCP连接。我们称之为incast或者fan-in(微突发流)。如果这种微突发流比较多,那么就要求网络交换机有良好的内部流量管理能力,以及相应的buffers。这种间歇性的buffers使用可能会影响其他的网络行为。这需要另开一篇详细讨论。

Reducer task已经收集了所有intermediate data,现在可以做最后计算了。在这个例子中,我们只需简单的把数字相加就得到了最终结果,写入result.txt

我们的这个例子并没有导致很多的intermediate data在网络间传输。然而其他的jobs可能会产生大量的intermediate data:比如,TB级数据的排序,输出的结果是原始数据集的重新排序,结果尺寸和原始文件大小一致。Map Reduce过程会产生多大的网络流量王权依赖于给定的Job类型。

如果你对网络管理很感兴趣,那么你将了解更多Map Reduce和你运行集群的Jobs类型,以及这些Jobs类型如何影响到网络。如果你是一个Hadoop网络的狂热爱好者,那么你可能会建议写更好的Map Reduce jobs代码来优化网络性能,更快的完成Job

Hadoop通过在现有数据的基础上提供某种商业价值,从而在你的组织内获得成功。当人们意识到它的价值,那么你可能获得更多的资金购买更多的机架和服务器,来扩展现有的Hadoop集群。

当增加一个装满服务器的新机架到Hadoop集群中时,你可能会面临集群不平衡的局面。在上图的例子中,Rack1和Rack2是已经存在的机器,保存着文件File.txt并且正在运行Map Reduce jogs。当我们增加两个新的机架到集群中时,File.txt 数据并不会神奇的自动散布到新的机架中。

新的Data node服务器由于没有数据只能空闲着,直到Client开始保存新的数据到集群中。此外当Rack1和Rack2上的服务器都满负荷的工作,那么Job Tracker可能没有别的选择,只能把作用在File.txt上的Map task分配到这些没有数据的新服务器上,新服务器需要通过网络跨机架获取数据。这就导致更多的网络流量,更慢的处理速度。

为了处理这种情况,Hadoop包含一个时髦的工具叫做 balancer

Balancer查看节点可用存储的差异性,在达到特定的阀值后尝试执行balance。有很多空闲空间的新节点将被检测到,然后balancer开始从空闲空间很少的Data node拷贝数据到这个新节点。Balancer通过控制台的命令行启动,通过控制台取消或者关闭balancer

Balancer可用的网络流量是非常低的,缺省设置为1MB/s。可以通过hdfs-site.xml的df.balance.bandwidthPerSec参数来修改。

Balancer是你的集群的好管家。在你增加服务器时一定会用到它,定期(每周)运行一次也是一个好主意。Balancer使用缺省带宽可能会导致很长时间才能完成工作,比如几天或者几周。

本文是基于Training from Cloudera 的学习 以及对我的Hadoop实验环境的观测。这里讨论的内容都是基于latest stable release of Cloudera’s CDH3 distribution of Hadoop 。本文并没有讨论Hadoop的新技术,比如:Hadoop on Demand(HOD)HDFS Federation ,但是这些的确值得花时间去研究。 1 vote, average: 5.00 out of 51 vote, average: 5.00 out of 51 vote, average: 5.00 out of 51 vote, average: 5.00 out of 51 vote, average: 5.00 out of 5 (*1 个评分,平均: 5.00*)

Loading ... Loading ...

很靠谱linux常用命令

Posted on

很靠谱linux常用命令

vim是打开vim编辑器,别的编辑器还有vi(功能没有vim 强大),nano,emacs等等,感觉还是vim最强大,其次是vi,别的就要差一些了。 我听我们老师说,用图形界面本身已经会被高手笑了,如果打开一个gpedit或者kwrite那就废了...... 常用的命令 ls,列出当前目录下的文件,ls -l是列出详细信息,ls -a列出隐藏文件。 cd,更改目录。clear,清屏命令。reset,重置终端。 startx,启动图形界面。fdisk -l,查看硬盘分区。 ps aux,列出系统进程。cat,显示文本。tac,逆序显示文本。 od,二进制格式显示文本。wc,判断文件的大小行数和字符数等等。 aspell,检查文件中的拼写错误。less,分页读取文件。more,与less类似,但是功能不及less。 reboot,重启系统。poweroff,关机。halt,也是关机,但是需要手动切断电源,不推荐使用。shutdown -h now,立即关机,后面的now可以替换成时间,可以指定关机时间的指令,据说良好的系统管理员应该使用这个命令。shutdown -r now,与上一条类似,只不过是重启。sync,同步硬盘数据,重启或关机前应该多次使用。 locate,查询文件位置,每隔一段时间应该使用updatedb命令以提供搜索范围。find,强大的查询命令,参数众多。find / -name /,这是查询/下所有文件的意思。 whereis,我用他来判断命令的所在位置,如whereis ls。 sudo,在普通帐户的情况下使用root权限,不过需要修改/etc/sudoers文件才可以。 mv,移动文件或者重命名。mv /etc// /home/tom,是将/etc所有文件移动到tom目录下的意思。mv a b,把a重命名为b.当然,这只是个例子,具体操作的时候需要看具体情况进行判定。 cp,于mv类似,也是相同的格式,只不过不是移动,是复制。如果复制的是目录的话,需使用-r参数,cp -r ///. rm,这是删除指令,与cp类似,删除目录添加-r,提示删除使用-i useradd,添加一个新帐户。userdel,删除一个帐户。 passwd,为一个帐户设置密码。都有许多参数来实现其他功能。 chown,更改文件所属。如chown tom.tom 文件名,将文件改为所属组tom,所属者也是tom。 chmod,更改文件的权限,只说简单的改法,chmod 777 文件名,文件将有所有的权限。 chkconfig --list,用来观察服务状态,chkconfig --level ? 服务名 on/off,打开或者关闭服务,?代表运行级别。 init (1,2,3,4,5,6)用来在6个运行级别切换。 runlevel查看现在的运行级别。 bc,一个计算器。date,显示时间。cal显示日历。 如果是redhat的话,还有setup,用来设置一些系统相关,ntsysv,专门用来设置服务,这样就不用chkconfig了。 tr,压缩或者替换字符。dh,计算目录的大小。df,显示文件系统的信息。 free,显示内存cpu的时用情况。top,动态观察进程。 tar -czvf,创建/.tar.gz压缩包,tar -xzvf,解压这种压缩包。 tar -cjvf,创建的是/*.tar.bz2,解压是tar -xjvf rpm -ivh,安装rpm包,rpm -e卸载rpm包 who,观察登录情况。whoami,who am i,两条命令有一些区别,不过差不多。id,用来查看帐户的信息。w,也是查看登录情况的,更加详细。 echo,用来显示环境变量等等,例子echo $LANG。 history,显示命令历史。mount挂在设备。umount,卸载设备。dmesg,显示启动信息。yum,更新时用的命令。 ssh,ssh登录。telnet,telnet登录。还有ftp命令。 gcc,g++,java,javac,都是编程用的命令。make,如果有makefile的话,可以用他编译。

基于Hadoop 2.2.0的高可用性集群搭建步骤(64位)

Posted on

基于Hadoop 2.2.0的高可用性集群搭建步骤(64位)

内容概要: CentSO_64bit集群搭建, hadoop2.2(64位)编译,安装,配置以及测试步骤

新版亮点:基于yarn计算框架和高可用性DFS的第一个稳定版本。

注1:官网只提供32位release版本, 若机器为64位,需要手动编译。

注2:目前网上传的2.2版本的安装步骤几乎都有问题,没有一个版本是完全正确的。若不懂新框架内部机制,不要照抄网传的版本。

0. 编译前的准备

虚拟机vmware准备,64bit CentOS准备

节点ip

cluster1 172.16.102. 201

cluster2 172.16.102. 202

cluster3 172.16.102. 203

cluster4 172.16.102. 204

各节点职能划分

cluster1 resourcemanager, nodemanager,

proxyserver,historyserver, datanode, namenode,

cluster2 datanode, nodemanager

cluster3 datanode, nodemanager

cluster4 datanode, nodemanager

说明

以下关于修改hostname, 设置静态ip, ssh免登陆,关闭防火墙等步骤,放在文章末尾,这些内容并不是本文讨论的重点。

1. hadoop2.2**编译** 1说明:标准的

bash

提示符,root用户为

'/#'

,普通用户为

'%'

,由于博客编辑器的缘故,

'/#'

提示符会被默认为comment, 因此在这篇博文中不再区分root和普通user的提示符, 默认全部为

'$'

因为我们安装的CentOS是64bit的,而官方release的hadoop2.2.0版本没有对应的64bit安装包,故需要自行编译。

首先需要去oracle下载64位jdk: 1

2 $

su

root

$wget http:

//download

.oracle.com

/otn-pub/java/jdk/7u45-b18/jdk-7u45-linux-x64

.

tar

.gz

注: prompt(提示符)为%默认为当前用户, /#则为root,注意以下各步骤中的prompt类型。

下面为hadoop编译步骤(注:中间部分的文本框里内容提要只是一些补充说明,不要执行框里的命令)

1.1 BOTPROTO改为”dhcp” 1

2 $

su

root

$

sed

–i s

/static/dhcp/g

/etc/sysconfig/network-scripts/ifcfg-eth0

/#servicenetwork restart

1.2 下载hadoop2.2.0 源码

1

2 3$

su

grid

$

cd

~ wget http:

//apache

.dataguru.cn

/hadoop/common/stable/hadoop-2

.2.0-src.

tar

.gz

1.3 安装maven

1

2 3

4 5$

su

root

$

cd

/opt wget http:

//apache

.fayea.com

/apache-mirror/maven/maven-3/3

.1.1

/binaries/apache-maven-3

.1.1-bin.

tar

.gz

$

tar

zxvf apache-maven-3.1.1-bin.

tar

.gz $

cd

apache-maven-3.1.1

**修改系统环境变量有两种方式,修改/etc/profile, 或者在/etc/profile.d/下添加定制的shell文件,

鉴于profile文件的重要性,尽量不要在profile文件里添加内容,官方建议采用第二种,以保证profile文件的绝对安全。

下面采用第二种方式:

首先,创建一个简单shell脚脚本并添加相关内容进去: 1

2 $

cd

/etc/profile

.d/

$

touch

maven.sh 其次,maven.sh里添加内容如下:1

2 3/#environmentvariable settings for mavn2

export

MAVEN_HOME=

'/opt/apache-maven-3.1.1'

3 export

PATH=$MAVEN_HOME

/bin

:$PATH

最后,source一下

1$

source

/etc/profile



$

source

/etc/profile1

2 3<em

id

=

"__mceDel"

$mvn -version

Apache Maven 3.1.1 <

/em

>

1.4 安装protobuf

注意apache官方网站上的提示“NOTE: You will need protoc 2.5.0 installed.” 1

2 3

4 5

6 $

su

root

$

cd

/opt wget https:

//protobuf

.googlecode.com

/files/protobuf-2

.5.0.

tar

.bz2

$

tar

xvf protobuf-2.5.0.

tar

.bz2 (注意压缩文件后缀, maven安装包是—

gzip

文件,解压时需加–z) $

cd

protobuf-2.5.0

.

/configure

安装protobuf时提示报错”configure: error: C++ preprocessor "/lib/cpp" failssanity check”

安装gcc 1$yum

install

gcc

1.5 编译hadoop

首先从官网下载hadoop2.2.0source code: 1

2 3$

su

grid;

$

cd

~grid/ wget http:

//apache

.dataguru.cn

/hadoop/common/stable/hadoop-2

.2.0-src.

tar

.gz

好了,痛苦的编译过程来了。

解压之: 1

2 $

tar

zxvf hadoop-2.2.0-src.

tar

.gz

$

cd

hadoop-2.2.0-src

1.6 给maven指定国内镜像源

1.6.1. 切换root权限, 修改/opt/apache-maven-3.1.1/conf/settings.xml 1

2 $

su

root

$vim

/opt/apache-maven-3

.1.1

/conf/settings

.xml

修改1. 在里添加国内源(注意,保留原本就有的...):

复制代码 1 2 3 nexus-osc4 /*5 Nexusosc6 http://maven.oschina.net/content/groups/public/7 8

复制代码

修改2. 在标签中增加以下内容(保留原来的, jdk版本根据用户的情况填写)

复制代码 1 2 jdk-1.4 3 4 1.4 5 6 7 8 nexus 9 local private nexus10 http://maven.oschina.net/content/groups/public/11 12 true13 14 15 false16 17 18 19 20 21 nexus22 local private nexus23 http://maven.oschina.net/content/groups/public/24 25 true26 27 28 false29 30 31 32 33

复制代码

1.6.2 将刚才修改的配置文件拷到当前用户home目录下

复制代码 $ su grid $ sudo cp /opt/apache-maven-3.1.1/conf/settings.xml ~/.m2//#若提示该用户不在sudoers里,执行以下步骤: $ su root /#在sudoers里第99行添加当前用户(下面行号不要加): $ cat /etc/sudoers98 root ALL=(ALL) ALL99 grid ALL=(ALL) ALL

复制代码

1.7 现在执行官方的clean步骤: $mvn clean install –DskipTests

漫长的等待后发现安装一切正常。

1.8 安装3个依赖包 1

2 3Cmake

ncurses-devel openssl-devel

执行以下步骤:

1

2 3

4 $

su

root

$yum

install

ncurses-devel $yum

install

openssl-devel

$yum

install

cmake89

以上安装完成后,切回用户grid:

1

2 $

su

grid

$

cd

~

/hadoop-2

.2.0-src

**1.9 所有依赖已安装完毕,开始编译

1$mvn package-Pdist,native -DskipTests -Dtar

漫长的等待后,编译成功,查看结果:

一切正常。至此,hadoop2.2.0编译完成。

**1.10 验证

下面验证编译结果是否符合预期, 注意我们当前是在目录~/hadoop-2.2.0-src下, 1

2 3$

cd

hadoop-dist/

$

ls pom.xml target

以上为maven编译的配置文件

1

2 3

4 5

6 7$

cd

target

$

ls

-sF total 276M

4.0K antrun/ 92M hadoop-2.2.0.

tar

.gz 4.0K maven-archiver/ 4.0K dist-layout-stitching.sh 4.0K hadoop-dist-2.2.0.jar 4.0K

test

-

dir

/

4.0K dist-

tar

-stitching.sh 184M hadoop-dist-2.2.0-javadoc.jar 4.0K hadoop-2.2.0/ 4.0K javadoc-bundle-options/

以上为maven编译后自动生成的目录文件,进入hadoop-2.2.0:

1

2 3$

cd

hadoop-2.2.023

$

ls bin etc include lib libexec sbin share

这才是和官方release2.2.0版本(官方只有32bit版本)的相同的目录结构。

1.10.1 下面主要验证两项:

**a.验证版本号 1

2 3

4 5

6 7$bin

/hadoop

version

Hadoop 2.2.0 Subversion Unknown -r Unknown

Compiled by grid on 2013-11-06T13:51Z Compiled with protoc 2.5.0

From

source

with checksum 79e53ce7994d1628b240f09af91e1af4 This

command

was run using

/home/grid/hadoop-2

.2.0-src

/hadoop-dist/target/hadoop-2

.2.0

/share/hadoop/common/hadoop-common-2

.2.0.jar

可以看到hadoop版本号,编译工具(protoc2.5.0版本号与官方要求一致)以及编译日期.

**b.验证hadoop lib的位数 1

2 3

4 5

6 $

file

lib

//native/

/*

lib

//native/libhadoop

.a: current ar archive lib

//native/libhadooppipes

.a: current ar archive

lib

//native/libhadoop

.so: symbolic link to `libhadoop.so.1.0.0' lib

//native/libhadoop

.so.1.0.0:ELF 64-bitLSB<

/strong

shared object, x86-64, version 1 (SYSV), dynamically linked, notstripped1011 lib

//native/libhadooputils

.a: current ar archive1213 lib

//native/libhdfs

.a: current ar archive1415 lib

//native/libhdfs

.so: symbolic link to `libhdfs.so.0.0.0'

lib

//native/libhdfs

.so.0.0.0: ELF 64-bit LSB shared object<

/strong

, x86-64,version 1 (SYSV), dynamically linked, not stripped

看到黑色的“ELF-64bit LSB”证明64bit hadoop2.2.0初步编译成功,查看我们之前的hadoop0.20.3版本,会发现lib//native/libhadoop.so.1.0.0是32bit,这是不正确的!。^_^

2. hadoop2.2**配置**

**2.1 home设置**

为了和MRv1区别, 2.2版本的home目录直接命名为yarn: 1

2 3

4 $

su

hadoop

$

cd

~ $

mkdir

–p yarn

/yarn_data67

$

cp

–a ~hadoop

/hadoop-2

.2.0-src

/hadoop-dist/target/hadoop-2

.2.0 ~hadoop

/yarn

2.2 环境变量设置

~/.bashrc里添加新环境变量:

1

2 3

4 5

6 7

8 9

10 11

12 /# javaenv

export

JAVA_HOME=

"/usr/java/jdk1.7.0_45"

exportPATH=

"$JAVA_HOME/bin:$PATH" /# hadoopvariable settings

export

HADOOP_HOME=

"$HOME/yarn/hadoop-2.2.0" export

HADOOP_PREFIX=

"$HADOOP_HOME/"

export

YARN_HOME=$HADOOP_HOME export

HADOOP_MAPRED_HOME=

"$HADOOP_HOME"

export

HADOOP_COMMON_HOME=

"$HADOOP_HOME" export

HADOOP_HDFS_HOME=

"$HADOOP_HOME"

export

HADOOP_CONF_DIR=

"$HADOOP_HOME/etc/hadoop/" export

YARN_CONF_DIR=$HADOOP_CONF_DIR

export

PATH=

"$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH"

以上操作注意2点:

  1. jdk一定要保证是64bit的

2.HADOOP_PREFIX极其重要,主要是为了兼容MRv1,优先级最高(比 如寻找conf目录,即使我们配置了HADOOP_CONF_DIR,启动脚本依然会优先从$HADOOP_PREFIX/conf/里查找),一定要保 证此变量正确配置(也可不设置,则默认使用HADOOP_HOME/etc/hadoop/下的配置文件)

**2.3 改官方启动脚本的bug**

**说明:此版本虽然是release稳定版,但是依然有非常弱智的bug存在。

正常情况下,启动守护进程$YARN_HOME/sbin/hadoop-daemons.sh中可以指定node.

我们看下该启动脚本的说明: 1

2 $sbin

/hadoop-daemons

.sh

Usage:hadoop-daemons.sh [--config confdir] [--hosts hostlistfile] [start|stop]

command

args...

可以看到--hosts可以指定需要启动的存放节点名的文件名:

但这是无效的,此脚本调用的$YARN_HOME/libexec/hadoop-config.sh脚本有bug.

先建一个文件datanodefile 添加datanode节点,放入conf/文件夹下,然后执行一下启动脚本: 1

2 $sbin

/hadoop-daemons

.sh --hosts datanodefile start datanode

at:

/home/grid/yarn/hadoop-2

.2.0

/etc/hadoop//126571

:No such

file

or directory

分析脚本,定位到嵌套脚本$YARN_HOME/libexec/hadoop-config.sh第96行:

196

export

HADOOP_SLAVES=

"${HADOOP_CONF_DIR}/$$1"

看到红色部分是不对的,应该修改为:

196

export

HADOOP_SLAVES=

"${HADOOP_CONF_DIR}/$1"

备注1:此版本11月初发布至今,网上教程不论中文还是英文,均未提及此错误。

备注2:$YARN_HOME/libexec/hadoop-config.sh中分析hostfile的逻辑非常脑残: 1

2 3

4 593

if

[

"--hosts"

=

"$1"

]

94

then 95

shift

96

export

HADOOP_SLAVES=

"${HADOOP_CONF_DIR}/%$1" 97

shift

因此,用户只能将自己的hostfile放在${HADOOP_CONF_DIR}/ 下面,放在其它地方是无效的。

备注3:按照$YARN_HOME/libexec/hadoop-config.sh脚本的逻辑,还有一种方式指定host 1$hadoop-daemons.sh –hostnames cluster1 start datanode

注意,因为bash脚本区分输入参数的分割符为\t或\s,所以限制了此种方式只能指定一个单独的节点

总结以上分析和修改步骤: 1

2 3

4 5$

cd

$YARN_HOME

/libexec/

$vim hadoop-config.sh /#修改第96行代码为:

export

HADOOP_SLAVES=

"${HADOOP_CONF_DIR}/$1" /#保存退出vim

**2.4 配置文件设置**

复制代码 1 2 3 <?xml version="1.0"?> 4 <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> 5 6 7 8 fs.defaultFS 9 hdfs://cluster1:900010 11 12 13 hadoop.tmp.dir14 /home/grid/hadoop-2.2.0-src/hadoop-dist/target/hadoop-2.2.0//yarn_data/tmp/hadoop-grid15 16 17 备注1:注意fs.defaultFS为新的变量,代替旧的:fs.default.name18 19 备注2:tmp文件夹放在我们刚才新建的$HOME/yarn/yarn_data/下面。20 21 22 23 24 dfs.replication25 326 27

复制代码

**备注1. 新:dfs.namenode.name.dir,旧:dfs.name.dir,新:dfs.datanode.name.dir,旧:dfs.data.dir

**备注2. dfs.replication确定 data block的副本数目,hadoop基于rackawareness(机架感知)默认复制3份分block,(同一个rack下两个,另一个rack下一 份,按照最短距离确定具体所需block, 一般很少采用跨机架数据块,除非某个机架down了)

复制代码 1 2 3 4 5 yarn.nodemanager.aux-services 6 mapreduce_shuffle 7 8 9 10 yarn.resourcemanager.address11 cluster1:803212 13 14 15 yarn.resourcemanager.resource-tracker.address16 cluster1:803117 18 19 20 yarn.resourcemanager.admin.address21 cluster1:803322 23 24 25 yarn.resourcemanager.scheduler.address26 cluster1:803027 28 29 30 yarn.nodemanager.loacl-dirs31 /home/grid/hadoop-2.2.0-src/hadoop-dist/target//hadoop-2.2.0/yarn_data/mapred/nodemanager32 true33 34 35 36 yarn.web-proxy.address37 cluster1:888838 39 40 41 yarn.nodemanager.aux-services.mapreduce.shuffle.class42 org.apache.hadoop.mapred.ShuffleHandler43 44

复制代码

在此特意提醒:

(1) 目前网上盛传的各种hadoop2.2的基于分布式集群的安装教程大部分都是错的,hadoop2.2配置里最重要的也莫过于yarn-site.xml里的变量了吧?

(2)不同于单机安装,基于集群的搭建必须设置

yarn-site.xml可选变量yarn.web-proxy.address 和

yarn.nodemanager.loacl-dirs 外的其它所有变量!后续会专门讨论yarn-site.xml里各个端口配置的含义。

复制代码 1 2 3 4 5 mapreduce.framework.name6 yarn7 8

复制代码

备注1:新的计算框架取消了实体上的jobtracker, 故不需要再指定mapreduce.jobtracker.addres,而是要指定一种框架,这里选择yarn. 备注2:hadoop2.2.还支持第三方的计算框架,但没怎么关注过。 配置好以后将$HADOOP_HOME下的所有文件,包括hadoop目录分别copy到其它3个节点上。

2.5**各节点功能规划**

确保在每主机的/etc/hosts里添加了所有node的域名解析表(i.e.cluster1 198.0.0.1);iptables已关闭;/etc/sysconfig/network-script/ifcfg-eth0里 BOTPROTO=static;/etc/sysconfig/network文件里已设置了各台主机的hostname, 静态ip地址,且已经重启过每台机器;jdk和hadoop都为64bit;ssh免登陆已配置;完成以上几项后,就可以启动hadoop2.2.0了。

注意到从头到尾都没有提到Master, Slave,也没有提到namenode,datanode,是因为,新的计算框架,新的hdfs中不存在物理上的Master节点,所有的节点都是等价的。

各节点职能划分在篇首已有说明, 在此重提一下: 1

2 3

4 cluster1 resourcemanager, nodemanager, proxyserver,historyserver, datanode, namenode,

cluster2 datanode, nodemanager cluster3 datanode, nodemanager

cluster4 datanode, nodemanager

2.6 hdfs 格式化

1$bin

/hdfs

namenode –

format

(注意:hadoop 2.2.0的格式化步骤和旧版本不一样,旧的为 $YARN_HOME/bin/hadoop namenode –format)

2.7 hadoop整体启动

**启动方式(1)分别登录各自主机开启

在cluster1节点上,分别启动resourcemanager,nodemanager, proxyserver, historyserver, datanode, namenode,

在cluster2, cluster3, cluster4 节点主机上,分别启动datanode,nodemanager

备注:如果resourcemanager是 独立的,则除了resourcemanager,其余每一个节点都需要一个nodemanager,我们可以在$YARN_HOME/etc /hadoop/下新建一个nodehosts, 在里面添加所有的除了resourcemanager外的所有node,因为此处我们配置的resourcemanager和namenode是同一台主 机,所以此处也需要添加nodemanager

执行步骤如下: 1

2 3

4 5

6 7

8 9

10 11

12 13$

hostname

/#查看host名字

cluster1 $sbin

/hadoop-daemon

.sh --script hdfs start namenode

/# 启动namenode

$sbin

/hadoop-daemon

.sh --script hdfs start datanode

/# 启动datanode $sbin

/yarndaemon

.shstart nodemanager

/#启动nodemanager

$sbin

/yarn-daemon

.sh start resourcemanager

/# 启动resourcemanager $sbin

/yarn-daemon

.shstart proxyserver

/# 启动web App proxy, 作用类似jobtracker,若yarn-site.xml里没有设置yarn.web-proxy.address的host和端口,或者设置了和 resourcemanager相同的host和端口,则hadoop默认proxyserver和resourcemanager共享 host:port

$sbin

/mr-jobhistory-daemon

.sh start historyserver

/#你懂得 $

ssh

cluster2

/#登录cluster2

$

hostname

/#查看host名字cluster2 $sbin

/yarndaemon

.shstart nodemanager

/# 启动nodemanager

$sbin

/hadoop-daemon

.sh --script hdfs start datanode

/# 启动datanode $

ssh

cluster3

/#登录cluster3.../# cluster2, cluster3, cluster4启动方式和cluster2一样。

启动方式(2)使用hadoop自带的批处理脚本开启

Step1.确认已登录cluster1: 1$

hostname

cluster1

在$YARN_HOME/etc/hadoop/下新建namenodehosts,添加所有namenode节点

1

2

$

cat

$YARN_HOME

/etc/hadoop/namenodehosts

cluster1

在$YARN_HOME/etc/hadoop/下新建datanodehosts,添加所有datanode节点

1

2 3

4 $

cat

$YARN_HOME

/etc/hadoop/datanodehosts

cluster2 cluster3

cluster4

在$YARN_HOME/etc/hadoop/下新建nodehosts,添加所有datanode和namenode节点

1

2 3

4 5$

cat

$YARN_HOME

/etc/hadoop/datanodehosts

cluster1 cluster2

cluster3 cluster4

备注:以上的hostfile名字是随便起的,可以是任意的file1,file2,file3, 但是必须放在$YARN_HOME/etc/hadoop/下面!

Step2.执行脚本 1

2 3

4 5

6 $sbin

/hadoop-daemons

.sh--hosts namenodehosts --script hdfsstart namenode

$sbin

/hadoop-daemons

.sh--hosts datanodehosts --script hdfsstart datanode $sbin

/yarn-daemons

.sh--hostnames cluster1 start resourcemanager

$sbin

/yarn-daemons

.sh--hosts allnodehosts start nodemanager $sbin

/yarn-daemons

.sh--hostnames cluster1 start proxyserver

$sbin

/mr-jobhistory-daemon

.sh start historyserver

在这里不得不纠正一个其他教程上关于对hadoop2.2做相关配置和运行时的错误!

我们在core-site.xml指定了default filesystem为cluster1, 并指定了其节点ip(或节点名)和端口号, 这意味着若启动hadoop时不额外添加配置(启动hadoop时命令行里加--conf指定用户配置文件的存放位置),则默认的namenode就一 个,那就是cluster1, 如果随意指定namenode必然会出现错误!

如果你要还要再启动一个新的namenode(以cluster3为例),则必须如下操作:

a. 新建一个core-site.xml,添加fs.defaultFS的value为hdfs://cluster3:9000

b. command: 1$sbin

/hadoop-daemon

.sh --hostnames cluster3 --conf you_conf_dir --script hdfs --start namenode

我们之前启动的namenode为cluster1, 假如要查看放在此文件系统根目录下的文件input_file,则它的完整路径为 hdfs://cluster1:9000/input_file

Step3.查看启动情况

在cluster1上: 1

2 3

4 5

6 $jps

22411 NodeManager 23356 Jps

22292 ResourceManager 22189 DataNode

22507 WebAppProxyServer

在cluster2上

1

2 3

4 $jps

8147 DataNode 8355 Jps

8234 NodeManagercluster3,cluster4上和cluster2一样。

**Step4.查看各节点状态以及yarncluster运行状态

(1)查看各节点状态

FireFox进入: http://cluster1:50070(cluster1为namenode所在节点)

在主页面(第一张图)上点击Live Node,查看(第二张图)上各Live Node状态:

(2)查看resourcemanager上cluster运行状态

Firefox进入:http://cluster2:8088(node1为resourcemanager所在节点)

Step5. Cluster上MapReduce测试

现提供3个test cases

Test Case 1 testimated_value_of_pi

command: $sbin/yarnjar $YARN_HOME/share/hadoop//mapreduce/hadoop-mapreduce-examples-2.2.0.jar \pi 101000000

console输出:

复制代码 Number of Maps =10 Samples per Map = 1000000 Wrote input for Map /#0 Wrote input for Map /#1 Wrote input for Map /#2 Wrote input for Map /#3 Wrote input for Map /#4 Wrote input for Map /#5 Wrote input for Map /#6 Wrote input for Map /#7 Wrote input for Map /#8 Wrote input for Map /#9 Starting Job 13/11/06 23:20:07 INFO Configuration.deprecation: mapred.map.tasksis deprecated. Instead, use mapreduce.job.maps 13/11/06 23:20:07 INFO Configuration.deprecation:mapred.output.key.class is deprecated. Instead, usemapreduce.job.output.key.class 13/11/06 23:20:07 INFO Configuration.deprecation:mapred.working.dir is deprecated. Instead, use mapreduce.job.working.dir 13/11/06 23:20:11 INFO mapreduce.JobSubmitter: Submittingtokens for job: job_1383806445149_0001 13/11/06 23:20:15 INFO impl.YarnClientImpl: Submittedapplication application_1383806445149_0001 to ResourceManager at /0.0.0.0:8032 13/11/06 23:20:16 INFO mapreduce.Job: The url to trackthe job: http://Node1:8088/proxy/application_1383806445149_0001/ 13/11/06 23:20:16 INFO mapreduce.Job: Running job:job_1383806445149_0001 13/11/06 23:21:09 INFO mapreduce.Job: Jobjob_1383806445149_0001 running in uber mode : false 13/11/06 23:21:10 INFO mapreduce.Job: map 0% reduce 0% 13/11/06 23:24:28 INFO mapreduce.Job: map 20% reduce 0% 13/11/06 23:24:30 INFO mapreduce.Job: map 30% reduce 0% 13/11/06 23:26:56 INFO mapreduce.Job: map 57% reduce 0% 13/11/06 23:26:58 INFO mapreduce.Job: map 60% reduce 0% 13/11/06 23:28:33 INFO mapreduce.Job: map 70% reduce 20% 13/11/06 23:28:35 INFO mapreduce.Job: map 80% reduce 20% 13/11/06 23:28:39 INFO mapreduce.Job: map 80% reduce 27% 13/11/06 23:30:06 INFO mapreduce.Job: map 90% reduce 27% 13/11/06 23:30:09 INFO mapreduce.Job: map 100% reduce 27% 13/11/06 23:30:12 INFO mapreduce.Job: map 100% reduce 33% 13/11/06 23:30:25 INFO mapreduce.Job: map 100% reduce 100% 13/11/06 23:30:54 INFO mapreduce.Job: Jobjob_1383806445149_0001 completed successfully 13/11/06 23:31:10 INFO mapreduce.Job: Counters: 43 File SystemCounters FILE:Number of bytes read=226 FILE:Number of bytes written=879166 FILE:Number of read operations=0 FILE:Number of large read operations=0 FILE:Number of write operations=0 HDFS:Number of bytes read=2590 HDFS:Number of bytes written=215 HDFS:Number of read operations=43 HDFS:Number of large read operations=0 HDFS:Number of write operations=3 JobCounters Launchedmap tasks=10 Launchedreduce tasks=1 Data-localmap tasks=10 Totaltime spent by all maps in occupied slots (ms)=1349359 Totaltime spent by all reduces in occupied slots (ms)=190811 Map-ReduceFramework Mapinput records=10 Mapoutput records=20 Mapoutput bytes=180 Mapoutput materialized bytes=280 Inputsplit bytes=1410 Combineinput records=0 Combineoutput records=0 Reduceinput groups=2 Reduceshuffle bytes=280 Reduceinput records=20 Reduceoutput records=0 SpilledRecords=40 ShuffledMaps =10 FailedShuffles=0 MergedMap outputs=10 GCtime elapsed (ms)=45355 CPUtime spent (ms)=29860 Physicalmemory (bytes) snapshot=1481818112 Virtualmemory (bytes) snapshot=9214468096 Totalcommitted heap usage (bytes)=1223008256 ShuffleErrors BAD_ID=0 CONNECTION=0 IO_ERROR=0 WRONG_LENGTH=0 WRONG_MAP=0 WRONG_REDUCE=0 File InputFormat Counters BytesRead=1180 File OutputFormat Counters BytesWritten=97 13/11/06 23:31:15 INFO mapred.ClientServiceDelegate:Application state is completed. FinalApplicationStatus=SUCCEEDED. Redirectingto job history server Job Finished in 719.041 seconds Estimated value of Pi is 3.14158440000000000000

复制代码

说明:可以看到最后输出值为该job使用了 10个maps, job id为job1383806445149_000, 最后计算得Pi的值为13.14158440000000000000, job Id分配原则为job年月日时分job序列号,序列号从0开始,上限值为1000, task id分配原则为job年月日时分job序列号_task序列号_m, job年月日时分_job序列号_task序列号_r, m代表map taskslot , r代表reduce task slot, task 序列号从0开始,上限值为1000.

Test Case 2 random_writting /#command line $sbin/yarnjar $YARN_HOME/share/hadoop//mapreduce/hadoop-mapreduce-examples-2.2.0.jar \randomwriter/user/grid/test/test_randomwriter/out

复制代码

/#Console输出摘录: Running 10 maps.Job started: Wed Nov 0623:42:17 PST 201313/11/0623:42:17 INFO client.RMProxy: Connecting toResourceManager at /0.0.0.0:803213/11/0623:42:19 INFO mapreduce.JobSubmitter: number ofsplits:1013/11/0623:42:20 INFO mapreduce.JobSubmitter: Submittingtokens for job: job_1383806445149_000213/11/0623:42:21 INFO impl.YarnClientImpl: Submittedapplication application_1383806445149_0002 to ResourceManager at /0.0.0.0:803213/11/0623:42:21 INFO mapreduce.Job: The url to trackthe job: http://Master:8088/proxy/application_1383806445149_0002/13/11/0623:42:21 INFO mapreduce.Job: Running job:job_1383806445149_000213/11/0623:42:40 INFO mapreduce.Job: Jobjob_1383806445149_0002 running in uber mode : false13/11/0623:42:40 INFO mapreduce.Job: map 0% reduce 0% 13/11/0623:55:02 INFO mapreduce.Job: map 10% reduce 0% 13/11/0623:55:14 INFO mapreduce.Job: map 20% reduce 0% 13/11/0623:55:42 INFO mapreduce.Job: map 30% reduce 0% 13/11/0700:06:55 INFO mapreduce.Job: map 40% reduce 0% 13/11/0700:07:10 INFO mapreduce.Job: map 50% reduce 0% 13/11/0700:07:36 INFO mapreduce.Job: map 60% reduce 0% 13/11/0700:13:47 INFO mapreduce.Job: map 70% reduce 0% 13/11/0700:13:54 INFO mapreduce.Job: map 80% reduce 0% 13/11/0700:13:58 INFO mapreduce.Job: map 90% reduce 0% 13/11/0700:16:29 INFO mapreduce.Job: map 100% reduce 0% 13/11/0700:16:37 INFO mapreduce.Job: Jobjob_1383806445149_0002 completed successfully File OutputFormat Counters BytesWritten=10772852496Job ended: Thu Nov 0700:16:40 PST 2013The job took 2062 seconds.

复制代码

说明:电脑存储空间足够的话,可以从hdfs里down下来看看。

现只能看一看输出文件存放的具体形式:

复制代码 ./bin/hadoopfs -ls /user/grid/test/test_randomwriter/out/Found 11items-rw-r--r-- 2 grid supergroup 02013-11-0700:16/user/grid/test/test_randomwriter/out/_SUCCESS-rw-r--r-- 2 grid supergroup 10772782142013-11-0623:54 /user/grid/test/test_randomwriter/out/part-m-00000 -rw-r--r-- 2 grid supergroup 10772827512013-11-0623:55 /user/grid/test/test_randomwriter/out/part-m-00001 -rw-r--r-- 2 grid supergroup 10772802982013-11-0623:55 /user/grid/test/test_randomwriter/out/part-m-00002 -rw-r--r-- 2 grid supergroup 10773031522013-11-0700:07 /user/grid/test/test_randomwriter/out/part-m-00003 -rw-r--r-- 2 grid supergroup 10772842402013-11-0700:06 /user/grid/test/test_randomwriter/out/part-m-00004 -rw-r--r-- 2 grid supergroup 10772866042013-11-0700:07 /user/grid/test/test_randomwriter/out/part-m-00005 -rw-r--r-- 2 grid supergroup 10772843362013-11-0700:13 /user/grid/test/test_randomwriter/out/part-m-00006 -rw-r--r-- 2 grid supergroup 10772848292013-11-0700:13 /user/grid/test/test_randomwriter/out/part-m-00007 -rw-r--r-- 2 grid supergroup 10772897062013-11-0700:13 /user/grid/test/test_randomwriter/out/part-m-00008 -rw-r--r-- 2 grid supergroup 10772783662013-11-0700:16 /user/grid/test/test_randomwriter/out/part-m-00009

复制代码

Test Case3 word_count

(1)Locaol上创建文件: $mkdirinput%echo ‘hello,world’ >> input/file1.in$echo ‘hello, ruby’ >> input/file2.in

(2)上传到hdfs上: ./bin/hadoop fs -mkdir -p /user/grid/test/test_wordcount/./bin/hadoop fs –put input/user/grid/test/test_wordcount/in

(3)用yarn新计算框架运行mapreduce:

复制代码 /#command line $bin/yarn jar$YARN_HOME/share/hadoop//mapreduce/hadoop-mapreduce-examples-2.2.0.jarwordcount /user/grid/test/test_wordcount/in/user/grid/test/test_wordcount/out /#ConSole输出摘录:3/11/0700:35:03 INFO client.RMProxy:Connecting to ResourceManager at /0.0.0.0:803213/11/0700:35:05 INFO input.FileInputFormat:Total input paths to process : 213/11/0700:35:05 INFO mapreduce.JobSubmitter:number of splits:213/11/0700:35:06 INFO mapreduce.JobSubmitter:Submitting tokens for job: job_1383806445149_000313/11/0700:35:08 INFO impl.YarnClientImpl:Submitted application application_1383806445149_0003 to ResourceManager at /0.0.0.0:803213/11/0700:35:08 INFO mapreduce.Job: The urlto track the job: http://Master:8088/proxy/application_1383806445149_0003/13/11/0700:35:08 INFO mapreduce.Job: Runningjob: job_1383806445149_000313/11/0700:35:25 INFO mapreduce.Job: Jobjob_1383806445149_0003 running in uber mode : false13/11/0700:35:25 INFO mapreduce.Job: map 0% reduce 0% 13/11/0700:37:50 INFO mapreduce.Job: map 33% reduce 0% 13/11/0700:37:54 INFO mapreduce.Job: map 67% reduce 0% 13/11/0700:37:55 INFO mapreduce.Job: map 83% reduce 0% 13/11/0700:37:58 INFO mapreduce.Job: map 100% reduce 0% 13/11/0700:38:51 INFO mapreduce.Job: map 100% reduce 100% 13/11/0700:38:54 INFO mapreduce.Job: Jobjob_1383806445149_0003 completed successfully13/11/0700:38:56 INFO mapreduce.Job:Counters: 43

复制代码

说明:查看word count的计算结果: 1

2 3

4 $bin

/hadoop

fs -

cat

/user/grid/test//test_wordcount/out/

/*

hadoop 1 hello 1

ruby

补充:因为新的YARN为了保持与MRv1框 架的旧版本兼容性,很多老的API还是可以用,但是会有INFO。此处通过修改$YARN_HOME/etc/hadoop /log4j.properties可以turn offconfiguration deprecation warnings.

建议去掉第138行的注释(可选),确保错误级别为WARN(默认为INFO级别,详见第20行:hadoop.root.logger=INFO,console): 1138 log4j.logger.org.apache.hadoop.conf.Configuration.deprecation=WARN

附文:

集群搭建、配置步骤(基于CentOS_64bit)

0. 说明

大体规划如下:

虚拟机: VMware-workstation-full-8.0.3-703057(VMware10中文版不完整,此版本内含vmware tools,为设定共享文件夹所必须)

电脑1,VMWare,内装2个虚拟系统,(cluster1, cluster2)

电脑2,,VMware内装2个虚拟系统,(cluster3, cluster4)

虚拟主机: CentOS x86 64bit

局域网IP设置:** 1

2 3

4

cluster1 172.16.102. 201

cluster2 172.16.102. 202 cluster3 172.16.102. 203

cluster4 172.16.102. 204

网关

1172.16.102.254

1. Linux集群安装

(1) 准备

Vmware: VMware-workstation-full-8.0.3-703057(此安装包自带VMWare Tools)

Linux:CentOS.iso

(2) VMWare配置

VMWare以及所有安装的虚拟机均为桥接

Step1. 配置VMWare 联网方式: Editor->Virtual Network Editor->选择Bridged, 点击确定

Step2. 安装虚拟机

Step3.配置各虚拟机接网方式:右键已安装虚拟机->点击NetworkAdapter, 选择桥接,确定

Step4. 为所有安装好的虚拟系统设置一个共享目录(类似FTP,但是设置共享目录更方便) :右键已安装虚拟机->点击Virtual Machine Settings对话框上部Options, 选择Shared Folder, 在本地新建SharedFolder并添加进来,确定。

(3) linux下网卡以及IP配置

以下配置在三个虚拟系统里均相同, 以cluster1为例:

配置前需切换为root

Step1. 修改主机名, 设置为开启网络

配置/etc/sysconfig/network: 1

2 3[root@localhost ~]

/# cat /etc/sysconfig/network

NETWORKING=

yes HOSTNAME=cluster1

Step2.修改当前机器的IP, 默认网关, IP分配方式, 设置网络接口为系统启动时有效:

a.查看配置前的ip: 1

2 3

4 [root@localhost ~]

/# ifconfig

eth0 Link encap:Ethernet HWaddr 00:0C:29:E1:FB:95 inet addr:172.16.102.3 Bcast:172.16.102.255 Mask:255.255.255.0

inet6 addr: fe80::20c:29ff:fee1:fb95

/64

Scope:Lin

b.配置/etc/sysconfig/network-scripts/ifcfg-eth0

注意以下几项:

BOOTPROTO="static" (IP分配方式, 设为static则主机ip即为IPADDR里所设,若为”dhcp”, 此时只有局域网有效,则vmware会启动自带虚拟”dhcp”, 动态分配ip, 此时可以连接互联网 )

复制代码 IPV6INIT="no" /#你懂得 IPADDR="172.16.102.201" /#ip地址 GETEWAY="172.16.102.254" /#默认网关地址 ONBOOT="yes" /#系统启动时网络接口有效 [root@localhost ~]/# cat /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE="eth0"BOOTPROTO="static"HWADDR="00:0C:29:E1:FB:95"BOOTPROTO="dhcp"IPV6INIT="no"IPADDR="172.16.102.201"GETEWAY="172.16.102.254"ONBOOT="yes"NM_CONTROLLED="yes"TYPE="Ethernet"UUID="79612b26-326b-472c-94af-9ab151fc2831

复制代码

c.使当前设置生效: $service network restart $ifdown eth0 /#关闭默认网卡 $ifup eth/#重新启用默认网卡 $service network restart; ifdown eth0; ifup eth0

d.查看新设置的ip: $ifconfigeth0 Link encap:Ethernet HWaddr 00:0C:29:E1:FB:95 inet addr:192.168.1.200 Bcast:192.168.1.255 Mask:255.255.255.0inet6 addr: fe80::20c:29ff:fee1:fb95/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

Step3. 修改hosts文件,此文件会被DNS解析,类似linux里的alias, 设置后以后,hostname就是ip地址, 两者可以互换。

配置/etc/hosts, 添加三行如下, (注意,此3行在3个虚拟主机里都相同,切必须全部都要加上)

复制代码 [root@localhost ~]/# cat /etc/hosts127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 cluster1 172.16.102. 201cluster2 172.16.102. 202cluster3 172.16.102. 203cluster4 172.16.102. 204

复制代码

Step4. 按照以上3个步骤分别设置两外两个虚拟主机,

配置完以后必须按照之前的三个命令分别重启 network, ifeth0: $service network restart $ifdown eth0 $ifup eth0

重新初始化以后查看各自主机的ip配置是否正确。

在任意一台主机上执行: ping cluster1; ping cluster2; ping cluster3; ping cluster4

若配置正确,一定可以ping通,否则,请检查各个主机的/etc/hosts文件是否已经添加新的映射!至此,linux集群已成功配置。

2. 设置 ssh免登陆

a. 新建一个用户

在三台主机上分别以root权限新建一个用户,此处默认为grid:

cluster1,cluster2, cluster3, cluster4上: $useradd –m grid $passwd grid 1qaz!QAZ

注意一定要保证4台主机上有相同的用户名, 以实现同一个用户在4台主机上登录。

b. 在cluster1上生成RSA密钥

切换回user: grid $su grid $cd ~

生成密钥对:

1

2 3$

ssh

-keygen –t rsa

/#一路回车到最后( 此处生成无需密码的秘钥-公钥对)。 /#上一个步骤 ssh-keygen –t rsa会在grid的home目录下生成一个.ssh文件夹

之后:

$cd ~/.ssh/$cp id_rsa.pub authorized_keys

c. 在另外3个主机上的grid用户home目录下也声称相应的密钥对, 并在.ssh目录下生成一个

authorized_keys 文件

d. 想办法将4台主机grid用户下刚生成的

authorized_keys 里的内容整合成一个完整的

authorized_keys.

比如将4个authorized_keys里的内容全部复制到cluster1上的authorized_keys里, 然后: $chmod 600 authorized_keys $scp .ssh/authorized_keys cluster2:/home/grid/.ssh/$scp .ssh/authorized_keys cluster3:/home/grid/.ssh/$scp .ssh/authorized_keys cluster4:/home/grid/.ssh/

若要求输入密码,则输入之前新建用户grid时设置的密码, 一路回车到最后.

e. 下面尝试ssh无秘钥登录:

在cluster1主机上:ssh cluster2, 依次尝试登陆cluster2, cluster3, cluster4

若均可可以免密码登录,则直接跳到下一步骤,否则,请看下面的解决方案:

可能出现的问题有3,

第一种可能,.ssh文件夹非自动生成,而是你手动新建的,若如此,会出现.ssh的安全上下文问题, 解决方案, 在三个主机上以grid用户,删除刚才生成的.ssh文件夹,重新进入home目录,务必用 /# ssh-keygen –t rsa 生成秘钥, 此过程ssh程序会自动在home目录下成成一个.ssh文件夹

第二种可能, authorized_keys权限不一致。 在各自.ssh目录下:ls–alauthorizedkeys,查看此文件的权限,一定为600(−rw−−−−−−−),即只对当前用户grid开放可读可写权限,若不是,则修改authorizedkeys文件权限chmod 600 authorized_keys

若经过以上两步还不行,则执行以下命令,重新启动ssh-agent, 且加入当前用户秘钥id_rsa $ssh-add ~grid/.ssh/id_rsa

经过以上三步,一定可以实现grid从cluster1到其它3个节点的免秘钥登录。

因为hadoop2.2新架构的缘故,我们还应该设置为每一个节点到其它任意节点免登陆。

具体步骤:

1.在将cluster2, cluster3, cluster4上各自的.ssh/id_rsa.pub 分别复制到cluster1的.ssh/下: scp id_rsa.pub cluster1:/home/grid/.ssh/tmp2, scp id_rsa.pub cluster1:/home/grid/.ssh/tmp3 ...

2.将cluster1节点/home/grid/.ssh/下的tmp2, tmp3, tmp4分别appand到authorized_keys里, 并请将各自节点上的id_rsa.pub也append到各自节点的authorized_keys里,以实现本地登陆(类似: ssh localhost)

至此,ssh免秘钥登陆设置完成。

3. 安装jdk

Step1. 记得之前在安装cluster1时在VMWare里设置的共享目录吗?

在Windows下将Hadoop安装包,jdk安装包Copy到共享目录下,然后在linux下从/mnt/hgfs/Data-shared/下cp到/home/grid/下,直接执行jdk安装包,不需要解压。

注意:若在安装过程中提示”Extracting… install.sfx 5414: /lib/ld-linux.50.2 No such file or directory, 则执行以下命令:

a.我们之前为了测试自定义的ip是否有效,已将各台主机的ip分配方式设为了BOOTPROTO=”static”, 这种方式是无法连入外部网络的,所以此时为了安装缺省的包,切换到root, 修改/etc/sysconfig/network-script/ifcfg-eth0,将BOOTPROTO=”static” 修改为BOOTPROTO=”dhcp”,

b.重启网络服务和网卡: 在root权限下: $service network restart; ifdown eth0; ifup eth0 $yum install glibc.i686

d.切换回grid,重新安装jdk

$cd /usr/java/ /#注意必须进入java文件夹,因为java安装包默认安装在当前目录下 $./jdk-6u25-linux-i586.bin /#安装jdk

安装完以后,记得将eth0文件修改回来:

$sed -i s/dhcp/static/g /etc/sysconfig/network-scripts/ifcfg-eth0 /#此处用sed直接替换,若不放心也可以用编辑器修改 /#service network restart; ifdown eth0;ifup eth0

至此,jdk已在linux下安装完毕。

最后,将java安装好的路径append到$PATH变量里(处于个人习惯,新环境变量一律添加到所需用户的.bashrc文件里, 即只对当前用户有效) $su grid $vim ~/.bashrc (修改.bashrc文件,添加如下两行:) $tail -2 ~/.bashrc export JAVA_HOME="/usr/java/jdk1.6.0_25/"export PATH="${PATH}:${JAVA_HOME}/bin"

测试一下java是否可以正常启动:

$source ~/.bashrc $which java $/usr/java/jdk1.6.0_25/bin/java

至此,jdk安装完毕。

用同样的方式在另外3台虚拟主机上安装jdk, 提示:先复制到home下 $scp -r /mnt/hgfs/Data-shared/Archive/jdk-6u25-linux-i586.bin cluster2:/home/grid/$scp -r /mnt/hgfs/Data-shared/Archive/jdk-6u25-linux-i586.bin cluster3:/home/grid/$scp -r /mnt/hgfs/Data-shared/Archive/jdk-6u25-linux-i586.bin cluster4:/home/grid/

再切root, copy到/usr/java下, cd /usr/java, 然后再安装.

通过网络使用adb

Posted on

通过网络使用adb

在adb的说明文档中提到:

“An ADB transport models a connection between the ADB server and one device
or emulator. There are currently two kinds of transports:
   - USB transports, for physical devices through USB
   - Local transports, for emulators running on the host, connected to
     the server through TCP”

大意是说,在物理设备上,adb是通过USB连接到设备上的,而在模拟器上,adb是通过TCP协议连接到设备上的。实际上在物理设备上,也可以让adb 通过TCP协议来连接设备(当然前提条件是你的设备要有网口)。首先看一下下面这段源代码,出自system/core/adb/adb.c,第921 行:

// for the device, start the usb transport if the // android usb device exists and "service.adb.tcp" // is not set, otherwise start the network transport. // property_get("service.adb.tcp.port", value, "0"); if (sscanf(value, "%d", &port) == 1 && port > 0) { // listen on TCP port specified by service.adb.tcp.port property local_init(port); } else if (access("/dev/android_adb", F_OK) == 0) { // listen on USB usb_init(); } else { // listen on default port local_init(ADB_LOCAL_TRANSPORT_PORT); }

分析上述代码可以发现,在adbd启动时首先检查是否设置了service.adb.tcp.port,如果设置了,就是使用TCP作为连接方式;如果没 设置,就去检查是否有adb的USB设备(dev/android_adb),如果有就用USB作为连接方式;如果没有USB设备,则还是用TCP作为连 接方式。

因此只需要在启动adbd之前设置service.adb.tcp.port,就可以让adbd选则TCP模式,也就可以通过网络来连接adb了。这需要修改init.rc文件。如果不想修改,也可以在系统启动之后,在控制台上执行下列命令:

/#stop adbd

/#set service.adb.tcp.port 5555

/#start adbd

这样就可以在主机上通过下列命令来连接设备了:

adb connetc <ip-of-device>:5555

linux下adb工具的安装

Posted on

linux下adb工具的安装

第一步:启动开发板,进入android系统后,在linux终端输入lsusb命令查询USB总线上的设备,比如我这里查询结果如下:

我这里是: Bus 007 Device 009: ID 18d1:4e12

第二步:下载最新的android SDK并解压到某目录,下载地址: http://developer.android.com/sdk/index.html 截至目前最新的SDK为android-sdk_r12-linux_x86.tgz 解压出来的名称为android-sdk-linux_x86 进入下面目录: cd android-sdk-linux_x86/tools/ ./android update adb

第三步:创建一个新的udev规则的文件,在/etc/udev/rules.d路径下,新建名为imx-android.rules的文件,编辑内容如下: vim /etc/udev/rules.d/50-android.rules

文件里添加如下配置参数:

/#Acer 0502

SUBSYSTEM=="usb", SYSFS{idVendor}=="0502", MODE="0666"

/#Dell 413c

SUBSYSTEM=="usb", SYSFS{idVendor}=="413c", MODE="0666"

/#Foxconn 0489

SUBSYSTEM=="usb", SYSFS{idVendor}=="0489", MODE="0666"

/#Garmin-Asus 091E

SUBSYSTEM=="usb", SYSFS{idVendor}=="091e", MODE="0666"

/#HTC 0bb4

SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"

/#Huawei 12d1

SUBSYSTEM=="usb", SYSFS{idVendor}=="12d1", MODE="0666"

/#Kyocera 0482

SUBSYSTEM=="usb", SYSFS{idVendor}=="0482", MODE="0666"

/#LG 1004

SUBSYSTEM=="usb", SYSFS{idVendor}=="1004", MODE="0666"

/#Motorola 22b8

SUBSYSTEM=="usb", SYSFS{idVendor}=="22b8", MODE="0666"

/#Nvidia 0955

SUBSYSTEM=="usb", SYSFS{idVendor}=="0955", MODE="0666"

/#Pantech 10A9

SUBSYSTEM=="usb", SYSFS{idVendor}=="10A9", MODE="0666"

/#Samsung 04e8

SUBSYSTEM=="usb", SYSFS{idVendor}=="04e8", MODE="0666"

/#Sharp 04dd

SUBSYSTEM=="usb", SYSFS{idVendor}=="04dd", MODE="0666"

/#Sony Ericsson 0fce

SUBSYSTEM=="usb", SYSFS{idVendor}=="0fce", MODE="0666"

/#ZTE 19D2

SUBSYSTEM=="usb", SYSFS{idVendor}=="19D2", MODE="0666

/#MEIZU 18d1

SUBSYSTEM=="usb", SYSFS{idVendor}=="18d1", MODE="0666

但是这上面的ID,并不能包括所有。 解决办法是你可以使用lsusb命令查看你的USB ID

第四步:在/etc/profile中声明adb的路径:

export PATH=/usr/local/android-sdk-linux/platform-tools:$PATH

第五步:重启ADB adb kill-server adb start-server

第六步:使用adb devices命令查找设备:

[root@redhat6 platform-tools]/# adb devices

List of devices attached

353BCHHRB44F device

至此,安装成功。

你可以进去设备了,用adb shell,可以操作你到android了。