Hadoop入门之HDFS与MapReduce

fmms 12年前
     Hadoop的核心就是HDFS与MapReduce    <br />    <br />    <p>1. HDFS</p>    <p><img style="width:704px;height:486px;" alt="Hadoop入门之HDFS与MapReduce" src="https://simg.open-open.com/show/fe65fb47125bda1541f9c0677ac1cb7c.gif" /></p> master/slave : Namenode,Datanode    <br /> Namenode:Namenode执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录。它也负责确定数据块到具体Datanode节点的映射。    <br /> Datanode:Datanode负责处理文件系统客户端的读写请求。在Namenode的统一调度下进行数据块的创建、删除和复制。    <br />    <br />    <br /> 文件怎么存的?    <br /> 文件分块,存到Datanode里。分块的原则:除了最后一个数据块,其它数据块的大小相同,一般为64MB or 128MB。    <br /> 每个数据块有副本(一般为3):副本多了浪费空间。    <br /> 副本存储:在大多数情况下,副本系数是3,HDFS的存放策略是将一个副本存放在本地机架的节点上,一个副本放在同一机架的另一个节点上,    <br />           最后一个副本放在不同机架的节点上。这种策略减少了机架间的数据传输,这就提高了写操作的效率。    <br /> 副本目的:可靠性+性能    <br />    <br />    <br /> 集群中单一Namenode的结构大大简化了系统的架构。Namenode是所有HDFS元数据的仲裁者和管理者,这样,用户数据永远不会流过Namenode。    <br />    <br />    <br /> client读数据:为了降低整体的带宽消耗和读取延时,HDFS会尽量让读取程序读取离它最近的副本。如果在读取程序的同一个机架上有一个副本,    <br />               那么就读取该副本。如果一个HDFS集群跨越多个数据中心,那么客户端也将首先读本地数据中心的副本。    <br /> client写数据:一次性写入,多次读取,数据访问会高效。    <br />    <br />    <br /> 通讯协议:tcp/ip     <br />    <br />    <br />    <p>2. MapReduce</p>    <p><img style="width:680px;height:513px;" alt="Hadoop入门之HDFS与MapReduce" src="https://simg.open-open.com/show/fb0f754ce82fd01547c53846202f8ec7.jpg" /></p> 流程:    <br /> Inputformat——》map——》(combine)——》partition——》copy&merge——》sort——》reduce——》outputformat    <br /> 优化措施:合理设计MapReduce, 代码级别    <br />    <p>转载一篇讲的比较好的文章:</p>    <p style="text-align:left;padding-bottom:0px;line-height:21px;border-right-width:0px;background-color:#ebebeb;list-style-type:none;margin-top:0px;text-indent:2em;font-family:simsun;word-wrap:normal;margin-bottom:5px;border-top-width:0px;border-bottom-width:0px;color:#323e32;font-size:14px;word-break:normal;border-left-width:0px;padding-top:0px;"><span style="font-family:宋体,simsun;word-wrap:normal;word-break:normal;">我 们以wordcount为例,假设有个6400M的文件,100台hadoop机器(准确地说应该是tasktracker机),默认block大小为 64M,这样每台执行map的文件刚好是一个64M的block文件(假设这个分发过程已经完成,同时忽略备份数之类的细节),并且我们使用10个 reduce任务来归并文件。Hadoop的mapreducer的执行过程如下:</span></p>    <p style="text-align:left;padding-bottom:0px;line-height:21px;border-right-width:0px;background-color:#ebebeb;list-style-type:none;margin-top:0px;text-indent:2em;font-family:simsun;word-wrap:normal;margin-bottom:5px;border-top-width:0px;border-bottom-width:0px;color:#323e32;font-size:14px;word-break:normal;border-left-width:0px;padding-top:0px;">这100台机器上面的map都是并发、独立的执行,以wordcount为例,步骤如下:</p>    <p style="text-align:left;padding-bottom:0px;line-height:21px;border-right-width:0px;background-color:#ebebeb;list-style-type:none;margin-top:0px;text-indent:2em;font-family:simsun;word-wrap:normal;margin-bottom:5px;border-top-width:0px;border-bottom-width:0px;color:#323e32;font-size:14px;word-break:normal;border-left-width:0px;padding-top:0px;">1、 <wbr /> 每个map任务使用默认的textinputformat类的LineRecordReader方法按行读取文件,这个读取的行数据就 被交给map函数去执行,wordcount的map做的就是提取里面的单词,并以单词为key,1为value作为输出,格式为:     <word integer(1)="">      。     </word></p>    <p style="text-align:left;padding-bottom:0px;line-height:21px;border-right-width:0px;background-color:#ebebeb;list-style-type:none;margin-top:0px;text-indent:2em;font-family:simsun;word-wrap:normal;margin-bottom:5px;border-top-width:0px;border-bottom-width:0px;color:#323e32;font-size:14px;word-break:normal;border-left-width:0px;padding-top:0px;">2、 <wbr /> 如果有combine,先对第一步的输出结果就行combine操作。Combine就是个小reduce操作,作用就是对某个map 自己的输出结果先进行一次归并,把相同word的计数累加,这样假设某个map输出结果做如果有50%的重复word,那combine后的中间结果大小 可以减少一半,可减少后续的patition、copy、sort等的开销,提高性能。</p>    <p style="text-align:left;padding-bottom:0px;line-height:21px;border-right-width:0px;background-color:#ebebeb;list-style-type:none;margin-top:0px;text-indent:2em;font-family:simsun;word-wrap:normal;margin-bottom:5px;border-top-width:0px;border-bottom-width:0px;color:#323e32;font-size:14px;word-break:normal;border-left-width:0px;padding-top:0px;">3、 <wbr /> 每个map对自己的输出文件进行patition操作。上面提到有10个reducer任务,那默认的patition操作就是对 map的输出kay进行hash,并对10求余(hash(key)),并提供10个文件(内存足够的话可以是链表等内存数据结构),假设是r1、 r2….r10这10个文件,把不同key的放到不同的文件,这次操作就可以把相同key聚合到同一个文件。由于算法一样,保证了每个map的输出结果经 过这个操作后,相同key的肯定在同一个聚合文件里,比如某个单词word肯定都在r1文件里。</p>    <p style="text-align:left;padding-bottom:0px;line-height:21px;border-right-width:0px;background-color:#ebebeb;list-style-type:none;margin-top:0px;text-indent:2em;font-family:simsun;word-wrap:normal;margin-bottom:5px;border-top-width:0px;border-bottom-width:0px;color:#323e32;font-size:14px;word-break:normal;border-left-width:0px;padding-top:0px;">4、 <wbr /> 接下来就是copy文件的过程了,10个reducer任务各自从所有map机器上取到属于自己的文件,比如reducer1会从100台map机器上取到所有r1文件,reducer2取所有r2的文件,这样同一类word已经到了同一台reducer机器上了。</p>    <p style="text-align:left;padding-bottom:0px;line-height:21px;border-right-width:0px;background-color:#ebebeb;list-style-type:none;margin-top:0px;text-indent:2em;font-family:simsun;word-wrap:normal;margin-bottom:5px;border-top-width:0px;border-bottom-width:0px;color:#323e32;font-size:14px;word-break:normal;border-left-width:0px;padding-top:0px;">5、 <wbr /> 每个reducer合并(meger)自己取到的文件,reducer1就是合并100个r1文件(实际过程是在上面第4步操作中会边copy边meger,在内存中)。</p>    <p style="text-align:left;padding-bottom:0px;line-height:21px;border-right-width:0px;background-color:#ebebeb;list-style-type:none;margin-top:0px;text-indent:2em;font-family:simsun;word-wrap:normal;margin-bottom:5px;border-top-width:0px;border-bottom-width:0px;color:#323e32;font-size:14px;word-break:normal;border-left-width:0px;padding-top:0px;">6、 <wbr /> 合并好后进行下sort(排序)操作,再次把不同小文件中的同一个单词聚合在一起。作为提供给reduce操作的数据。</p>    <p style="text-align:left;padding-bottom:0px;line-height:21px;border-right-width:0px;background-color:#ebebeb;list-style-type:none;margin-top:0px;text-indent:2em;font-family:simsun;word-wrap:normal;margin-bottom:5px;border-top-width:0px;border-bottom-width:0px;color:#323e32;font-size:14px;word-break:normal;border-left-width:0px;padding-top:0px;">7、 <wbr /> 进行reduce操作,对同一个单词的value列表再次进行累加,最终得到某个单词的词频数。</p>    <p style="text-align:left;padding-bottom:0px;line-height:21px;border-right-width:0px;background-color:#ebebeb;list-style-type:none;margin-top:0px;text-indent:2em;font-family:simsun;word-wrap:normal;margin-bottom:5px;border-top-width:0px;border-bottom-width:0px;color:#323e32;font-size:14px;word-break:normal;border-left-width:0px;padding-top:0px;">8、 <wbr /> Outputformat操作,把reduce结果写到磁盘。</p>    <p style="text-align:left;padding-bottom:0px;line-height:21px;border-right-width:0px;background-color:#ebebeb;list-style-type:none;margin-top:0px;text-indent:2em;font-family:simsun;word-wrap:normal;margin-bottom:5px;border-top-width:0px;border-bottom-width:0px;color:#323e32;font-size:14px;word-break:normal;border-left-width:0px;padding-top:0px;">所以,总的流程应该是这样的:</p>    <p style="text-align:left;padding-bottom:0px;line-height:21px;border-right-width:0px;background-color:#ebebeb;list-style-type:none;margin-top:0px;text-indent:2em;font-family:simsun;word-wrap:normal;margin-bottom:5px;border-top-width:0px;border-bottom-width:0px;color:#323e32;font-size:14px;word-break:normal;border-left-width:0px;padding-top:0px;">* <wbr /> <wbr /> Inputformat——》map——》(combine)——》partition——》copy&merge——》sort——》reduce——》outputformat</p>    <p style="text-align:left;padding-bottom:0px;line-height:21px;border-right-width:0px;background-color:#ebebeb;list-style-type:none;margin-top:0px;text-indent:2em;font-family:simsun;word-wrap:normal;margin-bottom:5px;border-top-width:0px;border-bottom-width:0px;color:#323e32;font-size:14px;word-break:normal;border-left-width:0px;padding-top:0px;">由此我们也可以看出,执行reduce的代价还是有些的,所以如果我们的应用只使用map就能搞定的话,那就尽量不要再有reduce操作在其中。</p>    <br /> 3. Hadoop调度流程    <br />    <br />    <br />    <img alt="Hadoop入门之HDFS与MapReduce" src="https://simg.open-open.com/show/7edc8325b3578ac46710bcdffeded18f.jpg" width="587" height="562" />    <br />    <br /> 转自:    <a href="/misc/goto?guid=4959500381043985451" target="_blank">http://blog.csdn.net/perfumekristy/article/details/7182323</a>