Hadoop工作流程

来源:互联网 发布:广东省电子网络发票 编辑:程序博客网 时间:2024/05/21 18:45

这里我就按我自己对Hadoop工作流程的理解大概写一下,如果哪位大牛看到,有错误或漏洞请指正。这是一篇综述类的博客,我会就某些局部细节写后续博客。

       Hadoop集群中分主节点master节点和slave节点,master节点监控slave节点。master和slave之间通过ssh协议进行通信。

       master节点上部署有JobTracker和NameNode,当然也可以部署TaskTracker和DataNode。slave节点上部署TaskTracker和DataNode节点。JobTracker监控TaskTracker,NameNode管理DataNode节点。每个TaskTracker节点又有若干个map和reducer槽。每个map槽或reduce槽就代表一个任务。TaskTracker监控本机的map和reduce任务。如果map任务或reduce任务有更新,会通过心跳(一般间隔是3秒)告诉TraskTracker,TraskTracker再通过心跳(一般至少5s,因为代价比较大)告诉JobTracker。

在介绍数据流之前,先介绍一个分区的概念:Partitioner。这个类主要用来根据关键字对<key, value>对进行分区,默认是采用哈希操作进行分区,分区被传送至reduce进行处理。

       用户首先把要处理的数据上传到HDFS,HDFS是分布式文件系统,提供了很好的容错性,它将上传来的数据分块儿,分别存储到集群中的机器,默认每个数据块儿都有三个副本,如果觉得3个不合适,我们可以修改副本个数,这些数据分布,都有master节点上的NameNode控制管理。

       用户提交jar文件后,JobTracker根据作业调度算法(一般是FIFO)决定下一个执行的作业。map阶段JobTracker根据数据本地化最优的原则分配任务,因为map任务处理本地数据避免了从其他机器通过网络传输数据造成的效率低下。每个TaskTracker可以多个map任务,map任务的数量受TaskerTracker的map任务槽数量的限制。

       map任务在执行过程中,会产生输出存储到本地的环形内存缓冲区中,默认情况下,缓冲区大小只有100MB,此值可以通过io.sort.mb属性来调整。一旦缓冲区内容达到阈值(io.sort.spill.percent,默认为0.80,或80%),一个后台线程便开始把内容写到磁盘中,在写磁盘的过程中,map输出继续被写到缓冲区,但如果在此期间缓冲区被填满,map会阻塞到写磁盘过程完成。写磁盘将按轮询方式写到mapred.local.dir属性指定的特定子目录中。在写磁盘之前,线程首先根据数据最终要传送到的reducer把数据划分成相应的分区,在每个分区中,后台线程按键进行那个内排序,如果有一个combiner,它会在排序后的输出上运行。一旦内存缓冲区达到溢出写的阈值,就会新建一个溢出写文件,因此在map任务写完其最后一个输出记录之后,会有几个溢出写文件。在任务完成之前,溢出写文件被合并成一个已分区且已排序的输出文件。配置属性io.sort.factor控制着一次最多能合并多少流,默认值是10。

      其实上述过程可以简单描述为,当map内存缓冲区超过设定的阈值时,就会把内存中的数据写到磁盘上的一个临时文件,但是在进行写磁盘之前,hadoop会首先根据关键字对键值对进行分区,然后在分区内按键值进行排序,如果此时设置了combiner我们可以在map的输出上运行combiner,运行combiner的作用就是减少map输出进而减少网络之间的通信量,当然,我们也可以通过对map输出进行压缩来减少网络流量。。。。待续


具体可参阅Hadoop很经典的三篇论文:

MapReduce: Simplified Data Processing on Large Clusters

The Google File System

Bigtable: A Distributed Storage System for Structured Data