??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久久久久综合日本亚洲,久久精品国产99国产精品,国内精品久久久久久久久电影网 http://m.shnenglu.com/mysileng/category/20280.htmlzh-cnTue, 25 Jun 2013 03:41:55 GMTTue, 25 Jun 2013 03:41:55 GMT60hadoop0.20.2在eclipse中的~译http://m.shnenglu.com/mysileng/archive/2013/06/24/201276.html鑫龙鑫龙Mon, 24 Jun 2013 10:58:00 GMThttp://m.shnenglu.com/mysileng/archive/2013/06/24/201276.htmlhttp://m.shnenglu.com/mysileng/comments/201276.htmlhttp://m.shnenglu.com/mysileng/archive/2013/06/24/201276.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/201276.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/201276.html1. 下蝲Hadoop源代?br />Hadoop 各成员源代码下蝲地址Q?a style="color: #336699; text-decoration: initial;">http://svn.apache.org/repos/asf/hadoopQ请使用SVN下蝲Q在SVN览器中trunk目录下的源代码check-out 出来卛_。请注意只check-out出SVN 上的tag 目录下的内容Q如Q?br />http://svn.apache.org/repos/asf/hadoop/common/tag/release-0.20.2Q?/p>


2. 准备~译环境

2.1. pȝ

CentOS5.5

2.2. Hadoop代码版本
hadoop-0.20.2-release

2.3. 联网
~译Hadoop 会依赖很多第三方库,但编译工具Ant 会自动从|上下蝲~少的库Q所以必M证机器能够访问Internet?br />2.4. java
~译Hadoop要用JDK1.6 以上Q网址Q?a style="color: #336699; text-decoration: initial;">http://java.sun.com/javase/downloads/index.jsp?br />安装好之后,误|好JAVA_HOME 环境变量?br />2.5. Ant 
需要用Ant 工具来编译HadoopQ可以从Q?a style="color: #336699; text-decoration: initial;">http://ant.apache.org/ivy/download.cgi 下蝲Ant

安装好之后,误|好ANT_HOME 环境变量?/p>

2.6. Eclipse

Eclipse 则可以从http://www.eclipse.org/downloads/上下载?/p>

 

3. ~译Hadoop

3.1. ~译Hadoop
步骤1) 在Elipse 的Package 视图中单d键,选择New->Java ProjectQ如下图所C:

在上图所C的对话框中Q点击Browse 按钮Q选择hadoop-0.20.2 源代码目录,q设|Projectname 为hadoop-0.20.2-dev。工E导入完成后Q进入Eclipse ȝ面,可以看到hadoop-0.20.2 已经导入q来Q但可以看到目录上有U叉叉,是因为Elipse默认使用了Java BuilderQ而不是Ant BuilderQ所以下一步就是设|用Ant Builder?/p>


步骤3) 讄Builder 为AntQ右键hadoop-0.20.2-dev>Properties->Builders:


点击Browse File System 按钮Q选择hadoop-0.20.2源代码目录下的build.xml 文gQƈ讄Name 为Ant_BuilderQName 可以Ҏ其它的,但徏议用Ant_BuilderQ因样名副其实)Q操作结果如下图所C:

Hadoop 各成员都需要编译成jarQ所以做如下图所C的一个修改:

上面完成后,回到Builder 的主对话框,再将对话框中的Java Builder 下移Qƈ它前面的勾L?/span>
q入Eclipse ȝ面,׃之前选择了Manual BuildQ所以需要h工方式驱动编译,~译成功后,可以看到BUILDSUCCESSFUL 字样?/span>

 h意:如果上图所C的菜单中的BuildAutomatically 被勾中,则在common的右键菜单中可能不会出现Build 子菜单?br />      在编译过E中QAnt 会自动从|上下蝲所依赖的库。hadoop-0.20.2 ~译成功l束后,可以在build 目录下找到编译后生成的文件hadoop-core-0.20.2-dev.jar?/p>

 

3.2~译q程中出现错?/strong>


1、可能有时候因为eclipse版本或者操作系l版本的问题使得hadoop提供的eclipse plugin不太好用?br />解决ҎQ?br />1Q修?HADOOP_HOME/src/contrib/build-contrib.xml
增加一行:<propertyname="eclipse.home" location="/home/gushui/eclipse"/>
上句后面?home/gushui/eclipsepq$ECLIPSE_HOME代替

2Q修?HADOOP_HOME/src/contrib/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/HadoopApplicationLaunchShortcut.java
注释掉原来的//importorg.eclipse.jdt.internal.debug.ui.launcher.JavaApplicationLaunchShortcut;
改ؓimportorg.eclipse.jdt.debug.ui.launchConfigurations.JavaApplicationLaunchShortcut;

2、报错:

Buildfailed

Cannot write to the specified tarfile!

解决ҎQ?/p>

hadoop-0.20.2-dev目录下的Build.xml?br /><!--    
<tar compression="gzip"destfile="${build.classes}/bin.tgz">
      <tarfileset dir="bin"mode="755"/>
    </tar>  
 -->

注销掉,q行成功?/p>

 

参?nbsp;http://blog.csdn.net/basicthinker/article/details/6174442   

参考: http://hi.baidu.com/xxjjyy2008/blog/item/7b5ed10f20e6a9346059f335.html

参考:http://hadoop.hadoopor.com/thread-941-1-1.html

http://trac.nchc.org.tw/cloud/wiki/waue/2010/0211



转自http://www.cnblogs.com/zyumeng/archive/2013/03/22/2975165.html



鑫龙 2013-06-24 18:58 发表评论
]]>
在HADOOP中用MRUNITq行单元试http://m.shnenglu.com/mysileng/archive/2013/04/03/199065.html鑫龙鑫龙Wed, 03 Apr 2013 03:27:00 GMThttp://m.shnenglu.com/mysileng/archive/2013/04/03/199065.htmlhttp://m.shnenglu.com/mysileng/comments/199065.htmlhttp://m.shnenglu.com/mysileng/archive/2013/04/03/199065.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/199065.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/199065.html本文地址Q博客园 逖靖?nbsp;http://gpcuster.cnblogs.com

前提

