五分钟深入 Hadoop 内核


hadoop单台内存_hadoop单台内存


回顾

上篇文章我们说到,Hadoop 的工作下图所示,负责把 mapper function 装载到要运行 mapper 的机器上,然后执行 mapper function,之后负责把 mapper 的结果 shuffle 到要运行 reducer 的机器上,下载 reducer 运行得到最终结果。

hadoop单台内存_hadoop单台内存_02



那么下面,我们就通过学习 Hadoop 的 component 架构,来理解 Hadoop 是怎么做到这几步的。

架构

JobTracker

我们上面说了:Hadoop 是一个很强大的 Framework, 那用户怎么使用呢?Hadoop 提供了一个叫做 JobTracker 的 component, 去等待用户提交的Hadoop 任务。

具体说来, 用户告诉 JobTracker 要运行什么 mapper function 和 reducer function, 这个非常 make sense 对不对?Hadoop 就是要帮助用户运行mapper 和 reducer, 不知道他们是什么样的怎么行?

那 Mapper 和 Reducer 长什么样呢?

我们用 Java 举例:用户需要用一个 class 实现 Hadoop 定义的 Mapper 接口,用户在这个 class 里提供 mapper function 的具体实现(当然 Hadoop 也支持别的语言),同样的 reducer function 也是用户实现 Reducer 接口的 class.

既然是 java, 这两个 class 就会存在 jar 中,所以用户要告诉 JobTracker 这个 jar 的路径是什么,也要告诉这个 jar 里,哪个 class 是 mapper, 哪个是 reducer. 只有这样,JobTracker 才能帮助用户把 mapper function 和 reducer function 部署到要运行的机器上。

除此之外,用户还要告诉 JobTracker 要处理的数据在哪里。实际上,数据存储使用的是 HDFS 文件系统。我们之后会为大家详细介绍,这里请大家把 HDFS 想象成普通电脑里的文件系统就好,使用文件夹结构,比如 Linux 下的 /root, /usr, /etc ……

特别的是,HDFS 为了扩大容量,把文件存在很多台机器上,但用户不需要知道分布的具体细节:只要告诉 HDFS 我要哪个目录下的文件,HDFS 就会很神奇的找到相应的机器为用户读取数据(这就是分布式文件系统的特点)。

用户需要告诉 JobTracker 这个任务里需要处理的数据数据存在 HDFS 的哪个目录下面就 OK 啦。同样的,用户也要告诉 JobTracker 这个 Hadoop 任务的输出在哪里,通常也是一个HDFS上的目录。

JobTracker 是以一个进程的形式运行的,一直等待用户提交的任务。说白了,就好像大家玩过的扫雷:你打开这个游戏后,那个窗口一直等待你点击鼠标。我们要记住的是一个 Hadoop cluster 里只有一个 JobTracker.

JobTracker 接收了用户提交的任务之后它做什么呢?

它就要挑选机器来执行 mapper / reducer function.

我们刚才说过,任务要处理的数据被 HDFS 管理。用户是不知道数据存在哪些机器上的,而只要告诉 HDFS 一个目录,它就知道到哪台机器取。

这样 JobTracker 告诉 HDFS 用户提交的输入数据的路径,HDFS 就会告诉 JobTracker 数据在哪台机器上,Job Tracker 也就可以把 mapper function 运行在那台机器上,这样就可以达到非常好的运行效率:mapper function 处理本台机器上的数据。

我们知道 HDFS 和 Hadoop 运行在一组机器上,那这些机器有可能还在运行别的软件,或者处理之前提交的任务。这就有可能造成:明明数据就在 Host A 上,但是 Host A 太忙,没有空闲资源运行 mapper function, 这种情况怎么办呢?

这样的情况下,JobTracker 可能就要退而求其次了:把 mapper function 运行在一个离数据很近的机器上,比如和数据所在机器网络连接速度很快的机器 Host B. 这样,在数据从 Host A 读取到 Host B之后,mapper function 就可以的继续执行。

说起来简单,但是前提是 JobTracker 需要知道每台机器忙不忙,否则它怎么知道存数据的当前机器不能用,或者选择另一个不忙的机器呢?

Hadoop 所做的就是为每一台机器定义 N 个 slot, 就是能同时运行 N 个 mapper function 或者 reducer function, 用几个 slot 被占用评断机器忙不忙。

一个机器有几个 slot 是机器管理员根据机器 cpu 和内存情况设定的,在用户提交任务以前就定义好了。Jobtracker 通过追踪每一台机器上还有几个 slot可以用来判断机器的繁忙程度。

这里你是不是觉得 Hadoop 绕弯子?直接看每台机器 cpu 和 memory 不就好了,为什么还通过 slot 表示?恭喜你,你已经有 Hadoop 2.0 architect 的水平了:) 我们之后讨论哈。

之前说过 JobTracker 只是运行在一台机器上的一个进程,那它如何知道其他机器有哪些 slot 呢?

答案是:它是通过 TaskTracker 来完成的。

TaskTracker

TaskTracker 是运行在每一台机器上的一个 daemon. 它的首要任务就是 keep track of 本台机器有哪些 slot.


这个工作比较简单:TaskTracker 启动时,它从机器管理员写的 config file 里读出这台机器有几个 slot; 当 JobTracker 分配给这台机器一个 mapper function 或者 reducer function, 那 TaskTracker 就会记录下 slot 减少一个。

TaskTracker and Slots

TaskTracker 有一个 heartbeat 机制,就是每隔几秒钟或者几分钟向 JobTracker 发一个信息,告之当前机器还有几个 free slot. 这样,JobTracker 就知道所有 Hadoop 机器资源使用情况。那么下次 JobTracker 收到用户提交的任务时,就有足够的信息决定向哪个机器分配 mapper 或 reducer 任务。


JobTracker task allocation to TaskTrackers

那么当 JobTracker 决定了给机器 a, c, e, f (out of 机器 a-h) 分配任务之后,JobTracker 就向每一台机器发消息,告诉它你要执行的 mapper 或者 reducer function 是什么。

在Java里,这一步就是告诉每一台机器 jar 的路径,以及 mapper class 和 reducer class 的名称。

如果分配的是 mapper function, JobTracker 还要告诉 TaskTracker mapper 要处理的数据路径。我们之前提到了 JobTracker 会尽可能把 mapper 分配到数据所在的机器,这样 mapper 可以从本地文件读取数据了。

当 TaskTracker 得知所有这些信息之后,就可以运行 mapper/reducer.

我们之前说 Hadoop 会去执行 mapper function 和 reducer function, TaskTracker 就是 Hadoop 里负责这个任务的 component.

mapper function 和 reducer function 运行结束以后,TaskTracker 会报告给 JobTracker 运行结果。当所有 mapper 和 reducer 运行结束后,整个 Job 就完成了!


Hadoop / MapReduce 作为非常成熟的大数据架构,已经被部署在很多知名公司的实际系统中、发挥着重要作用,比如 Amazon, Facebook, Apple 等等。

除了并行处理数据外的优势外,其对海量数据的处理和优化也非常有特色。我们会在之后的短文中为大家分享更多优化和可以配置的技巧,让大家轻松面对大叔距离最刁钻的面试题。