??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲乱码中文字幕综合,久久国产亚洲精品,亚洲综合av一区二区三区不卡http://m.tkk7.com/ashutc/category/46711.htmlj2eezh-cnSat, 23 Oct 2010 06:29:51 GMTSat, 23 Oct 2010 06:29:51 GMT60分布式计开源框架Hadoop介绍http://m.tkk7.com/ashutc/archive/2010/10/22/335890.html西瓜西瓜Fri, 22 Oct 2010 07:21:00 GMThttp://m.tkk7.com/ashutc/archive/2010/10/22/335890.htmlhttp://m.tkk7.com/ashutc/comments/335890.htmlhttp://m.tkk7.com/ashutc/archive/2010/10/22/335890.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/335890.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/335890.html

在SIP目设计的过E中Q对于它庞大的日志在开始时p虑使用d分解的多U程处理模式来分析统计,在我从前写的文章《Tiger Concurrent Practice --日志分析q行分解设计与实现》中有所提到。但是由于统计的内容暂时q是十分单,所以就采用Memcache作ؓ计数器,l合MySQL完成了讉K 控制以及l计的工作。然而未来,对于量日志分析的工作,q是需要有所准备。现在最火的技术词汇莫q于“云计?#8221;Q在Open API日益盛行的今天,互联|应用的数据会来有价|如何d析这些数据,挖掘其内在h|需要分布式计算来支撑v量数据的分析工作?/p>

回过头来看,早先那种多线E,多Q务分解的日志分析设计Q其实是分布式计的一个单机版~略Q如何将q种单机的工作进行分拆,变成协同工作的集, 其实是分布式计框架设计所涉及的。在d参加BEA大会的时候,BEA和VMWare合作采用虚拟机来构徏集群Q无非就是希望得计机g能够cM 于应用程序中资源池的资源Q用者无需兛_资源的分配情况,从而最大化了硬件资源的使用价倹{分布式计算也是如此Q具体的计算d交由哪一台机器执行,? 行后p来汇总,q都由分布式框架的Master来抉择,而用者只需单地待分析内容提供l分布式计算pȝ作ؓ输入Q就可以得到分布式计后的结果?/p>

Hadoop是Apache开源组l的一个分布式计算开源框Ӟ在很多大型网站上都已l得C应用Q如亚马逊、Facebook和Yahoo{等? 对于我来_最q的一个用点是服务集成q_的日志分析。服务集成^台的日志量将会很大,而这也正好符合了分布式计的适用场景Q日志分析和索引建立? 是两大应用场景)?/p>

当前没有正式定使用Q所以也是自׃余摸索,后箋所写的相关内容Q都是一个新手的学习q程Q难免会有一些错误,只是希望记录下来可以分nl更多志同道合的朋友?/p>

什么是HadoopQ?/h2>

搞什么东西之前,W一步是要知道WhatQ是什么)Q然后是WhyQؓ什么)Q最后才是HowQ怎么做)。但很多开发的朋友在做了多q项目以后,都习惯是先HowQ然后WhatQ最后才是WhyQ这样只会让自己变得躁Q同时往往会将技术误用于不适合的场景?/p>

Hadoop框架中最核心的设计就是:MapReduce和HDFS。MapReduce的思想是由Google的一论文所提及而被qؓ传的, 单的一句话解释MapReduce是“d的分解与l果的汇?#8221;。HDFS是Hadoop分布式文件系l(Hadoop Distributed File SystemQ的~写Qؓ分布式计存储提供了底层支持?/p>

MapReduce从它名字上来看就大致可以看出个缘由,两个动词Map和ReduceQ?#8220;MapQ展开Q?#8221;是一个Q务分解成为多个Q 务,“Reduce”是分解后多Q务处理的l果汇总v来,得出最后的分析l果。这不是什么新思想Q其实在前面提到的多U程Q多d的设计就可以扑ֈq? U思想的媄子。不论是现实C会Q还是在E序设计中,一工作往往可以被拆分成为多个Q务,d之间的关pd以分ZU:一U是不相关的dQ可以ƈ行执 行;另一U是d之间有相互的依赖Q先后顺序不能够颠倒,q类d是无法ƈ行处理的。回到大学时期,教授上课时让大家d析关键\径,无非是找最省时? d分解执行方式。在分布式系l中Q机器集就可以看作g资源池,ƈ行的d拆分Q然后交由每一个空闲机器资源去处理Q能够极大地提高计算效率Q同? q种资源无关性,对于计算集群的扩展无疑提供了最好的设计保证。(其实我一直认为Hadoop的卡通图标不应该是一个小象,应该是蚂蚁,分布式计就好比 蚂蚁吃大象,廉h的机器群可以ҎM高性能的计机Q纵向扩展的曲线始终敌不q横向扩展的斜线Q。Q务分解处理以后,那就需要将处理以后的结果再汇总v 来,q就是Reduce要做的工作?/p>
?QMapReducel构C意?/strong>

上图是MapReduce大致的结构图Q在Map前还可能会对输入的数据有SplitQ分Ԍ的过E,保证dq行效率Q在Map之后q会有ShuffleQ؜合)的过E,对于提高Reduce的效率以及减数据传输的压力有很大的帮助。后面会具体提及q些部分的细节?/p>

HDFS是分布式计算的存储基矻IHadoop的分布式文gpȝ和其他分布式文gpȝ有很多类似的特质。分布式文gpȝ基本的几个特点:

  1. 对于整个集群有单一的命名空间?/li>
  2. 数据一致性。适合一ơ写入多ơ读取的模型Q客L在文件没有被成功创徏之前无法看到文g存在?/li>
  3. 文g会被分割成多个文件块Q每个文件块被分配存储到数据节点上,而且Ҏ配置会由复制文g块来保证数据的安全性?/li>

?QHDFSl构C意?/strong>