1. 了解JUnit4.x的用?/span>
2. 了解Mock的概念在单元试中的应用?/span>
3. 了解Hadoop中MapReduce的编E模型?/span>

    如果您对Junit和Mock不了解,可以先阅?a style="color: #993300;">[译]Unit testing with JUnit 4.x and EasyMock in Eclipse - Tutorial?/p>

    如果您对Hadoop中MapReduce的编E模型不了解Q可以先阅读Map/Reduce Tutorial?/p>

    介绍

    MRUnit是一ƄCouldera公司开发的专门针对Hadoop中编写MapReduce单元试的框架?/p>

    它可以用?.18.x版本中的l典org.apache.hadoop.mapred.*的模型,也能?.20.x版本org.apache.hadoop.mapreduce.*的新模型中用?/p>

    官方的介l如下:

    MRUnit is a unit test library designed to facilitate easy integration between your MapReduce development process and standard development and testing tools such as JUnit. MRUnit contains mock objects that behave like classes you interact with during MapReduce execution (e.g., InputSplit and OutputCollector) as well as test harness "drivers" that test your program's correctness while maintaining compliance with the MapReduce semantics. Mapper and Reducer implementations can be tested individually, as well as together to form a full MapReduce job.

    安装

    在目前Hadoop的发行版中,q没有默认包含MRUnit。你需要去Couldera公司的官|中M载一个由他们再次发行的版本?/p>

    推荐的版本ؓQ?a style="color: #993300;">hadoop-0.20.1+133.tar.gz?/p>

    下蝲q个文g后,你将在hadoop-0.20.1+133\contrib\mrunit目录中找到我们需要的jar包:hadoop-0.20.1+133-mrunit.jar?/p>

    Z使用MRUnitQ我们需要将hadoop-0.20.1+133-mrunit.jar和Junit4.x使用的jar包:junit.jar都添加到我们开发HadoopE序目的classpath中?/p>

    CZ

    代码是最好的文档Q我们先看一个简单的map单元试CZQ代码如下:

    package gpcuster.cnblogs.com;

    import junit.framework.TestCase;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapred.Mapper;
    import org.apache.hadoop.mapred.lib.IdentityMapper;
    import org.junit.Before;
    import org.junit.Test;
    import org.apache.hadoop.mrunit.MapDriver;

    public class TestExample extends TestCase {

    private Mapper<Text, Text, Text, Text> mapper;
    private MapDriver<Text, Text, Text, Text> driver;

    @Before
    public void setUp() {
    mapper = new IdentityMapper<Text, Text>();
    driver = new MapDriver<Text, Text, Text, Text>(mapper);
    }

    @Test
    public void testIdentityMapper() {
    driver.withInput(new Text("foo"), new Text("bar"))
    .withOutput(new Text("foo"), new Text("bar"))
    .runTest();
    }
    }

    在这D늤例代码中Q我们用的map是org.apache.hadoop.mapred.lib.IdentityMapper。这是一个非常简单的map函数Q输入什么,pZ么?/p>

    org.apache.hadoop.mrunit.MapDriver是我们从MRUnit框架中导入的一个专门用于测试map的类?/p>

    我们通过withInput指定输入的参敎ͼ通过withOutput指定我们期望的输出,然后通过runTestq行我们的测试?/p>

    功能

    1. 试MapQ我们可以用MapDriver?/span>
    2. 试ReduceQ我们可以用ReduceDriver?/span>
    3. 试一个完整的MapReduceQ我们可以用MapReduceDriver?/span>
    4. 试多个MapReducel合而成的操作,我们可以使用PipelineMapReduceDriver?/span>

      实现

      MRUnit框架非常_Q其核心的单元测试依赖于JUnit?/p>

      ׃我们~写的MapReduce函数中包含有一个OutputCollector的对象,所以MRUnit自己实现了一套Mock对象来控制OutputCollector的操作?/p>

      局?/h2>

      通过阅读MRUnit的源代码我们会发玎ͼ

      1. 不支持MapReduce框架中的分区和排序操作:从Map输出的值经qshuffle处理后直接就导入Reduce中了?/span>
      2. 不支持Streaming实现的MapReduce操作?/span>

        虽然MRUnit有这些局限,但是以完成大多数的需求?/p>

        参考资?/h2>

        http://www.cloudera.com/hadoop-mrunit

         

        本文地址Q博客园 逖靖?nbsp;http://gpcuster.cnblogs.com



        鑫龙 2013-04-03 11:27 发表评论
        ]]>Mapreduce-Partition分析http://m.shnenglu.com/mysileng/archive/2013/04/01/199028.html鑫龙鑫龙Mon, 01 Apr 2013 13:10:00 GMThttp://m.shnenglu.com/mysileng/archive/2013/04/01/199028.htmlhttp://m.shnenglu.com/mysileng/comments/199028.htmlhttp://m.shnenglu.com/mysileng/archive/2013/04/01/199028.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/199028.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/199028.html阅读全文

        鑫龙 2013-04-01 21:10 发表评论
        ]]>
        hadoop namenode启动q程详细剖析及瓶颈分?/title><link>http://m.shnenglu.com/mysileng/archive/2013/03/28/198897.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Thu, 28 Mar 2013 10:52:00 GMT</pubDate><guid>http://m.shnenglu.com/mysileng/archive/2013/03/28/198897.html</guid><wfw:comment>http://m.shnenglu.com/mysileng/comments/198897.html</wfw:comment><comments>http://m.shnenglu.com/mysileng/archive/2013/03/28/198897.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/mysileng/comments/commentRss/198897.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/mysileng/services/trackbacks/198897.html</trackback:ping><description><![CDATA[<h2>NameNode中几个关键的数据l构</h2><h3>FSImage</h3><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">Namenode会将HDFS的文件和目录元数据存储在一个叫fsimage的二q制文g中,每次保存fsimage之后Cơ保存之间的所有hdfs操作Q将会记录在editlog文g中,当editlog辑ֈ一定的大小QbytesQ由fs.checkpoint.size参数定义Q或从上ơ保存过后一定时间段q后QsecQ由fs.checkpoint.period参数定义Q,namenode会重新将内存中对整个HDFS的目录树和文件元数据刷到fsimage文g中。Namenode是通过q种方式来保证HDFS中元数据信息的安全性?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">Fsimage是一个二q制文gQ当中记录了HDFS中所有文件和目录的元数据信息Q在我的hadoop的HDFS版中Q该文g的中保存文g和目录的格式如下Q?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><img src="http://hi.csdn.net/attachment/201008/26/0_128283242641Uj.gif" alt="" width="909" height="111" style="margin: 0px; padding: 0px; border: none; " /></p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "> </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">当namenode重启加蝲fsimageӞ是按照如下格式协议从文件流中加载元数据信息。从fsimag的存储格式可以看出,fsimage保存有如下信息:</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">1.         首先是一个image headQ其中包含:</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">a)         imgVersion(int)Q当前image的版本信?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">b)        namespaceID(int)Q用来确保别的HDFS instance中的datanode不会误连上当前NN?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">c)         numFiles(long)Q整个文件系l中包含有多文件和目录</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">d)        genStamp(long)Q生成该image时的旉戳信息?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">2.         接下来便是对每个文g或目录的源数据信息,如果是目录,则包含以下信息:</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">a)         path(String)Q该目录的\径,?#8221;/user/build/build-index”</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">b)        replications(short)Q副本数Q目录虽然没有副本,但这里记录的目录副本C?Q?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">c)         mtime(long)Q该目录的修Ҏ间的旉戳信?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">d)        atime(long)Q该目录的访问时间的旉戳信?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">e)         blocksize(long)Q目录的blocksize都ؓ0</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">f)         numBlocks(int)Q实际有多少个文件块Q目录的该值都?1Q表Citem为目?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">g)        nsQuota(long)Qnamespace Quota|若没加Quota限制则ؓ-1</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">h)        dsQuota(long)Qdisk Quota|若没加限制则也ؓ-1</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">i)          username(String)Q该目录的所属用户名</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">j)          group(String)Q该目录的所属组</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">k)        permission(short)Q该目录的permission信息Q如644{,有一个short来记录?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">3.         若从fsimage中读到的item是一个文Ӟ则还会额外包含如下信息:</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">a)         blockid(long)Q属于该文g的block的blockidQ?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">b)        numBytes(long)Q该block的大?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">c)         genStamp(long)Q该block的时间戳</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">当该文g对应的numBlocksC?Q而是大于1Ӟ表示该文件对应有多个block信息Q此时紧接在该fsimage之后的就会有多个blockidQnumBytes和genStamp信息?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">因此Q在namenode启动Ӟ需要对fsimage按照如下格式q行序的加载,以将fsimage中记录的HDFS元数据信息加载到内存中?/p><h3>BlockMap</h3><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">从以上fsimage中加载如namenode内存中的信息中可以很明显的看出,在fsimage中,q没有记录每一个block对应到哪几个datanodes的对应表信息Q而只是存储了所有的关于namespace的相关信息。而真正每个block对应到datanodes列表的信息在hadoop中ƈ没有q行持久化存储,而是在所有datanode启动Ӟ每个datanodeҎ地磁盘进行扫描,本datanode上保存的block信息汇报lnamenodeQnamenode在接收到每个datanode的块信息汇报后,接收到的块信息Q以及其所在的datanode信息{保存在内存中。HDFS是通过q种块信息汇报的方式来完?nbsp;block -> datanodes list的对应表构徏。Datanode向namenode汇报块信息的q程叫做<strong style="margin: 0px; padding: 0px; ">blockReport</strong>Q而namenodeblock -> datanodes list的对应表信息保存在一个叫<strong style="margin: 0px; padding: 0px; ">BlocksMap</strong>的数据结构中?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">BlocksMap的内部数据结构如下:   </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><img src="http://hi.csdn.net/attachment/201008/26/0_1282832577NUG7.gif" alt="" style="margin: 0px; padding: 0px; border: none; " />              </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "> </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">如上图显C,BlocksMap实际上就是一个Block对象对BlockInfo对象的一个Map表,其中Block对象中只记录了blockidQblock大小以及旉戳信息,q些信息在fsimage中都有记录。而BlockInfo是从Block对象l承而来Q因此除了Block对象中保存的信息外,q包括代表该block所属的HDFS文g的INodeFile对象引用以及该block所属datanodes列表的信息(即上图中的DN1QDN2QDN3Q该数据l构会在下文详述Q?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">因此在namenode启动q加载fsimage完成之后Q实际上BlocksMap中的keyQ也是Block对象都已l加载到BlocksMap中,每个key对应的value(BlockInfo)中,除了表示其所属的datanodes列表的数lؓI外Q其他信息也都已l成功加载。所以可以说Qfsimage加蝲完毕后,BlocksMap中仅~少每个块对应到其所属的datanodes list的对应关pM息。所~些信息,是通过上文提到的从各datanode接收<strong style="margin: 0px; padding: 0px; ">blockReport</strong>来构建。当所有的datanode汇报lnamenode的blockReport处理完毕后,BlocksMap整个l构也就构徏完成?/p><h3>BlockMap中datanode列表数据l构</h3><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">在BlockInfo中,该block所属的datanodes列表保存在一个Object[]数组中,但该数组不仅仅保存了datanodes列表Q还包含了额外的信息。实际上该数l保存了如下信息Q?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><img src="http://hi.csdn.net/attachment/201008/26/0_1282832653nh2L.gif" alt="" style="margin: 0px; padding: 0px; border: none; " /></p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "> </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">上图表示一个block包含有三个副本,分别攄在DN1QDN2和DN3三个datanode上,每个datanode对应一个三元组Q该三元l中的第二个元素Q即上图中prev block所指的是该block在该datanode上的前一个BlockInfo引用。第三个元素Q也是上图中next Block所指的是该block在该datanode上的下一个BlockInfo引用。每个block有多个副本Q其对应的BlockInfo对象中就会有多少个这U三元组?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">       Namenode采用q种l构来保存block->datanode list的目的在于节Unamenode内存。由于namenodeblock->datanodes的对应关pM存在了内存当中,随着HDFS中文件数的增加,blockC会相应的增加QnamenodeZ保存block->datanodes的信息已l耗费了相当多的内存,如果q像q种方式一L保存datanode->block list的对应表Q势必耗费更多的内存,而且在实际应用中Q要查一个datanode上保存的block list的应用实际上非常的少Q大部分情况下是要根据block来查datanode列表Q所以namenode中通过上图的方式来保存block->datanode list的对应关p,当需要查询datanode->block list的对应关pLQ只需要沿着该数据结构中next Block的指向关p,p得出l果Q而又无需保存datanode->block list在内存中?/p><h2>NameNode启动q程</h2><h3>fsimage加蝲q程</h3><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">Fsimage加蝲q程完成的操作主要是ZQ?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">1.         从fsimage中读取该HDFS中保存的每一个目录和每一个文?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">2.         初始化每个目录和文g的元数据信息</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">3.         Ҏ目录和文件的路径Q构造出整个namespace在内存中的镜?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">4.         如果是文Ӟ则读取出该文件包含的所有blockidQƈ插入到BlocksMap中?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">整个加蝲程如下图所C:</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><img src="http://hi.csdn.net/attachment/201008/26/0_1282832793TFNr.gif" alt="" style="margin: 0px; padding: 0px; border: none; " /></p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "> </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">如上图所C,namenode在加载fsimageq程其实非常单,是从fsimage中不停的序d文g和目录的元数据信息,q在内存中构建整个namespaceQ同时将每个文g对应的blockid保存入BlocksMap中,此时BlocksMap中每个block对应的datanodes列表暂时为空。当fsimage加蝲完毕后,整个HDFS的目录结构在内存中就已经初始化完毕,所~的是每个文g对应的block对应的datanode列表信息。这些信息需要从datanode的blockReport中获取,所以加载fsimage完毕后,namenodeq程q入rpc{待状态,{待所有的datanodes发送blockReports?/p><h3>blockReport阶段</h3><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">每个datanode在启动时都会扫描其机器上对应保存hdfs block的目录下(dfs.data.dir)所保存的所有文件块Q然后通过namenode的rpc调用这些block信息以一个long数组的方式发送给namenodeQnamenode在接收到一个datanode的blockReport rpc调用后,从rpc中解析出block数组Qƈ这些接收到的blocks插入到BlocksMap表中Q由于此时BlocksMap~少的仅仅是每个block对应的datanode信息Q而namenoe能从report中获知当前report上来的是哪个datanode的块信息Q所以,blockReportq程实际上就是namenode在接收到块信息汇报后Q填充BlocksMap中每个block对应的datanodes列表的三元组信息的过E。其程如下图所C?</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><img src="http://hi.csdn.net/attachment/201008/26/0_128283285152J9.gif" alt="" style="margin: 0px; padding: 0px; border: none; " /></p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "> </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">当所有的datanode汇报完blockQnamenode针对每个datanode的汇报进行过处理后,namenode的启动过E到此结束。此时BlocksMap中block->datanodes的对应关pdl初始化完毕。如果此时已l达到安全模式的推出阈|则hdfsd退出安全模式,开始提供服务?/p><h1><a name="_Toc268446377" style="margin: 0px; padding: 0px; color: #336699; ">启动q程数据采集和瓶颈分?/a></h1><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">对namenode的整个启动过E有了详l了解之后,可以对其启动过E中各阶D各函数的调用耗时q行profiling的采集,数据的profiling仍然分ؓ两个阶段Q即fsimage加蝲阶段和blockReport阶段?/p><h2>fsimage加蝲阶段性能数据采集和瓶颈分?/h2><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">以下是对建库集群真实的fsimage加蝲q程的的性能采集数据Q?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><img src="http://hi.csdn.net/attachment/201008/26/0_1282832976Z25j.gif" alt="" width="765" height="92" style="margin: 0px; padding: 0px; border: none; " /></p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "> </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">从上囑֏以看出,fsimage的加载过E那个中Q主要耗时的操作分别分布在<strong style="margin: 0px; padding: 0px; ">FSDirectory.addToParent</strong>Q?strong style="margin: 0px; padding: 0px; ">FSImage.readString</strong>Q以?strong style="margin: 0px; padding: 0px; ">PermissionStatus.read</strong>三个操作Q这三个操作分别占用了加载过E的73%Q?5%以及8%Q加hd消耗了整个加蝲q程?6%。而其?strong style="margin: 0px; padding: 0px; ">FSImage.readString</strong>?strong style="margin: 0px; padding: 0px; ">PermissionStatus.read</strong>操作都是从fsimage的文件流中读取数据(分别是读取String和shortQ的操作Q这U操作优化的I间不大Q但是通过调整该文件流的Buffer大小来提高少许性能。?strong style="margin: 0px; padding: 0px; ">FSDirectory.addToParent</strong>的调用却占用了整个加载过E的73%Q所以该调用中的优化I间比较大?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">       以下是addToParent调用中的profiling数据Q?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><img src="http://hi.csdn.net/attachment/201008/26/0_12828330345m9e.gif" alt="" width="759" height="127" style="margin: 0px; padding: 0px; border: none; " /></p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "> </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">从以上数据可以看出addToParent调用占用?3%的耗时中,?6%都耗在了INode.getPathComponents调用上,而这66%分别?6%消耗在INode.getPathNames调用Q?0%消耗在INode.getPathComponents调用。这两个耗时操作的具体分布如以下数据所C:</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><img src="http://hi.csdn.net/attachment/201008/26/0_1282833100y9i1.gif" alt="" width="839" height="218" style="margin: 0px; padding: 0px; border: none; " /></p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "> </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">可以看出Q消耗了36%的处理时间的INode.getPathNames操作Q全部都是在通过String.split函数调用来对文g或目录\径进行切分。另外消耗了30%左右的处理时间在INode.getPathComponents中,该函C最l耗时都耗在获取字符串的byte数组的java原生操作中?/p><h2>blockReport阶段性能数据采集和瓶颈分?/h2><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">׃blockReport的调用是通过datanode调用namenode的rpc调用Q所以在namenodeq入到等待blockreport阶段后,会分别开启rpc调用的监听线E和rpc调用的处理线E。其中rpc处理和rpc鉴定的调用耗时分布如下图所C:</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><img src="http://hi.csdn.net/attachment/201008/26/0_12828331820m3h.gif" alt="" style="margin: 0px; padding: 0px; border: none; " /></p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "> </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">而其中rpc的监听线E的优化是另外一个话题,在其他的issue中再详细讨论Q且׃blockReport的操作实际上是触发的rpc处理U程Q所以这里只兛_rpc处理U程的性能数据?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">       在namenode处理blockReportq程中的调用耗时性能数据如下Q?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><img src="http://hi.csdn.net/attachment/201008/26/0_1282833251doLC.gif" alt="" style="margin: 0px; padding: 0px; border: none; " /></p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "> </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">可以看出Q在namenode启动阶段Q处理从各个datanode汇报上来的blockReport耗费了整个rpc处理q程中的l大部分旉(48/49)QblockReport处理逻辑中的耗时分布如下图:</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><img src="http://hi.csdn.net/attachment/201008/26/0_12828333102I59.gif" alt="" style="margin: 0px; padding: 0px; border: none; " /></p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "> </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "> </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">从上图数据中可以发现QblockReport阶段中耗时分布主要耗时在FSNamesystem.addStoredBlock调用以及DatanodeDescriptor.reportDiffq程中,分别耗时37/48?0/48Q其中FSNamesystem.addStoredBlock所q行的操作时Ҏ一个汇报上来的blockQ将其于汇报上来的datanode的对应关pd始化到namenode内存中的BlocksMap表中。所以对于每一个block׃调用一ơ该Ҏ。所以可以看到该Ҏ在整个过E中调用?strong style="margin: 0px; padding: 0px; "><span style="margin: 0px; padding: 0px; color: red; ">774819</span></strong>ơ,而另一个耗时的操作,即DatanodeDescriptor.reportDiffQ该操作的过E在上文中有详细介绍Q主要是Z该datanode汇报上来的blocks跟namenode内存中的BlocksMap中进行对比,以决定那个哪些是需要添加到BlocksMap中的blockQ哪些是需要添加到toRemove队列中的blockQ以及哪些是d到toValidate队列中的block。由于这个操作需要针Ҏ一个汇报上来的blockL询BlocksMapQ以及namenode中的其他几个mapQ所以该q程也非常的耗时。而且从调用次C可以看出QreportDiff调用在启动过E中仅调用了14??4个datanodeq行块汇?Q却耗费?0/48的时间。所以reportDiff也是整个blockReportq程中非常耗时的瓶颈所在?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">       同时可以看到Q出了reportDiffQaddStoredBlock的调用耗费?7%的时_也就是耗费了整个blockReport旉?7/48Q该Ҏ的调用目的是Z从datanode汇报上来的每一个block插入到BlocksMap中的操作。从该方法调用的q行数据如下图所C:</p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><img src="http://hi.csdn.net/attachment/201008/26/0_12828333662q8q.gif" alt="" style="margin: 0px; padding: 0px; border: none; " /></p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "> </p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">从上囑֏以看出,addStoredBlock中,主要耗时的两个阶D分别是FSNamesystem.countNode和DatanodeDescriptor.addBlockQ后者是java中的插表操作Q而FSNamesystem.countNode调用的目的是Zl计在BlocksMap中,每一个block对应的各副本中,有几个是live状态,几个是decommission状态,几个是Corrupt状态。而在namenode的启动初始化阶段Q用来保存corrput状态和decommission状态的block的map都还是空状态,q且E序逻辑中要得到的仅仅是Zlive状态的block敎ͼ所以,q里的countNoes调用在namenode启动初始化阶Dƈ无需l计每个block对应的副本中的corrrput数和decommission敎ͼ而仅仅需要统计live状态的block副本数即可,q样countNodes能够在namenode启动阶段变得更轻量,以节省启动时间?/p><h2>瓉分析ȝ</h2><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">从profiling数据和瓶颈分歧情冉|看,fsimage加蝲阶段的瓶颈除了在分切路径的过E中不够优以外,其他耗时的地方几乎都是在java原生接口的调用中Q如从字节流L据,以及从String对象中获取byte[]数组的操作?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">       而blockReport阶段的耗时其实很大的原因是跟当前的namenode设计以及内存l构有关Q比较明昄不优之处是在namenode启动阶段的countNode和reportDiff的必要性,q两处在namenode初始化时的blockReport阶段有一些不必要的操作浪费了旉。可以针对namenode启动阶段必要的操作抽取出来Q定制成namenode启动阶段才调用的方式Q以优化namenode启动性能?/p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><br style="margin: 0px; padding: 0px; " /></p><p style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">Ref: <a style="margin: 0px; padding: 0px; color: #336699; text-decoration: none; ">http://blog.csdn.net/ae86_fc/article/details/5842020</a></p><img src ="http://m.shnenglu.com/mysileng/aggbug/198897.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/mysileng/" target="_blank">鑫龙</a> 2013-03-28 18:52 <a href="http://m.shnenglu.com/mysileng/archive/2013/03/28/198897.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hadoop二次排序 (Map/Reduce中分区和分组的问?http://m.shnenglu.com/mysileng/archive/2013/03/25/198814.html鑫龙鑫龙Mon, 25 Mar 2013 11:38:00 GMThttp://m.shnenglu.com/mysileng/archive/2013/03/25/198814.htmlhttp://m.shnenglu.com/mysileng/comments/198814.htmlhttp://m.shnenglu.com/mysileng/archive/2013/03/25/198814.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/198814.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/198814.html

        1.二次排序概念Q?/p>

        首先按照W一字段排序Q然后再对第一字段相同的行按照W二字段排序Q注意不能破坏第一ơ排?/em>的结??/p>

        如: 输入文gQ?/p>

        20 21 
        50 51 
        50 52 
        50 53 
        50 54 
        60 51 
        60 53 
        60 52 
        60 56 
        60 57 
        70 58 
        60 61 
        70 54 
        70 55 
        70 56 
        70 57 
        70 58 
        1 2 
        3 4 
        5 6 
        7 82 
        203 21 
        50 512 
        50 522 
        50 53 
        530 54 
        40 511 
        20 53 
        20 522 
        60 56 
        60 57 
        740 58 
        63 61 
        730 54 
        71 55 
        71 56 
        73 57 
        74 58 
        12 211 
        31 42 
        50 62 
        7 8

        输出Q需要分割线Q:

        ------------------------------------------------ 
        1       2 
        ------------------------------------------------ 
        3       4 
        ------------------------------------------------ 
        5       6 
        ------------------------------------------------ 
        7       8 
        7       82 
        ------------------------------------------------ 
        12      211 
        ------------------------------------------------ 
        20      21 
        20      53 
        20      522 
        ------------------------------------------------ 
        31      42 
        ------------------------------------------------ 
        40      511 
        ------------------------------------------------ 
        50      51 
        50      52 
        50      53 
        50      53 
        50      54 
        50      62 
        50      512 
        50      522 
        ------------------------------------------------ 
        60      51 
        60      52 
        60      53 
        60      56 
        60      56 
        60      57 
        60      57 
        60      61 
        ------------------------------------------------ 
        63      61 
        ------------------------------------------------ 
        70      54 
        70      55 
        70      56 
        70      57 
        70      58 
        70      58 
        ------------------------------------------------ 
        71      55 
        71      56 
        ------------------------------------------------ 
        73      57 
        ------------------------------------------------ 
        74      58 
        ------------------------------------------------ 
        203     21 
        ------------------------------------------------ 
        530     54 
        ------------------------------------------------ 
        730     54 
        ------------------------------------------------ 
        740     58

        2.工作原理

        使用如下map和reduceQ(特别注意输入输出cdQ?其中IntPair定义cdQ?/p>

        public static class Map extends Mapper<LongWritable, Text, IntPair, IntWritable> 
        public static class Reduce extends Reducer<IntPair, NullWritable, IntWritable, IntWritable>

             在map阶段Q用job.setInputFormatClass(TextInputFormat)做ؓ输入格式。注意输出应该符合自定义Map中定义的输出<IntPair, IntWritable>。最l是生成一个List<IntPair, IntWritable>。在map阶段的最后,会先调用job.setPartitionerClass对这个Listq行分区Q每个分区映到一个reducer。每个分区内又调用job.setSortComparatorClass讄的key比较函数cL序。可以看刎ͼq本w就是一个二ơ排序。如果没有通过job.setSortComparatorClass讄key比较函数c,则用key的实现的compareToҎ。在随后的例子中Q第一个例子中Q用了IntPair实现的compareToҎQ而在下一个例子中Q专门定义了key比较函数cR?/p>

             在reduce阶段Qreducer接收到所有映到q个reducer的map输出后,也是会调用job.setSortComparatorClass讄的key比较函数cd所有数据对排序。然后开始构造一个key对应的valueq代器。这时就要用到分l,使用jobjob.setGroupingComparatorClass讄的分l函数类。只要这个比较器比较的两个key相同Q他们就属于同一个组Q它们的value攑֜一个valueq代器,而这个P代器的key使用属于同一个组的所有key的第一个key。最后就是进入Reducer的reduceҎQreduceҎ的输入是所有的Qkey和它的valueq代器)。同h意输入与输出的类型必M自定义的Reducer中声明的一致?/p>

        3Q具体步?/p>

        Q?Q自定义key

        在mr中,所有的key是需要被比较和排序的Qƈ且是二次Q先ҎpartitioneQ再Ҏ大小。而本例中也是要比较两ơ。先按照W一字段排序Q然后再对第一字段相同的按照第二字D|序。根据这一点,我们可以构造一个复合类IntPairQ他有两个字D,先利用分区对W一字段排序Q再利用分区内的比较对第二字D|序?nbsp;
        所有自定义的key应该实现接口WritableComparableQ因为是可序列的q且可比较的。ƈ重蝲ҎQ?br />

        //反序列化Q从中的二q制转换成IntPair  
        public void readFields(DataInput in) throws IOException          
        //序列化,IntPair转化成用流传送的二进?nbsp; 
        public void write(DataOutput out)  
        //key的比?nbsp; 
        public int compareTo(IntPair o)          
        //另外新定义的cd该重写的两个Ҏ  
        //The hashCode() method is used by the HashPartitioner (the default partitioner in MapReduce)  
        public int hashCode()   
        public boolean equals(Object right)
        Q?Q由于key是自定义的,所以还需要自定义一下类Q?nbsp;
        Q?.1Q分区函数类。这是key的第一ơ比较?nbsp;
        public static class FirstPartitioner extends Partitioner<IntPair,IntWritable>

        在job中用setPartitionerClasss讄Partitioner?nbsp;
        Q?.2Qkey比较函数cR这是key的第二次比较。这是一个比较器Q需要承WritableComparatorQ也是实现RawComprator接口Q?/p>

           Q这个就是前面说的第二种ҎQ但是在W三部分的代码中q没有实现此函数Q而是直接使用compareToҎq行比较Q所以也׃怸面一行的讄Q?nbsp;
        在job中用setSortComparatorClass讄key比较函数cR?/p>

        public static class KeyComparator extends WritableComparator
        2.3Q分l函数类。在reduce阶段Q构造一个key对应的valueq代器的时候,只要first相同属于同一个组Q放在一个valueq代器。这是一个比较器Q需要承WritableComparator?nbsp;
        public static class GroupingComparator extends WritableComparator
        分组函数cM必须有一个构造函敎ͼq且重蝲 public int compare(WritableComparable w1, WritableComparable w2) 
        分组函数cȝ另一U方法是实现接口RawComparator?nbsp;
        在job中用setGroupingComparatorClass讄分组函数cR?nbsp;
        另外注意的是Q如果reduce的输入与输出不是同一U类型,则不要定义Combiner也用reduceQ因为Combiner的输出是reduce的输入。除非重新定义一个Combiner?nbsp;


        转自Q?a style="font-family: Arial; line-height: 26px; ">http://www.cnblogs.com/dandingyy/archive/2013/03/08/2950703.html



        鑫龙 2013-03-25 19:38 发表评论
        ]]>
        hadoop面试时可能遇到的问题http://m.shnenglu.com/mysileng/archive/2013/03/18/198540.html鑫龙鑫龙Mon, 18 Mar 2013 05:03:00 GMThttp://m.shnenglu.com/mysileng/archive/2013/03/18/198540.htmlhttp://m.shnenglu.com/mysileng/comments/198540.htmlhttp://m.shnenglu.com/mysileng/archive/2013/03/18/198540.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/198540.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/198540.html面试hadoop可能被问到的问题Q你能回{出几个 ?

        1、hadoopq行的原?

        2、mapreduce的原?

        3、HDFS存储的机?

        4、D一个简单的例子说明mapreduce是怎么来运行的 ?

        5、面试的人给你出一些问?让你用mapreduce来实玎ͼ

              比如:现在?0个文件夹,每个文g多w?000000个url.现在让你扑ևtop1000000url?/p>

        6、hadoop中Combiner的作?

        SrcQ?nbsp;http://p-x1984.javaeye.com/blog/859843


         

        Q1. Name the most common InputFormats defined in Hadoop? Which one is default ? 
        Following 2 are most common InputFormats defined in Hadoop 
        - TextInputFormat
        - KeyValueInputFormat
        - SequenceFileInputFormat
        Q2. What is the difference between TextInputFormatand KeyValueInputFormat class
        TextInputFormat: It reads lines of text files and provides the offset of the line as key to the Mapper and actual line as Value to the mapper
        KeyValueInputFormat: Reads text file and parses lines into key, val pairs. Everything up to the first tab character is sent as key to the Mapper and the remainder of the line is sent as value to the mapper.
        Q3. What is InputSplit in Hadoop
        When a hadoop job is run, it splits input files into chunks and assign each split to a mapper to process. This is called Input Split 
        Q4. How is the splitting of file invoked in Hadoop Framework 
        It is invoked by the Hadoop framework by running getInputSplit()method of the Input format class (like FileInputFormat) defined by the user 
        Q5. Consider case scenario: In M/R system,
            - HDFS block size is 64 MB
            - Input format is FileInputFormat
            - We have 3 files of size 64K, 65Mb and 127Mb 
        then how many input splits will be made by Hadoop framework?
        Hadoop will make 5 splits as follows 
        - 1 split for 64K files 
        - 2  splits for 65Mb files 
        - 2 splits for 127Mb file 
        Q6. What is the purpose of RecordReader in Hadoop
        The InputSplithas defined a slice of work, but does not describe how to access it. The RecordReaderclass actually loads the data from its source and converts it into (key, value) pairs suitable for reading by the Mapper. The RecordReader instance is defined by the InputFormat 
        Q7. After the Map phase finishes, the hadoop framework does "Partitioning, Shuffle and sort". Explain what happens in this phase?
        - Partitioning
        Partitioning is the process of determining which reducer instance will receive which intermediate keys and values. Each mapper must determine for all of its output (key, value) pairs which reducer will receive them. It is necessary that for any key, regardless of which mapper instance generated it, the destination partition is the same

        - Shuffle
        After the first map tasks have completed, the nodes may still be performing several more map tasks each. But they also begin exchanging the intermediate outputs from the map tasks to where they are required by the reducers. This process of moving map outputs to the reducers is known as shuffling.
        - Sort
        Each reduce task is responsible for reducing the values associated with several intermediate keys. The set of intermediate keys on a single node is automatically sorted by Hadoop before they are presented to the Reducer 
        Q9. If no custom partitioner is defined in the hadoop then how is data partitioned before its sent to the reducer 
        The default partitioner computes a hash value for the key and assigns the partition based on this result 
        Q10. What is a Combiner 
        The Combiner is a "mini-reduce" process which operates only on data generated by a mapper. The Combiner will receive as input all data emitted by the Mapper instances on a given node. The output from the Combiner is then sent to the Reducers, instead of the output from the Mappers.
        Q11. Give an example scenario where a cobiner can be used and where it cannot be used
        There can be several examples following are the most common ones
        - Scenario where you can use combiner
          Getting list of distinct words in a file
        - Scenario where you cannot use a combiner
          Calculating mean of a list of numbers 
        Q12. What is job tracker
        Job Tracker is the service within Hadoop that runs Map Reduce jobs on the cluster
        Q13. What are some typical functions of Job Tracker
        The following are some typical tasks of Job Tracker
        - Accepts jobs from clients
        - It talks to the NameNode to determine the location of the data
        - It locates TaskTracker nodes with available slots at or near the data
        - It submits the work to the chosen Task Tracker nodes and monitors progress of each task by receiving heartbeat signals from Task tracker 
        Q14. What is task tracker
        Task Tracker is a node in the cluster that accepts tasks like Map, Reduce and Shuffle operations - from a JobTracker 

        Q15. Whats the relationship between Jobs and Tasks in Hadoop
        One job is broken down into one or many tasks in Hadoop
        Q16. Suppose Hadoop spawned 100 tasks for a job and one of the task failed. What willhadoop do ?
        It will restart the task again on some other task tracker and only if the task fails more than 4 (default setting and can be changed) times will it kill the job
        Q17. Hadoop achieves parallelism by dividing the tasks across many nodes, it is possible for a few slow nodes to rate-limit the rest of the program and slow down the program. What mechanism Hadoop provides to combat this  
        Speculative Execution 
        Q18. How does speculative execution works in Hadoop 
        Job tracker makes different task trackers process same input. When tasks complete, they announce this fact to the Job Tracker. Whichever copy of a task finishes first becomes the definitive copy. If other copies were executing speculatively, Hadoop tells the Task Trackers to abandon the tasks and discard their outputs. The Reducers then receive their inputs from whichever Mapper completed successfully, first. 
        Q19. Using command line in Linux, how will you 
        - see all jobs running in the hadoop cluster
        - kill a job
        hadoop job -list
        hadoop job -kill jobid 
        Q20. What is Hadoop Streaming 
        Streaming is a generic API that allows programs written in virtually any language to be used asHadoop Mapper and Reducer implementations 

        Q21. What is the characteristic of streaming API that makes it flexible run map reduce jobs in languages like perl, ruby, awk etc. 
        Hadoop Streaming allows to use arbitrary programs for the Mapper and Reducer phases of a Map Reduce job by having both Mappers and Reducers receive their input on stdin and emit output (key, value) pairs on stdout.
        Q22. Whats is Distributed Cache in Hadoop
        Distributed Cache is a facility provided by the Map/Reduce framework to cache files (text, archives, jars and so on) needed by applications during execution of the job. The framework will copy the necessary files to the slave node before any tasks for the job are executed on that node.
        Q23. What is the benifit of Distributed cache, why can we just have the file in HDFS and have the application read it 
        This is because distributed cache is much faster. It copies the file to all trackers at the start of the job. Now if the task tracker runs 10 or 100 mappers or reducer, it will use the same copy of distributed cache. On the other hand, if you put code in file to read it from HDFS in the MR job then every mapper will try to access it from HDFS hence if a task tracker run 100 map jobs then it will try to read this file 100 times from HDFS. Also HDFS is not very efficient when used like this.

        Q.24 What mechanism does Hadoop framework provides to synchronize changes made in Distribution Cache during runtime of the application 
        This is a trick questions. There is no such mechanism. Distributed Cache by design is read only during the time of Job execution

        Q25. Have you ever used Counters in Hadoop. Give us an example scenario
        Anybody who claims to have worked on a Hadoop project is expected to use counters

        Q26. Is it possible to provide multiple input to Hadoop? If yes then how can you give multiple directories as input to the Hadoop job 
        Yes, The input format class provides methods to add multiple directories as input to a Hadoop job

        Q27. Is it possible to have Hadoop job output in multiple directories. If yes then how 
        Yes, by using Multiple Outputs class

        Q28. What will a hadoop job do if you try to run it with an output directory that is already present? Will it
        - overwrite it
        - warn you and continue
        - throw an exception and exit

        The hadoop job will throw an exception and exit.

        Q29. How can you set an arbitary number of mappers to be created for a job in Hadoop 
        This is a trick question. You cannot set it

        Q30. How can you set an arbitary number of reducers to be created for a job in Hadoop 
        You can either do it progamatically by using method setNumReduceTasksin the JobConfclass or set it up as a configuration setting

         

        Src:http://xsh8637.blog.163.com/blog/#m=0&t=1&c=fks_084065087084081065083083087095086082081074093080080069



        鑫龙 2013-03-18 13:03 发表评论
        ]]>
        ZHadoop Sequencefile的小文g解决Ҏhttp://m.shnenglu.com/mysileng/archive/2013/03/04/198218.html鑫龙鑫龙Mon, 04 Mar 2013 11:28:00 GMThttp://m.shnenglu.com/mysileng/archive/2013/03/04/198218.htmlhttp://m.shnenglu.com/mysileng/comments/198218.htmlhttp://m.shnenglu.com/mysileng/archive/2013/03/04/198218.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/198218.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/198218.html

        ZHadoop Sequencefile的小文g解决Ҏ

         

        一?/strong> 概述

           文件是指文?/span>sizeHDFS?/span>block大小的文件。这L文g会给hadoop的扩展性和性能带来严重问题。首先,?/span>HDFS中,MblockQ文件或者目录在内存中均以对象的形式存储Q每个对象约?/span>150byteQ如果有1000 0000个小文gQ每个文件占用一?/span>blockQ则namenode大约需?/span>2GI间。如果存?/span>1亿个文gQ则namenode需?/span>20GI间。这?/span>namenode内存定w严重制约了集的扩展?/span> 其次Q访问大量小文g速度q远于讉K几个大文件?/span>HDFS最初是为流式访问大文g开发的Q如果访问大量小文gQ需要不断的从一?/span>datanode跛_另一?/span>datanodeQ严重媄响性能。最后,处理大量文仉度q远于处理同等大小的大文g的速度。每一个小文g要占用一?/span>slotQ?/span>task启动耗费大量旉甚至大部分时间都耗费在启?/span>task和释?/span>task上?/span>

        二?/strong>Hadoop自带的解x?/strong>

        对于文仉题,Hadoop本n也提供了几个解决ҎQ分别ؓQ?/span>Hadoop ArchiveQ?/span>Sequence file?/span>CombineFileInputFormat?/span>

        Q?/span>1Q?/span> Hadoop Archive

        Hadoop Archive或?/span>HARQ是一个高效地小文g攑օHDFS块中的文件存档工P它能够将多个文件打包成一?/span>HAR文gQ这样在减少namenode内存使用的同Ӟ仍然允许Ҏ件进行透明的访问?/span>

        使用HAR旉要两点,W一Q对文件进行存档后Q原文gq不会自动被删除Q需要用戯己删除;W二Q创?/span>HAR文g的过E实际上是在q行一?/span>mapreduce作业Q因而需要有一?/span>hadoop集群q行此命令?/span>

        该方案需人工q行l护Q适用理人员的操作,而且har文g一旦创建,Archives便不可改变,不能应用于多用户的互联网操作?/span>

        Q?/span>2Q?/span> Sequence file

        sequence file׃pd的二q制key/valuel成Q如果ؓkey文件名Q?/span>value为文件内容,则可以将大批文件合q成一个大文g?/span>

        Hadoop-0.21.0中提供了SequenceFileQ包?/span>WriterQ?/span>Reader?/span>SequenceFileSorterc进行写Q读和排序操作。如?/span>hadoop版本低于0.21.0的版本,实现Ҏ可参?/span>[3]?/span>

         

        该方案对于小文g的存取都比较自由Q不限制用户和文件的多少Q但?/span>SequenceFile文g不能q加写入Q适用于一ơ性写入大量小文g的操作?/span>

         

        Q?/span>3Q?/span>CombineFileInputFormat

        CombineFileInputFormat是一U新?/span>inputformatQ用于将多个文g合ƈ成一个单独的splitQ另外,它会考虑数据的存储位|?/span>

        该方案版本比较老,|上资料甚少Q从资料来看应该没有W二U方案好?/span>

         

         

        三?strong>文仉题解x?/strong>

        在原?span style="font-size: 9pt; font-family: Verdana,sans-serif;">HDFS基础上添加一个小文g处理模块Q具体操作流E如?span style="font-size: 9pt; font-family: Verdana,sans-serif;">:

               1.   当用户上传文件时Q判断该文g是否属于文Ӟ如果是,则交l小文g处理模块处理Q否则,交给通用文g处理模块处理?/p>

               2.  在小文g模块中开启一定时dQ其主要功能是当模块中文件?span style="font-size: 9pt; font-family: Verdana,sans-serif;">size大于HDFS?span style="font-size: 9pt; font-family: Verdana,sans-serif;">block大小的文件时Q则通过SequenceFilelg以文件名?span style="font-size: 9pt; font-family: Verdana,sans-serif;">keyQ相应的文g内容?span style="font-size: 9pt; font-family: Verdana,sans-serif;">value这些小文g一ơ性写?span style="font-size: 9pt; font-family: Verdana,sans-serif;">hdfs模块?/p>

               3. 同时删除已处理的文gQƈ结果写入数据库?/p>

               4.  当用戯行读取操作时Q可Ҏ数据库中的结果标志来d文g?/p>
        转自:http://lxm63972012.iteye.com/blog/1429011

        鑫龙 2013-03-04 19:28 发表评论
        ]]>
        hadoop jar xxxx.jar的流E?http://m.shnenglu.com/mysileng/archive/2013/03/02/198176.html鑫龙鑫龙Sat, 02 Mar 2013 09:28:00 GMThttp://m.shnenglu.com/mysileng/archive/2013/03/02/198176.htmlhttp://m.shnenglu.com/mysileng/comments/198176.htmlhttp://m.shnenglu.com/mysileng/archive/2013/03/02/198176.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/198176.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/198176.htmljar -cvf xxx.jar .
        hadopp jar xxx.jar clalss-name [input] [output]
        ----------------------------------------------------------------------
        hadoop jar hadoop-0.20.2-examples.jar [class name]的实质是:
        1.利用hadoopq个脚本启动一个jvmq程;
        2.jvmq程去运行org.apache.hadoop.util.RunJarq个javac?
        3.org.apache.hadoop.util.RunJar解压hadoop-0.20.2-examples.jar到hadoop.tmp.dir/hadoop-unjar*/目录?
        4.org.apache.hadoop.util.RunJar动态的加蝲q运行Main-Class或指定的Class;
        5.Main-Class或指定的Class中设定Job的各属?/div>
        6.提交job到JobTracker上ƈ监视q行情况?/div>
        注意Q以上都是在jobClient上执行的?/div>
        q行jar文g的时候,jar会被解压到hadoop.tmp.dir/hadoop-unjar*/目录下(如:/home/hadoop/hadoop-fs/dfs/temp/hadoop-unjar693919842639653083, 注意Q这个目录是JobClient的目录,不是JobTracker的目录)。解压后的文件ؓQ?/div>
        drwxr-xr-x 2 hadoop hadoop 4096 Jul 30 15:40 META-INF
        drwxr-xr-x 3 hadoop hadoop 4096 Jul 30 15:40 org
        有图有真相:

        提交job的实质是Q?/div>
        生成${job-id}/job.xml文g到hdfs://${mapred.system.dir}/Q比如hdfs://bcn152:9990/home/hadoop/hadoop-fs/dfs/temp/mapred/system/job_201007301137_0012/job.xmlQ,job的描q包括jar文g的\径,map|reducec\径等{?
        上传${job-id}/job.jar文g到hdfs://${mapred.system.dir}/Q比如hdfs://bcn152:9990/home/hadoop/hadoop-fs/dfs/temp/mapred/system/job_201007301137_0012/job.jarQ?/div>
        有图有真相:

        生成job之后Q通过static JobClient.runJob()׃向jobTracker提交job:
        JobClient jc = new JobClient(job);
        RunningJob rj = jc.submitJob(job);
        之后JobTracker׃调度此jobQ?/div>
        提交job之后Q用下面的代码获取job的进度:
            try {
              if (!jc.monitorAndPrintJob(job, rj)) {
                throw new IOException("Job failed!");
              }
            } catch (InterruptedException ie) {
              Thread.currentThread().interrupt();
            }




        鑫龙 2013-03-02 17:28 发表评论
        ]]>hadoop 序列化源码浅?(?http://m.shnenglu.com/mysileng/archive/2013/01/15/197301.html鑫龙鑫龙Tue, 15 Jan 2013 13:48:00 GMThttp://m.shnenglu.com/mysileng/archive/2013/01/15/197301.htmlhttp://m.shnenglu.com/mysileng/comments/197301.htmlhttp://m.shnenglu.com/mysileng/archive/2013/01/15/197301.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/197301.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/197301.html阅读全文

        鑫龙 2013-01-15 21:48 发表评论
        ]]>
        HADOOP_CLASSPATH讄(?http://m.shnenglu.com/mysileng/archive/2012/12/28/196753.html鑫龙鑫龙Fri, 28 Dec 2012 12:44:00 GMThttp://m.shnenglu.com/mysileng/archive/2012/12/28/196753.htmlhttp://m.shnenglu.com/mysileng/comments/196753.htmlhttp://m.shnenglu.com/mysileng/archive/2012/12/28/196753.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/196753.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/196753.html在写hadoopE序~译Ӟ往往需要HADOOP_CLASSPATH路径Q可通过以下方式q行在编译脚本中讄Q?/div>
        for f in $HADOOP_HOME/hadoop-*.jar; do
        CLASSPATH=${CLASSPATH}:$f
        done

        for f in $HADOOP_HOME/lib/*.jar; do
        CLASSPATH=${CLASSPATH}:$f
        done

        for f in $HIVE_HOME/lib/*.jar; do
        CLASSPATH=${CLASSPATH}:$f
        done
         
        转自Q?a >http://blog.sina.com.cn/s/blog_62a9902f01017x7j.html

        鑫龙 2012-12-28 20:44 发表评论
        ]]>
        CentOS 5.5 安装hadoop-0.21.0(?http://m.shnenglu.com/mysileng/archive/2012/12/25/196620.html鑫龙鑫龙Tue, 25 Dec 2012 12:54:00 GMThttp://m.shnenglu.com/mysileng/archive/2012/12/25/196620.htmlhttp://m.shnenglu.com/mysileng/comments/196620.htmlhttp://m.shnenglu.com/mysileng/archive/2012/12/25/196620.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/196620.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/196620.html倒腾了一天,l于在CentOS上装上了hadoop-0.21.0Q特此记录,以备后用?/p>

        操作pȝQCentOS 5.5

        HadoopQhadoop-0.21.0
        JDKQ?.6.0_17
        namenodeL?masterQnamenode的IP:192.168.90.91
        datanodeL?slaveQdatanode的IP:192.168.90.94

        W一步:安装q启动ssh服务

        CentOS 5.5安装完毕之后以及默认启动了sshd服务Q可以在“pȝ”Q?gt;“理”->“服务”中查看sshd服务是否启动。当然了Q如果机器上没有安装ssh服务Q则执行命osudo yum install ssh来安装。安?/span>rsyncQ它是一个远E数据同步工P可通过 LAN/WAN 快速同步多C机间的文?/span>Q执行命?span style="color: #0055ff; ">sudo yum install rsync。修Ҏ个节点的/etc/hosts文gQ将 namenode和datanode的IP信息加入到该文g的尾部:

        192.168.90.91 master
        192.168.90.94 slave

        W二步,配置SSH服务

        Q?Q,Q?Q是针对每一台机?/p>

        Q?Q创建hadoop用户名与用户l?/p>

             q行命osu - rootQ注意,不是命osu rootQ后者不能携带root用户的参C息,是不能执行创建用L和用户命令的。执行命令:groupadd hadoop和命?span style="color: #0055ff; ">useradd -g hadoop hadoop?span style="color: #ff0000; ">注意不能?home目录下创建hadoop目录Q否则创建hadoop用户会失败。创建好用户以后最好是重新启动计算机,以hadoop用户dpȝ。这样在之后的操作中׃需要su到hadoop用户下,而且也不会纠~于文g的owner问题?/span>

        Q?Q生成ssh密钥

             如果是其他用L录的则切换到hadoop用户下,执行命osu - hadoopQ在/home/hadoop目录下执行命令:ssh-keygen -t rsaQ一路回车,选择默认的保存\径)Q密钥生成成功之后,q入.ssh目录Q执?span style="color: #0055ff; ">cd .sshQ执行命令:cp id_rsa.pub authorized_keys。这个时候运行ssh localhostQ让pȝC用户Q之后ssh localhost׃需要再输入密码了?/p>

        Q?Q交换公?/p>

             namenode上的公钥拯到datanodeQ在hadoop用户的用L录下Q?home/hadoopQ下执行命ossh-copy-id -i $HOME/.ssh/id_rsa.pub hadoop@slave。同理,也可以将datanode上的公钥拯到namenodeQ但q不是必ȝ。这样两台机器在hadoop用户下互相ssh׃需要密码了?/p>

         

        W三步,安装JDK1.6或以上(每台机器Q?/span>

        Q?Q执行命令yum install jdk

        Q?Q如果第一步没有找到源码包Q那么就需要到官网上下载了Qhttps://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=jdk-6u22-oth-JPR@CDS-CDS_Developer?/p>

        Q?Q新建目?usr/javaQ将源码包jdk-6u22-linux-i586.bin复制到该目录下,执行命ochmod a+x jdk-6u22-linux-i586.bin
              使当前用h有对jdk-6u22-linux-i586.bin的执行权限。执行命?span style="color: #0055ff; ">sudo ./jdk-6u22-linux-i586.binq行安装

        Q?Q修?etc/profile来添加环境变量,/etc/profile中设|的环境变量像Windows下环境变量中的系l变量一P所有用户都可以使用?br />      用文本编辑器打开/etc/profile
              # vi /etc/profile
              在最后加入以下几行:
              export JAVA_HOME=/usr/java/jdk1.6.0_22
              export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
              export PATH=$PATH:$JAVA_HOME/bin
              q样我们p|好了JDKQ在centos?nbsp;source /etc/profile 可以生效了.

        q行命ojava -version可以判断是否安装成功

         

        W四步,安装hadoop

        原来现在才开始安装hadoopQ准备工作也作得太多了,废话说?/p>

        Q?Q新建目?usr/local/hadoopQ将hadoop-0.21.0.tar.gz解压~到该目录下Q执行命?span style="color: #0055ff; ">sudo tar -xvzf hadoop-0.21.0.tar.gzQ修?etc/profile文gQ将hadoop的安装目录append到文件最后:

        export HADOOP_HOME=/usr/local/hadoop/hadoop-0.21.0
        export PATH=$HADOOP_HOME/bin:$PATH
        Q?Q配|?conf/hadoop-env.sh文gQ修改java_home环境变量
        export JAVA_HOME=/usr/java/jdk1.6.0_22/
        export HADOOP_CLASSPATH=.
        Q?Q配|?core-site.xml 文g
        <configuration>
              <property>
                    <name>hadoop.tmp.dir</name>
                    <value>/usr/local/hadoop/hadoop-0.21.0/tmp</value>
                   (注意Q请先在 hadoopinstall 目录下徏?tmp 文g?
                    <description>A base for other temporary directories.</description>
              </property>
        <!-- file system properties -->
              <property>
                    <name>fs.default.name</name>
              <value>hdfs://master:54310</value>
              </property>
        </configuration>
        Q?Q配|?hdfs-site.xml 文g
        <configuration>
              <property>
                    <name>dfs.replication</name>
                    <value>1</value>Q这里共两台机器Q如果将主节点也配置为datanodeQ则q里可以?Q?/span>
              </property>
        <configuration>
        Q?Q配|?mapred-site.xml 文g
        <configuration>
              <property>
                    <name>mapred.job.tracker</name>
                    <value>master:54311</value>
              </property>
        </configuration>
        Q?Q配|?conf/masters 文gQ加?namenode ?ip 地址
        master
        Q?Q配|?slaves 文g, 加入所?datanode ?ip 地址

        slave

         

        (如果之前?/span>hdfs-site.xml文g中的拯数设|ؓ2Q则需要将master也加入到slaves文g?/span>)

        Q?Q将 namenode ??|???hadoop 所 ????hadoopQ?.21.0 ???br />datanode ?usr/lcoal/hadoop/目录下(实际?masters,slavers 文g时不必要的, 复制了也
        没问题)?br />Q?Q配|datanode?etc/profile 文gQ在文gappend下列内容Q?br />
        export HADOOP_HOME=/usr/local/hadoop/hadoop-0.21.0
        export PATH=$HADOOP_HOME/bin:$PATH

        W五步,启动hadoop
        首先记得关闭pȝ的防火墙Qroot用户下执行命?/span>/etc/init.d/iptables stopQ运行命?span style="color: #0055ff; ">/etc/init.d/iptables status查防火墙状态?span style="color: #000000; ">hadoop用户下,在namenode?usr/local/hadoop/hadoop-0.21.0/bin目录下打开l端Q执行命?span style="color: #0055ff; ">hadoop namenode -formatQ?span style="color: #000000; ">格式化目录节炏V?span style="color: #ff0000; ">注意Q?/span>/usr/local/hadoop/hadoop-0.21.0/tmp目录是可以写的,否则在格式化时会出现异常?/span>执行命ostart-all.sh启动hadoop集群Q执行命?span style="color: #0055ff; ">jps查看q程Q执行命?span style="color: #0055ff; ">hadoop dfsadmin -report查看状态。在览器中输入http://master:50070以web方式查看集群状态。查看jobtraker的运行状态:http://www.ibm.com/developerworks/cn/linux/l-hadoop-2/index.html
        PSQ格式化namenode的时候最好将节点的tmp目录清空、删除logs目录中的文g?br />

        到这里,ZCentOS5.5的hadoop集群搭徏完毕Q?/span>

         

        参考资料:http://www.ibm.com/developerworks/cn/linux/l-hadoop-2/index.html



        鑫龙 2012-12-25 20:54 发表评论
        ]]>
        从Hadoop框架与MapReduce模式中谈量数据处理Q含淘宝技术架构)(?http://m.shnenglu.com/mysileng/archive/2012/12/23/196549.html鑫龙鑫龙Sun, 23 Dec 2012 11:55:00 GMThttp://m.shnenglu.com/mysileng/archive/2012/12/23/196549.htmlhttp://m.shnenglu.com/mysileng/comments/196549.htmlhttp://m.shnenglu.com/mysileng/archive/2012/12/23/196549.html#Feedback0http://m.shnenglu.com/mysileng/comments/commentRss/196549.htmlhttp://m.shnenglu.com/mysileng/services/trackbacks/196549.html

                    从hadoop框架与MapReduce模式中谈量数据处理

        前言

            几周前,当我最初听刎ͼ以致后来初次接触Hadoop与MapReduceq两个东西,我便E显兴奋Q觉得它们很是神U,而神U的东西常能勾v我的兴趣Q在看过介绍它们的文章或论文之后Q觉得Hadoop是一富有趣呛_挑战性的技术,且它q牵扯到了一个我更加感兴的话题Qv量数据处理?/p>

            由此Q最q凡是空闲时Q便在看“Hadoop”Q?#8220;MapReduce”“量数据处理”q方面的论文。但在看论文的过E中Q总觉得那些论文都是浅辄止,常常看的很不q瘾QL一个东西刚要讲到紧要处Q它便结束了Q让我好?#8220;愤懑”?/p>

            管我对q个Hadoop与MapReduce知之甚浅Q但我还是想记录自己的学习过E,说不定,关于q个东西的学习能督促我最l写成和“l典法研究pd”一般的一pd文章?/p>

            OkQ闲话少说。本文从最基本的mapreduce模式QHadoop框架开始谈P然后由各自的架构引申开来,谈到量数据处理Q最后谈谈淘宝的量数据产品技术架构,以ؓ了兼备浅Z深入之效Q最l,希望得到读者的喜欢与支持。谢谢?/p>

            ׃本h是初ơ接触这两项技术,文章有Q何问题,Ƣ迎不吝指正。再谢一ơ。OkQ咱们开始吧?/p>

        W一部分、mapreduce模式与hadoop框架深入出

        架构D

                 惌懂此文,读者必d要明以下几点,以作为阅dl内容的基础知识储备Q?/p>

        1. Mapreduce是一U模式?/li>
        2. Hadoop是一U框架?/li>
        3. Hadoop是一个实Cmapreduce模式的开源的分布式ƈ行编E框架?/li>

            所以,你现在,知道了什么是mapreduceQ什么是hadoopQ以及这两者之间最单的联系Q而本文的LxQ一句话概括Q?strong>在hadoop的框架上采取mapreduce的模式处理v量数?/strong>。下面,׃可以依次深入学习和了解mapreduce和hadoopq两个东西了?/p>

        Mapreduce模式

            前面说了Qmapreduce是一U模式,一U什么模式呢?一U云计算的核心计模式,一U分布式q算技术,也是化的分布式编E模式,它主要用于解决问题的E序开发模型,也是开发h员拆解问题的Ҏ?/p>

            OkQ光说不上图Q没用。如下图所C,mapreduce模式的主要思想是将自动分割要执行的问题Q例如程序)拆解成mapQ映)和reduceQ化Q的方式Q流E图如下?所C:

            在数据被分割后通过Map 函数的程序将数据映射成不同的区块Q分配给计算机机处理达到分布式q算的效果,在通过Reduce 函数的程序将l果汇整Q从而输出开发者需要的l果?/p>

            MapReduce 借鉴了函数式E序设计语言的设计思想Q其软g实现是指定一个Map 函数Q把键值对(key/value)映射成新的键值对(key/value)QŞ成一pd中间l果形式的key/value 对,然后把它们传lReduce(规约)函数Q把h相同中间形式key 的value 合ƈ在一赗Map 和Reduce 函数h一定的兌性。函数描q如? 所C:

            MapReduce致力于解军_规模数据处理的问题,因此在设计之初就考虑了数据的局部性原理,利用局部性原理将整个问题分而治之。MapReduce集群由普通PC机构成,?span style="font-family: 'Times New Roman'; ">无共享式架构?/span>在处理之前,数据集分布臛_个节炏V处理时Q每个节点就q读取本地存储的数据处理QmapQ,处理后的数据进行合qӞcombineQ、排序(shuffle and sortQ后再分发(至reduce节点Q,避免了大量数据的传输Q提高了处理效率。无׃n式架构的另一个好处是配合复制QreplicationQ策略,集群可以h良好的容错性,一部分节点的down机对集群的正常工作不会造成影响?/p>

            okQ你可以再简单看看下副图Q整q图是有关hadoop的作业调优参数及原理Q图的左ҎMapTaskq行C意图,双是ReduceTaskq行C意图:

            如上图所C,其中map阶段Q当map task开始运,q生中间数据后q直接而简单的写入盘Q它首先利用内存buffer来对已经产生的bufferq行~存Qƈ在内存buffer中进行一些预排序来优化整个map的性能。而上囑֏边的reduce阶段则经历了三个阶段Q分别Copy->Sort->reduce。我们能明显的看出,其中的Sort是采用的归ƈ排序Q即merge sort?/p>

            了解了什么是mapreduceQ接下来Q咱们可以来了解实现了mapreduce模式的开源框?#8212;hadoop?/p>

        Hadoop框架

            前面说了Qhadoop是一个框Ӟ一个什么样的框架呢?Hadoop 是一个实CMapReduce 计算模型的开源分布式q行~程框架Q程序员可以借助Hadoop ~写E序Q将所~写的程序运行于计算机机上Q从而实现对量数据的处理?/p>

            此外QHadoop q提供一个分布式文gpȝ(HDFSQ及分布式数据库QHBaseQ用来将数据存储或部|到各个计算节点上。所以,你可以大致认为:Hadoop=HDFSQ文件系l,数据存储技术相养I+HBaseQ数据库Q?MapReduceQ数据处?/u>Q。Hadoop 框架如图2 所C:

            借助Hadoop 框架及云计算核心技术MapReduce 来实现数据的计算和存储,q且HDFS 分布式文件系l和HBase 分布式数据库很好的融入到云计框架中Q从而实C计算的分布式、ƈ行计和存储Qƈ且得以实现很好的处理大规模数据的能力?/p>

        Hadoop的组成部?/h3>

            我们已经知道QHadoop是Google的MapReduce一个Java实现。MapReduce是一U简化的分布式编E模式,让程序自动分布到一个由普通机器组成的大集群上ƈ发执行?strong>Hadoop主要由HDFS、MapReduce和HBase{组成。具体的hadoop的组成如下图Q?/p>

            ׃图,我们可以看到Q?/p>

            1?nbsp;            Hadoop HDFS是Google GFS存储pȝ的开源实玎ͼ主要应用场景是作为ƈ行计环境(MapReduceQ的基础lgQ同时也是BigTableQ如HBase、HyperTableQ的底层分布式文件系l。HDFS采用master/slave架构。一个HDFS集群是有׃个Namenode和一定数目的Datanodel成。Namenode是一个中心服务器Q负责管理文件系l的namespace和客LҎ件的讉K?em>Datanode在集中一般是一个节点一个,负责理节点上它们附带的存储。在内部Q一个文件其实分成一个或多个blockQ这些block存储在Datanode集合里。如下图所C(HDFS体系l构?/u>Q:

            2?nbsp;            Hadoop MapReduce是一个用简易的软g框架Q基于它写出来的应用E序能够q行在由上千个商用机器组成的大型集群上,q以一U可靠容错的方式q行处理上TBU别的数据集?/p>

            一个MapReduce作业QjobQ通常会把输入的数据集切分q独立的数据块,?MapdQtaskQ以完全q行的方式处理它们。框架会对Map的输?strong>先进行排?/strong>Q然后把l果输入lReduced。通常作业的输入和输出都会被存储在文gpȝ中。整个框架负责Q务的调度和监控,以及重新执行已经p|的Q务。如下图所C(Hadoop MapReduce处理程?/u>Q:

            3?nbsp;            Hive是基于Hadoop的一个数据仓库工P处理能力且成本低廉?/strong>

        主要特点Q?/p>

        存储方式是将l构化的数据文g映射Z张数据库表。提供类SQL语言Q实现完整的SQL查询功能。可以将SQL语句转换为MapReducedq行Q十分适合数据仓库的统计分析?/p>

        不之处Q?/strong>

        采用行存储的方式QSequenceFileQ来存储和读取数据。效率低Q当要读取数据表某一列数据时需要先取出所有数据然后再提取出某一列的数据Q效率很低。同Ӟ它还占用较多的磁盘空间?/p>

        ׃以上的不I有hQ查C博士)介绍了一U将分布式数据处理系l中以记录ؓ单位的存储结构变Z列ؓ单位的存储结构,q而减磁盘访问数量,提高查询处理性能。这P׃相同属性值具有相同数据类型和相近的数据特性,以属性gؓ单位q行压羃存储的压~比更高Q能节省更多的存储空间。如下图所C(行列存储的比较图Q:

        4?nbsp;            HBase

            HBase是一个分布式的、面向列的开源数据库Q它不同于一般的关系数据?是一个适合于非l构化数据存储的数据库。另一个不同的是HBaseZ列的而不是基于行的模式。HBase使用?BigTable非常相同的数据模型。用户存储数据行在一个表里。一个数据行拥有一个可选择的键和Q意数量的列,一个或多个列组成一个ColumnFamilyQ一个Fmaily下的列位于一个HFile中,易于~存数据。表是疏杄存储的,因此用户可以l行定义各种不同的列。在HBase中数据按主键排序Q同时表按主键划分ؓ多个HRegionQ如下图所C(HBase数据表结构图Q:

            OkQ行文至此,看似z洋z洒q千里,但若l读者造成阅读上的负担Q则不是我本意。接下来的内容,我不会再引用诸多J杂的专业术语,以给读者心里上造成不良影响?/p>

            我再l出一副图Q算是对上文所说的hadoop框架及其l成部分做个ȝQ如下图所C,便是hadoop的内部结构,我们可以看到Qv量的数据交给hadoop处理后,在hadoop的内部中Q正如上文所qͼhadoop提供一个分布式文gpȝQHDFSQ及分布式数据库QHbaseQ用来存储或部v到各个计点上,最l在内部采取mapreduce的模式对其数据进行处理,然后输出处理l果Q?/p>


        W二部分、淘宝v量数据品技术架构解?#8212;学习量数据处理l验

            在上面的本文的第一部分中,我们已经对mapreduce模式及hadoop框架有了一个深入而全面的了解。不q,如果一个东西,或者一个概念不攑ֈ实际应用中去Q那么你对这个理忉|q只是停留在理论之内Q无法向实践q进?/p>

            OkQ接下来Q本文的W二部分Q咱们以淘宝的数据魔Ҏ术架构ؓ依托Q通过介绍淘宝的v量数据品技术架构,来进一步学习和了解量数据处理的经验?/p>

        淘宝量数据产品技术架?/h3>

            如下?-1所C,x淘宝的v量数据品技术架构,׃下面要针对这个架构来一一剖析与解诅R?/p>

            怿Q看q本博客内其它文章的l心读者,定会发现Q图2-1最初见于本博客内的此篇文章Q从几幅架构图中偷得半点量数据处理l验之上Q同Ӟ此图2-1最初发表于《程序员?月刊Q作者:朋春?/p>

            在此之前Q有一点必说明的是:本文下面的内容大都是参考自朋春先生的这文章:淘宝数据方技术架构解?/u>所写,我个人所作的工作是对q篇文章的一U解M关键技术和内容的抽取,以ؓ读者更好的理解淘宝的v量数据品技术架构。与此同Ӟq能展示我自p此篇的思\与感悟,带学习Q何乐而不为呢??/p>

            OkQ不q,与本博客内之前的那篇文章Q几q架构图中偷得半Ҏv量数据处理经验)不同Q本文接下来Q要详细阐述q个架构。我也做了不准备工作(如把q图2-1打印了下来,l常琢磨Q:

         

                                                      ?-1 淘宝量数据产品技术架?/p>

            好的Q如上图所C,我们可以看到Q淘宝的量数据产品技术架构,分ؓ以下五个层次Q从上至下来看,它们分别是:数据源,计算层,存储层,查询层和产品层。我们来一一了解q五层:

        1. 数据来源层。存攄淘宝各店的交易数据。在数据源层产生的数据,通过DataXQDbSync和Timetunel准实时的传输C面第2Ҏq的“云梯”?/li>
        2. 计算层。在q个计算层内Q淘宝采用的是hadoop集群Q这个集,我们暂且UCZ梯,是计层的主要组成部分。在云梯上,pȝ每天会对数据产品q行不同的mapreduce计算?/li>
        3. 存储层。在q一层,淘宝采用了两个东西,一个MyFoxQ一个是Prom。MyFox是基于MySQL的分布式关系型数据库的集,Prom是基于hadoop Hbase技?的(读者可别忘了,在上文第一部分中,׃介绍Cq个hadoop的组成部分之一QHbase—在hadoop之内的一个分布式的开源数据库Q的一个NoSQL的存储集?/li>
        4. 查询层。在q一层中Q有一个叫做glider的东西,q个glider是以HTTP协议对外提供restful方式的接口。数据品通过一个唯一的URL来获取到它想要的数据。同Ӟ数据查询x通过MyFox来查询的。下文将具体介绍MyFox的数据查询过E?/li>
        5.  产品层。简单理解,不作q多介绍?/li>

            接下来,׃重点来了解第三层-存储层中的MyFox与PromQ然后会E带分析下glide的技术架构,最后,再了解下~存。文章即宣告l束?/p>

            我们知道Q关pd数据库在我们现在的工业生产中有着q泛的引用,它包括OracleQMySQL、DB2、Sybase和SQL Server{等?/p>

        MyFOX

            淘宝选择了MySQL的MyISAM引擎作ؓ底层的数据存储引擎。且Z应对量数据Q他们设计了分布式MySQL集群的查询代理层-MyFOX?/p>

        如下图所C,是MySQL的数据查询过E:

                                                                    ?-2 MyFOX的数据查询过E?/p>

            在MyFOX的每一个节点中Q存攄热节点和冯点两U节Ҏ据。顾名思义Q热节点存放着最新的Q被讉K频率较高的数据;冯点,存放着相对而来比较旧的Q访问频率比较低的数据。而ؓ了存储这两种节点数据Q出于硬件条件和存储成本的考虑Q你当然会考虑选择两种不同的硬盘,来存储这两种讉K频率不同的节Ҏ据。如下图所C:

                                                                   ?-3 MyFOX节点l构

             “热节?#8221;Q选择每分?5000转的SAS盘Q按照一个节点两台机器来计算Q单位数据的存储成本Uؓ4.5W/TB。相对应圎ͼ“h?#8221;我们选择了每分钟7500转的SATA盘Q单上能够存放更多的数据,存储成本Uؓ1.6W/TB?/p>

        Prom

        Z文章幅的考虑Q本文接下来不再q多阐述q个Prom了。如下面两幅图所C,他们分别表示的是Prom的存储结构以及Prom查询q程Q?/p>

                                                      ?-4 Prom的存储结?/p>

         

                                                                  ?-5 Prom查询q程

        glide的技术架?/strong>

            

                                                       ?-6 glider的技术架?/p>

            在这一?查询层中Q淘宝主要是Z用中间层隔离前后端的理念而考虑。Gliderq个中间层负责各个异构表之间的数据JOIN和UNION{计,q且负责隔离前端产品和后端存储,提供l一的数据查询服务?/p>

        ~存

            除了起到隔离前后端以及异?#8220;?#8221;之间的数据整合的作用之外Qglider的另外一个不容忽视的作用便是~存理。我们有一炚w了解Q在特定的时间段内,我们认ؓ数据产品中的数据是只ȝQ这是利用缓存来提高性能的理论基?/p>

        在上文图2-6中我们看刎ͼglider中存在两层缓存,分别是基于各个异?#8220;?#8221;QdatasourceQ的二~存和整合之后基于独立请求的一U缓存。除此之外,各个异构“?#8221;内部可能q存在自q~存机制?/p>

                                                                   ?-7 ~存控制体系

            ?-7向我们展CZ数据方在缓存控制方面的设计思\。用Lh中一定是带了~存控制?#8220;命o”的,q包括URL中的query stringQ和HTTP头中?#8220;If-None-Match”信息。ƈ且,q个~存控制“命o”一定会l过层层传递,最l传递到底层存储的异?#8220;?#8221;模块?/p>

            ~存pȝ往往有两个问题需要面对和考虑Q缓存穿透与失效时的雪崩效应?/p>

        1. ~存IK是指查询一个一定不存在的数据,׃~存是不命中时被动写的,q且Z定w考虑Q如果从存储层查不到数据则不写入~存Q这导致这个不存在的数据每ơ请求都要到存储层去查询Q失M~存的意义。至于如何有效地解决~存IK问题,最常见的则是采用布隆过滤器Q这个东西,在我的此文章中有介l:Q,所有可能存在的数据哈希C个够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系l的查询压力?/div>

            而在数据方里,淘宝采用了一个更为简单粗暴的ҎQ如果一个查询返回的数据为空Q不是数据不存在,q是pȝ故障Q,我们仍然把这个空l果q行~存Q但它的q期旉会很短,最长不过五分钟?/p>

              2、缓存失效时的雪崩效应尽对底层pȝ的冲击非常可怕。但遗憾的是Q这个问题目前ƈ没有很完的解决Ҏ。大多数pȝ设计者考虑用加锁或者队列的方式保证~存的单U程Q进E)写,从而避免失效时大量的ƈ发请求落到底层存储系l上?/p>

            在数据魔方中Q淘宝设计的~存q期机制理论上能够将各个客户端的数据失效旉均匀地分布在旉轴上Q一定程度上能够避免~存同时失效带来的雪崩效应?/p>

        本文参考:

        1. Z云计的量数据存储模型Q侯建等?/div>
        2. Zhadoop的v量日志数据处理,王小?/div>
        3. Zhadoop的大规模数据处理pȝQ王丽兵?/div>
        4. 淘宝数据方技术架构解析,朋春?/div>
        5. Hadoop作业调优参数整理及原理,guili?/div>

        读者点?/strong>@xdylxdylQ?/p>

        1. We want to count all the books in the library. You count up shelf #1, I count up shelf #2. That's map. The more people we get, the faster it goes. Now we get together and add our individual counts. That's reduce?/div>
        2. 数据方里的~存IK?架构,I数据缓存这些和Hadoop一点关p都么有Q如果是惌一个Hadoop的具体应用的?数据方q部分其实没讲清楚的?/div>
        3. 感觉你是把两个东西؜在一起了。不q这两个都是挺有价值的东西,或者说数据方的架构比Hadoop可能更重要一?基本上大的互联网公司都会选择q么做。Null对象的缓存保留五分钟未必会有好的l果?如果Null对象不是特别?数据的更新和插入不多也可以考虑实时l护?/div>
        4. Hadoop本n很笨重,不知道在数据方里是否是在扮演着实时数据处理的角?q是只是在做U下的数据分析的Q?/div>

        l语Q写文章是一U学习的q程?strong>重他h力_成果Q{载请注明出处。谢谢。July?011/8/20。完?br />
        转自:
        http://blog.csdn.net/v_july_v/article/details/6704077



        鑫龙 2012-12-23 19:55 发表评论
        ]]> ҹþþþ| 91ƷùۺϾþ| ҹƷþþþþþС˵| ˾þۺϳ| vĻþ| 91þþþþþ| ݺݾþŷר| רþۺϾĻ| þAV뾫Ʒɫҹ鶹 | þùƷ99þþþþ | ɫۺϾþþþר| ӰȷŮAV³ɫԴþ | ۺϾþϵ| þ99ƷСѼ| þһ | þ99Ʒ99þ6| þþƷ99Ӱ| ȾþֻоƷ| þþþùһ| ޾ƷþþþAV鶹| һ97ձ˾þۺӰԺ| þþþĻɫ| þþþav| þҹ³Ƭ| ձþþþþĻ| þۺһ| ٸþĻ| Ʒþ߹ۿ| þwww˳ɾƷ㽶| ɫۺϾþ| þùƷHDAV| һaƬþëƬ16| ٸۺϾþĻ| ƷŮٸavѾþ| þþþùɫAVѹۿ| þ×Ʒþþþþ| ƷŮͬһþ| 99þ99þþƷƬ| ޳˾Ʒþ| þþþһvr| þþþþ޾Ʒ|