上图中展C整个HDFS三个重要角色QNameNode、DataNode和Client。NameNode可以看作是分布式文gpȝ中的理 者,主要负责理文gpȝ的命名空间、集配|信息和存储块的复制{。NameNode会将文gpȝ的Meta-data存储在内存中Q这些信息主要包? 了文件信息、每一个文件对应的文g块的信息和每一个文件块在DataNode的信息等。DataNode是文件存储的基本单元Q它Block存储在本? 文gpȝ中,保存了Block的Meta-dataQ同时周期性地所有存在的Block信息发送给NameNode。Client是需要获取分布式? 件系l文件的应用E序。这里通过三个操作来说明他们之间的交互关系?/p>

文g写入Q?/strong>

  1. Client向NameNode发v文g写入的请求?/li>
  2. NameNodeҎ文g大小和文件块配置情况Q返回给Client它所理部分DataNode的信息?/li>
  3. Client文件划分ؓ多个BlockQ根据DataNode的地址信息Q按序写入到每一个DataNode块中?/li>

文gdQ?/strong>

  1. Client向NameNode发v文gd的请求?/li>
  2. NameNodeq回文g存储的DataNode的信息?/li>
  3. Clientd文g信息?/li>

文gBlock复制Q?/strong>

  1. NameNode发现部分文g的Block不符合最复制数或者部分DataNode失效?/li>
  2. 通知DataNode怺复制Block?/li>
  3. DataNode开始直接相互复制?/li>

最后再说一下HDFS的几个设计特点(对于框架设计值得借鉴Q:

  1. Block的放|:默认不配|。一个Block会有三䆾备䆾Q一份放在NameNode指定的DataNodeQ另一份放在与指定 DataNode非同一Rack上的DataNodeQ最后一份放在与指定DataNode同一Rack上的DataNode上。备份无非就是ؓ了数据安 全,考虑同一Rack的失败情况以及不同Rack之间数据拯性能问题采用这U配|方式?/li>
  2. 心蟩DataNode的健L况,如果发现问题采取数据备份的方式来保证数据的安全性?/li>
  3. 数据复制Q场景ؓDataNodep|、需要^衡DataNode的存储利用率和需要^衡DataNode数据交互压力{情况)Q这里先 说一下,使用HDFS的balancer命oQ可以配|一个Threshold来^衡每一个DataNode盘利用率。例如设|了Threshold? 10%Q那么执行balancer命o的时候,首先l计所有DataNode的磁盘利用率的均|然后判断如果某一个DataNode的磁盘利用率过q? 个均值Threshold以上Q那么将会把q个DataNode的block转移到磁盘利用率低的DataNodeQ这对于新节点的加入来说十分有用?/li>
  4. 数据交验Q采用CRC32作数据交验。在文gBlock写入的时候除了写入数据还会写入交验信息,在读取的时候需要交验后再读入?/li>
  5. NameNode是单点:如果p|的话QQ务处理信息将会纪录在本地文gpȝ和远端的文gpȝ中?/li>
  6. 数据道性的写入Q当客户端要写入文g到DataNode上,首先客户端读取一个Block然后写到W一个DataNode上,然后q 一个DataNode传递到备䆾的DataNode上,一直到所有需要写入这个Block的NataNode都成功写入,客户端才会l开始写下一? Block?/li>
  7. 安全模式Q在分布式文件系l启动的时候,开始的时候会有安全模式,当分布式文gpȝ处于安全模式的情况下Q文件系l中的内容不允许修改? 不允许删除,直到安全模式l束。安全模式主要是Zpȝ启动的时候检查各个DataNode上数据块的有效性,同时Ҏ{略必要的复制或者删除部分数? 块。运行期通过命o也可以进入安全模式。在实践q程中,pȝ启动的时候去修改和删除文件也会有安全模式不允怿改的出错提示Q只需要等待一会儿卛_?/li>

下面l合MapReduce和HDFS来看Hadoop的结构:


?QHadoopl构C意?/strong>

在Hadoop的系l中Q会有一台MasterQ主要负责NameNode的工作以及JobTracker的工作。JobTracker的主要职? 是启动、跟t和调度各个Slave的Q务执行。还会有多台SlaveQ每一台Slave通常hDataNode的功能ƈ负责TaskTracker? 工作。TaskTrackerҎ应用要求来结合本地数据执行Mapd以及Reduced?/p>

说到q里Q就要提到分布式计算最重要的一个设计点QMoving Computation is Cheaper than Moving Data。就是在分布式处理中Q移动数据的代hL高于转移计算的代仗简单来说就是分而治之的工作Q需要将数据也分而存储,本地d处理本地数据然后? 总,q样才会保证分布式计的高效性?/p>

Z么要选择HadoopQ?/h2>

说完了WhatQ简单地说一下Why。官方网站已l给了很多的说明Q这里就大致说一下其优点及用的场景Q没有不好的工具Q只用不适用的工P因此选择好场景才能够真正发挥分布式计的作用Q:

  1. 可扩展:不论是存储的可扩展还是计的可扩展都是Hadoop的设计根本?/li>
  2. l济Q框架可以运行在M普通的PC上?/li>
  3. 可靠Q分布式文gpȝ的备份恢复机制以及MapReduce的Q务监控保证了分布式处理的可靠性?/li>
  4. 高效Q分布式文gpȝ的高效数据交互实C及MapReducel合Local Data处理的模式,为高效处理v量的信息作了基础准备?/li>

使用场景Q?/strong>个h觉得最适合的就是v量数据的分析Q其实Google最早提出MapReduce也就是ؓ了v量数 据分析。同时HDFS最早是Z搜烦引擎实现而开发的Q后来才被用于分布式计算框架中。v量数据被分割于多个节点,然后由每一个节点ƈ行计,得出的l? 果归q到输出。同时第一阶段的输出又可以作ؓ下一阶段计算的输入,因此可以惌C个树状结构的分布式计图Q在不同阶段都有不同产出Q同时ƈ行和串行l? 合的计算也可以很好地在分布式集群的资源下得以高效的处理?/p>

其实参看Hadoop官方文档已经能够很容易配|分布式框架q行环境了,不过q里既然写了再多写一点,同时有一些细节需要注意的也说明一下,其实 也就是这些细节会让h摸烦半天。Hadoop可以单机跑,也可以配|集跑Q单׃需要多说了Q只需要按照Demo的运行说明直接执行命令即可。这? 主要重点说一下集配|运行的q程?/p>

环境

7台普通的机器Q操作系l都是Linux。内存和CPU׃说了Q反正Hadoop一大特点就是机器在多不在精。JDK必须?.5以上的,q个切记?台机器的机器名务必不同,后箋会谈到机器名对于MapReduce有很大的影响?/p>

部v考虑

正如上面我描q的Q对于Hadoop的集来_可以分成两大c角ԌMaster和SlaveQ前者主要配|NameNode? JobTracker的角Ԍ负责ȝ分布式数据和分解d的执行,后者配|DataNode和TaskTracker的角Ԍ负责分布式数据存储以及Q 务的执行。本来我打算看看一台机器是否可以配|成MasterQ同时也作ؓSlave使用Q不q发现在NameNode初始化的q程中以? TaskTracker执行q程中机器名配置好像有冲H(NameNode和TaskTracker对于Hosts的配|有些冲H,I竟是把机器名对? IP攑֜配置前面q是把Localhost对应IP攑֜前面有点问题Q不q可能也是我自己的问题吧Q这个大家可以根据实施情늻我反馈)。最后反正决定一 台MasterQ六台SlaveQ后l复杂的应用开发和试l果的比对会增加机器配置?/p>

实施步骤

  1. 在所有的机器上都建立相同的目录,也可以就建立相同的用P以该用户的home路径来做hadoop的安装\径。例如我在所有的机器上都建立?code>/home/wenchu?/li>
  2. 下蝲HadoopQ先解压到Master上。这里我是下载的0.17.1的版本。此时Hadoop的安装\径就?code>/home/wenchu/hadoop-0.17.1?/li>
  3. 解压后进入conf目录Q主要需要修改以下文Ӟhadoop-env.shQ?code>hadoop-site.xml?code>masters?code>slaves?

    Hadoop的基配置文g?code>hadoop-default.xmlQ看Hadoop的代码可以知道,默认建立一个Job的时候会建立Job的ConfigQConfig首先dhadoop-default.xml的配|,然后再读?code>hadoop-site.xml的配|(q个文g初始的时候配|ؓI)Q?code>hadoop-site.xml中主要配|你需要覆盖的hadoop-default.xml的系l配置Q以及你需要在你的MapReduceq程中用的自定义配|(具体的一些用例如final{参考文档)?/p>

    以下是一个简单的hadoop-site.xml的配|:

    <?xml version="1.0"?>
    <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
    <!-- Put site-specific property overrides in this file. -->
    <configuration>
    <property>
       <name>fs.default.name</name>//你的namenode的配|,机器名加端口
       <value>hdfs://10.2.224.46:54310/</value>
    </property>
    <property>
       <name>mapred.job.tracker</name>//你的JobTracker的配|,机器名加端口
       <value>hdfs://10.2.224.46:54311/</value>
    </property>
    <property>
       <name>dfs.replication</name>//数据需要备份的数量Q默认是?br />    <value>1</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>//Hadoop的默认时\径,q个最好配|,如果在新增节Ҏ者其他情况下莫名其妙的DataNode启动不了Q就删除此文件中的tmp目录卛_。不q如果删除了NameNode机器的此目录Q那么就需要重新执行NameNode格式化的命o?br />     <value>/home/wenchu/hadoop/tmp/</value>
    </property>
    <property>
       <name>mapred.child.java.opts</name>//java虚拟机的一些参数可以参照配|?br />    <value>-Xmx512m</value>
    </property>
    <property>
      <name>dfs.block.size</name>//block的大,单位字节Q后面会提到用处Q必L512的倍数Q因为采用crc作文件完整性校验,默认配置512是checksum的最单元?br />   <value>5120000</value>
      <description>The default block size for new files.</description>
    </property>
    </configuration>

    hadoop-env.sh文g只需要修改一个参敎ͼ

    # The java implementation to use.  Required.
    export JAVA_HOME=/usr/ali/jdk1.5.0_10

    配置你的Java路径Q记住一定要1.5版本以上Q免得莫名其妙出现问题?/p>

    Masters中配|Masters的IP或者机器名Q如果是机器名那么需要在/etc/hosts中有所讄。Slaves中配|的是Slaves的IP或者机器名Q同样如果是机器名需要在/etc/hosts中有所讄。范例如下,我这里配|的都是IPQ?/p>

    Masters:
    10.2.224.46

    Slaves:
    10.2.226.40
    10.2.226.39
    10.2.226.38
    10.2.226.37
    10.2.226.41
    10.2.224.36
  4. 建立Master到每一台Slave的SSH受信证书。由于Master会通过SSH启动所有Slave的HadoopQ所以需要徏立单向或者双向证书保证命令执行时不需要再输入密码。在Master和所有的Slave机器上执行:ssh-keygen -t rsa。执行此命o的时候,看到提示只需要回车。然后就会在/root/.ssh/下面产生id_rsa.pub的证书文Ӟ通过scpMaster机器上的q个文g拯到Slave上(记得修改名称Q,例如Q?code>scp root@masterIP:/root/.ssh/id_rsa.pub /root/.ssh/46_rsa.pubQ然后执?code>cat /root/.ssh/46_rsa.pub >>/root/.ssh/authorized_keysQ徏?code>authorized_keys? 件即可,可以打开q个文g看看Q也是rsa的公钥作为keyQuser@IP作ؓvalue。此时可以试验一下,从master ssh到slave已经不需要密码了。由slave反向建立也是同样。ؓ什么要反向呢?其实如果一直都是Master启动和关闭的话那么没有必要徏立反 向,只是如果惛_Slave也可以关闭Hadoop需要徏立反向?/li>
  5. Master上的Hadoop通过scp拯到每一个Slave相同的目录下Q根据每一个Slave?code>Java_HOME的不同修改其hadoop-env.sh?/li>
  6. 修改Master?code>/etc/profileQ?/code>
    新增以下内容Q(具体的内Ҏ据你的安装\径修改,q步只是Z方便使用Q?br />
    export HADOOP_HOME=/home/wenchu/hadoop-0.17.1
    export PATH=$PATH:$HADOOP_HOME/bin
    修改完毕后,执行source /etc/profile来其生效?/li>
  7. 在Master上执?code>Hadoop namenode –formatQ这是第一需要做的初始化Q可以看作格式化吧,以后除了在上面我提到q删除了Master上的hadoop.tmp.dir目录Q否则是不需要再ơ执行的?/li>
  8. 然后执行Master上的start-all.shQ这个命令可以直接执行,因ؓ?中已l添加到了path路径Q这个命令是启动hdfs和mapreduce两部分,当然你也可以分开单独启动hdfs和mapreduceQ分别是bin目录下的start-dfs.sh?code>start-mapred.sh?/li>
  9. 查Master的logs目录Q看看Namenode日志以及JobTracker日志是否正常启动?/li>
  10. 查Slave的logs目录看看Datanode日志以及TaskTracker日志是否正常?/li>
  11. 如果需要关闭,那么q接执?code>stop-all.sh卛_?/li>

以上步骤可以启动Hadoop的分布式环境Q然后在Master的机器进入Master的安装目录,执行hadoop jar hadoop-0.17.1-examples.jar wordcount输入路径和输\径,可以看到字数统计的效果了。此处的输入路径和输\径都指的是HDFS中的路径Q因此你可以首先通过拯本地文gpȝ中的目录到HDFS中的方式来徏立HDFS中的输入路径Q?/p>

hadoop dfs -copyFromLocal /home/wenchu/test-in test-in?/code>其中/home/wenchu/test-in是本地\径,test-in是将会徏立在HDFS中的路径Q执行完毕以后可以通过hadoop dfs –ls看到test-in目录已经存在Q同时可以通过hadoop dfs –ls test-in查看里面的内宏V输\径要求是在HDFS中不存在的,当执行完那个demo以后Q就可以通过hadoop dfs –ls 输出路径看到其中的内容,具体文g的内容可以通过hadoop dfs –cat文g名称来查看?/p>

l验ȝ和注意事(q部分是我在使用q程中花了一些时间走的弯路)Q?/p>

  1. Master和Slave上的几个conf配置文g不需要全部同步,如果定都是通过Masterd动和关闭Q那么Slave机器上的配置不需要去l护。但如果希望在Q意一台机器都可以启动和关闭HadoopQ那么就需要全部保持一致了?/li>
  2. Master和Slave机器上的/etc/hosts中必L集群中机器都配置上去Q就在各个配置文g? 使用的是IP。这个吃q不苦_原来以ؓ如果配成IP׃需要去配置HostQ结果发现在执行Reduce的时候L卡住Q在拯的时候就无法l箋? 去,不断重试。另外如果集中如果有两台机器的机器名如果重复也会出现问题?/li>
  3. 如果在新增了节点或者删除节点的时候出C问题Q首先就d除Slave?code>hadoop.tmp.dirQ然后重新启动试试看Q如果还是不行那干脆把Master?code>hadoop.tmp.dir删除Q意味着dfs上的数据也会丢失Q,如果删除了Master?code>hadoop.tmp.dirQ那么就需要重?code>namenode –format?/li>
  4. Mapd个数以及Reduced个数配置。前面分布式文gpȝ设计提到一个文件被攑օ到分布式文gpȝ中,会被分割成多个block攄到每一个的DataNode上,默认dfs.block.size应该?4MQ也是说如果你攄到HDFS上的数据于64Q那么将只有一个BlockQ此时会被放|到某一个DataNode中,q个可以通过使用命oQ?code>hadoop dfsadmin –report可以看到各个节点存储的情况。也可以直接L一个DataNode查看目录Q?code>hadoop.tmp.dir/dfs/data/current? 可以看到那些block了。Block的数量将会直接媄响到Map的个数。当然可以通过配置来设定Map和Reduce的Q务个数。Map的个数通常默认 和HDFS需要处理的blocks相同。也可以通过配置Map的数量或者配|minimum split size来设定,实际的个CؓQ?code>max(min(block_size,data/#maps),min_split_size)。Reduce可以通过q个公式计算Q?code>0.95*num_nodes*mapred.tasktracker.tasks.maximum?/li>

ȝ来说Z问题或者启动的时候最好去看看日志Q这样心里有底?/p>

Hadoop中的命oQCommandQȝ

q部分内容其实可以通过命o的Help以及介绍了解Q我主要侧重于介l一下我用的比较多的几个命o。Hadoop dfs q个命o后面加参数就是对于HDFS的操作,和Linux操作pȝ的命令很cMQ例如:

  • Hadoop dfs –ls是查看/usr/root目录下的内容Q默认如果不填\径这是当前用户路径Q?/li>
  • Hadoop dfs –rmr xxx是删除目录Q还有很多命令看看就很容易上手;
  • Hadoop dfsadmin –reportq个命o可以全局的查看DataNode的情况;
  • Hadoop job后面增加参数是对于当前运行的Job的操作,例如list,kill{;
  • Hadoop balancer是前面提到的均衡磁盘负载的命o?/li>

其他׃详细介绍了?/p>

Hadoop基本程

一个图片太大了Q只好分割成Z部分。根据流E图来说一下具体一个Q务执行的情况?/p>

  1. 在分布式环境中客L创徏dq提交?/li>
  2. InputFormat做Map前的预处理,主要负责以下工作Q?br />
    1. 验证输入的格式是否符合JobConfig的输入定义,q个在实现Map和构建Conf的时候就会知道,不定义可以是Writable的Q意子cR?/li>
    2. input的文件切分ؓ逻辑上的输入InputSplitQ其实这是在上面提到的在分布式文gpȝ中blocksize是有大小限制的,因此大文件会被划分ؓ多个block?/li>
    3. 通过RecordReader来再ơ处理inputsplitZlrecordsQ输出给Map。(inputsplit只是逻辑切分的第一步,但是如何Ҏ文g中的信息来切分还需要RecordReader来实玎ͼ例如最单的默认方式是回R换行的切分)
  3. RecordReader处理后的l果作ؓMap的输入,Map执行定义的Map逻辑Q输出处理后的key和value对应C时中间文件?/li>
  4. Combiner可选择配置Q主要作用是在每一个Map执行完分析以后,在本C先作Reduce的工作,减少在Reduceq程中的数据传输量?/li>
  5. Partitioner可选择配置Q主要作用是在多个Reduce的情况下Q指定Map的结果由某一个Reduce处理Q每一个Reduce都会有单独的输出文g。(后面的代码实例中有介l用场景)
  6. Reduce执行具体的业务逻辑Qƈ且将处理l果输出lOutputFormat?/li>
  7. OutputFormat的职责是Q验证输出目录是否已l存在,同时验证输出l果cd是否如Config中配|,最后输出Reduce汇d的结果?/li>

业务场景和代码范?/h2>

业务场景描述Q?/strong>可设定输入和输出路径Q操作系l的路径非HDFS路径Q,Ҏ讉K日志分析某一个应用访问某一个API的L数和L量,l计后分别输出到两个文g中。这里仅仅ؓ了测试,没有ȝ分很多类Q将所有的c都归ƈ于一个类便于说明问题?/p>


试代码cd

LogAnalysiser是ȝQ主要负责创建、提交Q务,q且输出部分信息。内部的几个子类用途可以参看流E中提到的角色职责。具体地看看几个cdҎ的代码片断:

LogAnalysiser::MapClass

    public static class MapClass extends MapReduceBase
        implements Mapper<LongWritable, Text, Text, LongWritable>
    {
        public void map(LongWritable key, Text value, OutputCollector<Text, LongWritable> output, Reporter reporter)
                throws IOException
        {   
            String line = value.toString();//没有配置RecordReaderQ所以默认采用line的实玎ͼkey是行号Qvalue是行内?br />             if (line == null || line.equals(""))
                return;
            String[] words = line.split(",");
            if (words == null || words.length < 8)
                return;
            String appid = words[1];
            String apiName = words[2];
            LongWritable recbytes = new LongWritable(Long.parseLong(words[7]));
            Text record = new Text();
            record.set(new StringBuffer("flow::").append(appid)
                            .append("::").append(apiName).toString());
            reporter.progress();
            output.collect(record, recbytes);//输出量的统计结果,通过flow::作ؓ前缀来标C?br />             record.clear();
            record.set(new StringBuffer("count::").append(appid).append("::").append(apiName).toString());
            output.collect(record, new LongWritable(1));//输出ơ数的统计结果,通过count::作ؓ前缀来标C?br />         }   
    }

LogAnalysiser:: PartitionerClass

    public static class PartitionerClass implements Partitioner<Text, LongWritable>
    {
        public int getPartition(Text key, LongWritable value, int numPartitions)
        {
            if (numPartitions >= 2)//Reduce 个数Q判断流量还是次数的l计分配C同的Reduce
                if (key.toString().startsWith("flow::"))
                    return 0;
                else
                    return 1;
            else
                return 0;
        }
        public void configure(JobConf job){}   
}

LogAnalysiser:: CombinerClass

参看ReduceClassQ通常两者可以用一个,不过q里有些不同的处理就分成了两个。在ReduceClass中蓝色的行表C在CombinerClass中不存在?/p>

LogAnalysiser:: ReduceClass

    public static class ReduceClass extends MapReduceBase
        implements Reducer<Text, LongWritable,Text, LongWritable>
    {
        public void reduce(Text key, Iterator<LongWritable> values,
                OutputCollector<Text, LongWritable> output, Reporter reporter)throws IOException
        {
            Text newkey = new Text();
            newkey.set(key.toString().substring(key.toString().indexOf("::")+2));
            LongWritable result = new LongWritable();
            long tmp = 0;
            int counter = 0;
            while(values.hasNext())//累加同一个key的统计结?br />             {
                tmp = tmp + values.next().get();
               
                counter = counter +1;//担心处理太久QJobTracker长时间没有收到报告会认ؓTaskTracker已经失效Q因此定时报告一?br />                 if (counter == 1000)
                {
                    counter = 0;
                    reporter.progress();
                }
            }
            result.set(tmp);
            output.collect(newkey, result);//输出最后的汇ȝ?br />         }   
    }

LogAnalysiser

	public static void main(String[] args)
{
try
{
run(args);
} catch (Exception e)
{
e.printStackTrace();
}
}
public static void run(String[] args) throws Exception
{
if (args == null || args.length <2)
{
System.out.println("need inputpath and outputpath");
return;
}
String inputpath = args[0];
String outputpath = args[1];
String shortin = args[0];
String shortout = args[1];
if (shortin.indexOf(File.separator) >= 0)
shortin = shortin.substring(shortin.lastIndexOf(File.separator));
if (shortout.indexOf(File.separator) >= 0)
shortout = shortout.substring(shortout.lastIndexOf(File.separator));
SimpleDateFormat formater = new SimpleDateFormat("yyyy.MM.dd");
shortout = new StringBuffer(shortout).append("-")
.append(formater.format(new Date())).toString();


if (!shortin.startsWith("/"))
shortin = "/" + shortin;
if (!shortout.startsWith("/"))
shortout = "/" + shortout;
shortin = "/user/root" + shortin;
shortout = "/user/root" + shortout;
File inputdir = new File(inputpath);
File outputdir = new File(outputpath);
if (!inputdir.exists() || !inputdir.isDirectory())
{
System.out.println("inputpath not exist or isn't dir!");
return;
}
if (!outputdir.exists())
{
new File(outputpath).mkdirs();
}

JobConf conf = new JobConf(new Configuration(),LogAnalysiser.class);//构徏Config
FileSystem fileSys = FileSystem.get(conf);
fileSys.copyFromLocalFile(new Path(inputpath), new Path(shortin));//本地文件系l的文g拯到HDFS?br />
conf.setJobName("analysisjob");
conf.setOutputKeyClass(Text.class);//输出的keycdQ在OutputFormat会检?br /> conf.setOutputValueClass(LongWritable.class); //输出的valuecdQ在OutputFormat会检?br /> conf.setMapperClass(MapClass.class);
conf.setCombinerClass(CombinerClass.class);
conf.setReducerClass(ReduceClass.class);
conf.setPartitionerClass(PartitionerClass.class);
conf.set("mapred.reduce.tasks", "2");//强制需要有两个Reduce来分别处理流量和ơ数的统?br /> FileInputFormat.setInputPaths(conf, shortin);//hdfs中的输入路径
FileOutputFormat.setOutputPath(conf, new Path(shortout));//hdfs中输\?br />
Date startTime = new Date();
System.out.println("Job started: " + startTime);
JobClient.runJob(conf);
Date end_time = new Date();
System.out.println("Job ended: " + end_time);
System.out.println("The job took " + (end_time.getTime() - startTime.getTime()) /1000 + " seconds.");
//删除输入和输出的临时文g
fileSys.copyToLocalFile(new Path(shortout),new Path(outputpath));
fileSys.delete(new Path(shortin),true);
fileSys.delete(new Path(shortout),true);
}

以上的代码就完成了所有的逻辑性代码,然后q需要一个注册驱动类来注册业务ClassZ个可标示的命令,让hadoop jar可以执行?/p>

public class ExampleDriver {
  public static void main(String argv[]){
    ProgramDriver pgd = new ProgramDriver();
    try {
      pgd.addClass("analysislog", LogAnalysiser.class, "A map/reduce program that analysis log .");
      pgd.driver(argv);
    }
    catch(Throwable e){
      e.printStackTrace();
    }
  }
}

代码打成jarQƈ且设|jar的mainClass为ExampleDriverq个cR在分布式环境启动以后执行如下语句:

hadoop jar analysiser.jar analysislog /home/wenchu/test-in /home/wenchu/test-out

?home/wenchu/test-in中是需要分析的日志文gQ执行后׃看见整个执行q程Q包括了Map和Reduce的进度。执行完毕会 ?home/wenchu/test-out下看到输出的内容。有两个文gQpart-00000和part-00001分别记录了统计后的结果? 如果需要看执行的具体情况,可以看在输出目录下的_logs/history/xxxx_analysisjobQ里面罗列了所有的MapQReduce 的创建情况以及执行情c在q行期也可以通过览器来查看Map,Reduce的情况:http://MasterIP:50030 /jobtracker.jsp

Hadoop集群试

首先q里使用上面的范例作为测试,也没有做太多的优化配|,q个试l果只是Z看看集群的效果,以及一些参数配|的影响?/p>

文g复制Cؓ1Qblocksize 5M

Slave?/td> 处理记录?万条) 执行旉Q秒Q?/td>
2 95 38
2 950 337
4 95 24
4 950 178
6 95 21
6 950 114

Blocksize 5M

Slave?/td> 处理记录?万条) 执行旉Q秒Q?/td>
2Q文件复制数?Q?/td> 950 337
2Q文件复制数?Q?/td> 950 339
6Q文件复制数?Q?/td> 950 114
6Q文件复制数?Q?/td> 950 117

文g复制Cؓ1

Slave?/td> 处理记录?万条) 执行旉Q秒Q?/td>
6(blocksize 5M) 95 21
6(blocksize 77M) 95 26
4(blocksize 5M) 950 178
4(blocksize 50M) 950 54
6(blocksize 5M) 950 114
6(blocksize 50M) 950 44
6(blocksize 77M) 950 74

试的数据结果很E_Q基本测几次同样条g下都是一栗通过试l果可以看出以下几点Q?/p>

  1. 机器数对于性能q是有帮助的Q等于没说^_^Q?/li>
  2. 文g复制数的增加只对安全性有帮助Q但是对于性能没有太多帮助。而且现在采取的是操作系l文件拷贝到HDFS中,所以备份多了,准备的时间很ѝ?/li>
  3. blocksize对于性能影响很大Q首先如果将block划分的太,那么会增加job的数量,同时也增加了协作的代P降低了性能Q但是配|的太大也会让job不能最大化q行处理。所以这个值的配置需要根据数据处理的量来考虑?/li>
  4. 最后就是除了这个表里面列出来的l果Q应该去仔细看输出目录中的_logs/history中的xxx_analysisjobq个文gQ里面记录了全部的执行过E以及读写情c这个可以更加清楚地了解哪里可能会更加耗时?/li>

随想

“云计?#8221;热的烫手Q就和SAAS、Web2及SNS{一P往往都是在搞概念Q只有真正踏t实实的大型互联|公司,才会投入人力物力ȝI符合自 q分布式计。其实当你的数据量没有那么大的时候,q种分布式计也׃仅只是一个玩兯已Q只有在真正解决问题的过E中Q它深层ơ的问题才会被挖掘出 来?/p>

q三文章(分布式计开源框架Hadoop介绍QHadoop中的集群配置和用技巧)仅仅是ؓ了给对分布式计算有兴的朋友抛个砖,要想真的掘到? 子,那么pt实实的ȝ、去惟뀁去分析。或者自׃会更q一步地ȝI框架中的实现机Ӟ在解册己问题的同时Q也能够贡献一些什么?/p>

前几日看到有求成为架构师的方式,看了有些可悲Q有些可W,其实有多架构师知道什么叫做架构?架构师的职责是什么?与其q求q么一个名Pq不如踏t实实地做块矛_沉到水底。要知道Q积累和沉淀的过E就是一U成ѝ?/p>


















西瓜 2010-10-22 15:21 发表评论
]]>Hadoop-- 量文g的分布式计算处理Ҏhttp://m.tkk7.com/ashutc/archive/2010/10/22/335863.html西瓜西瓜Fri, 22 Oct 2010 02:55:00 GMThttp://m.tkk7.com/ashutc/archive/2010/10/22/335863.htmlhttp://m.tkk7.com/ashutc/comments/335863.htmlhttp://m.tkk7.com/ashutc/archive/2010/10/22/335863.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/335863.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/335863.htmlMapReduce? 一个Java实现。MapReduce是一U简化的分布式编E模式,让程序自动分布到一个由普通机器组成的大集群上ƈ发执行。就如同javaE序员可? 不考虑内存泄露一P MapReduce的run-timepȝ会解册入数据的分布l节Q跨机器集的E序执行调度Q处理机器的失效Qƈ且管理机器之间的通讯h。这L 模式允许E序员可以不需要有什么ƈ发处理或者分布式pȝ的经验,可以处理超大的分布式系l得资源?

    一、概?/h2>

    作ؓHadoopE序员,他要做的事情是Q?br />     1、定义MapperQ处理输入的Key-Value对,输出中间l果?br />     2、定义ReducerQ可选,对中间结果进行规U,输出最l结果?br />     3、定义InputFormat 和OutputFormatQ可选,InputFormat每行输入文件的内容转换为JavacMMapper函数使用Q不定义旉认ؓString?br />     4、定义main函数Q在里面定义一个Jobq运行它?br />    

    然后的事情就交给pȝ了?br />     1.基本概念QHadoop的HDFS实现了google的GFS文gpȝQNameNode作ؓ文gpȝ的负责调度运行在 masterQDataNodeq行在每个机器上。同时Hadoop实现了Google的MapReduceQJobTracker作ؓ MapReduce的总调度运行在masterQTaskTracker则运行在每个机器上执行Task?br />
    2.main()函数Q创建JobConfQ定义MapperQReducerQInput/OutputFormat 和输入输出文件目录,最后把Job提交iJobTrackerQ等待Jobl束?br />
    3.JobTrackerQ创Z个InputFormat的实例,调用它的getSplits()ҎQ把输入目录的文件拆分成FileSplist作ؓMapper task 的输入,生成Mapper task加入Queue?br />
    4.TaskTracker ?JobTracker索求下一个Map/Reduce?br />       
     Mapper Task先从InputFormat创徏RecordReaderQ@环读入FileSplits的内容生成Key与ValueQ传lMapper函数Q处理完后中间结果写成SequenceFile.
     Reducer Task 从运行Mapper的TaskTracker的Jetty上用http协议获取所需的中间内容(33%Q,Sort/Merge后(66%Q,执行Reducer函数Q最后按照OutputFormat写入l果目录?

      TaskTracker ?0U向JobTracker报告一ơ运行情况,每完成一个Task10U后Q就会向JobTracker索求下一个Task?/p>

      Nutch目的全部数据处理都构徏在Hadoop之上Q详?a >Scalable Computing with Hadoop?/p>


    二、程序员~写的代?/h2>

    我们做一个简单的分布式的GrepQ简单对输入文gq行逐行的正则匹配,如果W合将该行打印到输出文件。因为是单的全部输出Q所以我们只要写Mapper函数Q不用写Reducer函数Q也不用定义Input/Output Format?/p>

package  demo.hadoop

public
  class  HadoopGrep {

 
public   static   class  RegMapper  extends  MapReduceBase  implements  Mapper {

  
private  Pattern pattern;

  
public   void  configure(JobConf job) {
   pattern 
=  Pattern.compile(job.get( " mapred.mapper.regex " ));
  }

  
public   void  map(WritableComparable key, Writable value, OutputCollector output, Reporter reporter)
    
throws  IOException {
   String text 
=  ((Text) value).toString();
   Matcher matcher 
=  pattern.matcher(text);
   
if  (matcher.find()) {
    output.collect(key, value);
   }
  }
 }

 
private  HadoopGrep () {
 } 
//  singleton

 
public   static   void  main(String[] args)  throws  Exception {
  
  JobConf grepJob 
=   new  JobConf(HadoopGrep. class );
  grepJob.setJobName(
" grep-search " );
  grepJob.set(
" mapred.mapper.regex " , args[ 2 ]);

  grepJob.setInputPath(
new  Path(args[ 0 ]));
  grepJob.setOutputPath(
new  Path(args[ 1 ]));
  grepJob.setMapperClass(RegMapper.
class );
  grepJob.setReducerClass(IdentityReducer.
class );
      
  JobClient.runJob(grepJob);
 }
}

        RegMappercȝconfigure()函数接受由main函数传入的查扑֭W串Qmap() 函数q行正则匚wQkey是行敎ͼvalue是文件行的内容,W合的文件行攑օ中间l果?br />         main()函数定义由命令行参数传入的输入输出目录和匚w字符ԌMapper函数为RegMapperc,Reduce函数是什么都不做Q直接把中间l果输出到最l结果的的IdentityReducerc,q行Job?/p>


        整个代码非常单,丝毫没有分布式编E的Ml节?/strong>


       ?q行HadoopE序

        Hadoopq方面的文档写得不全面,l合参?a >GettingStartedWithHadoop ?u>Nutch Hadoop Tutorial 两篇后,再碰了很多钉子才l于完整的跑h了,记录如下Q?nbsp;     

3.1 localq行模式

       完全不进行Q何分布式计算Q不动用Mnamenode,datanode的做法,适合一开始做调试代码?br />        解压hadoopQ其中conf目录是配|目录,hadoop的配|文件在hadoop-default.xmlQ如果要修改配置Q不是直接修改该文gQ而是修改hadoop-site.xmlQ将该属性在hadoop-site.xml里重新赋倹{?br />        hadoop-default.xml的默认配|已l是localq行Q不用Q何修改,配置目录里唯一必须修改的是hadoop-env.sh ?font face="Courier New">JAVA_HOME的位|?/p>


       编译好的HadoopGrep与RegMapper.class 攑օhadoop/build/classes/demo/hadoop/目录 找一个比较大的log文g攑օ一个目录,然后q行

       hadoop / bin / hadoop demo.hadoop.HadoopGrep log文g所在目?nbsp;L的输出目?nbsp;grep的字W串


     查看输出目录的结果,查看hadoop/logs/里的q行日志?nbsp; 
     在重新运行前Q先删掉输出目录?br />  

3.2 单机集群q行模式

       现在来搞一下只有单机的集群.假设以完?.1中的讄Q本机名为hadoopserver
       W??    然后修改hadoop-site.xml Q加入如下内容:

< property >
  
< name > fs.default.name </ name >
  
< value > hadoopserver:9000 </ value >
</ property >
< property >
  
< name > mapred.job.tracker </ name >
  
< value > hadoopserver:9001 </ value >
</ property >
< property >
  
< name > dfs.replication </ name >
  
< value > 1 </ value >
</ property >


    从此将q行从local文gpȝ转向了hadoop的hdfspȝQmapreduce的jobtracker也从local的进E内操作变成了分布式的Q务系l,9000Q?001两个端口h随便选择的两个空余端口号?br />  
  另外Q如果你?tmp目录不够大,可能q要修改hadoop.tmp.dir属性?/p>


  W?? 增加ssh不输入密码即可登陆?br />
    因ؓHadoop需要不用输入密码的ssh来进行调度,在不su的状态下Q在自己的home目录q行ssh-keygen -t rsa ,然后一路回车生成密钥,再进?ssh目录,cp id_rsa.pub authorized_keys
    详细可以man 一下ssh, 此时执行ssh hadoopserverQ不需要输入Q何密码就能进入了?/p>

  3.格式化namenodeQ执?br />   bin/hadoop namenode -format

  4.启动Hadoop
     执行hadoop/bin/start-all.sh, 在本机启动namenode,datanode,jobtracker,tasktracker
 
  5.现在待查找的log文g攑օhdfs,?br />      执行hadoop/bin/hadoop dfs 可以看到它所支持的文件操作指令?br />      执行hadoop/bin/hadoop dfs put log文g所在目?in Q则log文g目录已放入hdfs?user/user-name/in 目录?/p>

  6.现在来执行Grep操作
      hadoop/bin/hadoop demo.hadoop.HadoopGrep in out
      查看hadoop/logs/里的q行日志Q重新执行前。运行hadoop/bin/hadoop dfs rmr out 删除out目录?br />
  7.q行hadoop/bin/stop-all.sh l束

  3.3 集群q行模式
  假设已执行完3.2的配|,假设W?台机器名是hadoopserver2
  1.创徏与hadoopserver同样的执行用Phadoop解压到相同的目录?br />
  2.同样的修改haoop-env.sh中的JAVA_HOME 及修改与3.2同样的hadoop-site.xml

  3. hadoopserver中的/home/username/.ssh/authorized_keys 复制到hadoopserver2,保证hadoopserver可以无需密码登陆hadoopserver2
     scp /home/username/.ssh/authorized_keys  username@hadoopserver2:/home/username/.ssh/authorized_keys
 
  4.修改hadoop-server的hadoop/conf/slaves文g, 增加集群的节点,localhost改ؓ
    hadoop-server
    hadoop-server2

  5.在hadoop-server执行hadoop/bin/start-all.sh
   会在hadoop-server启动namenode,datanode,jobtracker,tasktracker
   在hadoop-server2启动datanode 和tasktracker
 
  6.现在来执行Grep操作
     hadoop/bin/hadoop demo.hadoop.HadoopGrep in out
    重新执行?q行hadoop/bin/hadoop dfs rmr out 删除out目录

  7.q行hadoop/bin/stop-all.sh l束?br />    

四、效?/h2>

    l测试,Hadoopq不是万用灵丹,很取决于文g的大和数量Q处理的复杂度以及群集机器的数量Q相q的带宽Q当以上四者ƈ不大Ӟhadoop优势q不明显?br />     比如Q不用hadoop用java写的单grep函数处理100M的log文g只要4U,用了hadoop local的方式运行是14U,用了hadoop单机集群的方式是30U,用双机集?0M|口的话更慢Q慢C好意思说出来的地步?/p>

西瓜 2010-10-22 10:55 发表评论
]]> վ֩ģ壺 AVƬ߹ۿ | ޾ƷĻ| ѹۿ߹ۿİ| ޾þþþþAV| һëƬѿ| ޵һվ߹ۿ| ѹۿĻƷ| AVһþ| ɫëƬƵ| һĹ˾| aëƬƵѹۿ| avһ| þw5www| ۺУ԰ɫ| ҹӰӴȫѹۿ| 㽶Ƶһ| պһ234| ߿Ƭ˳Ƶ| ༤ۺ͵ | պŷһ| Ʒѹһ| ҹӰȫѿ| AVһ| ˾ƷƵ| Ʒһ߹ۿ | ɫ͵͵޵һۺ| þɫһ| һëƬѿѲ| ޵ҹ| ᰡͣѿ| 9ֻоƷ| ձvaҹĻһ| Ƶѹۿ| ɫվ߿| Av뾫Ʒɫҹ| ëƬƵѹۿ| ߾ƷaaaƬ| רҳ| Av뾫Ʒ| һ˿www߸ѿ| Ʒ1024 |