文章从《Hadoop技术内幕:深入解析MapReduce架构设计与实现原理》总结而来。
TaskTracker概述
TaskTracker功能
-
执行命令
-
从JobTracker端接收并执行各种命令,如运行任务,杀死任务,提交任务
- 为了防止任务之间干扰,TaskTracker会为每个任务启动一个单独的JVM,并由专门的线程监控其资源使用情况,一旦发现超量使用资源就直接将其杀掉 汇报心跳
-
将本节点的各个任务状态通过周期性心跳汇报给JobTracker
- 包括机器级别信息(如节点健康状况,资源使用情况),任务级别信息(如任务执行进度,任务运行状态,任务Counter值)
RPC协议
-
Tasktracker<—>JobTracker
- 使用InterTrackerProtocol协议
- JobTracker为Server
- TaskTracker为Client TaskTracker<—>Task
- 使用TaskUmbilicalProtocol协议
- TaskTracker为Server
- Task为Client
TaskTracker启动过程四个重要接口
- MRConstants,定义了一些常量
- TaskUmbilicalProtocol,定义了TaskTracker与Task之间的RPC协议
- Runnable,线程接口,以线程方式启动TaskTracker,还维护了一个与JobTracker通信的连接
- TaskTrackerMXBean,提供监控接口
心跳机制
- TaskTracker服务初次启动之后,会向JobTracker发送第一个心跳信息,JobTracker经过检查之后将该TaskTracker添加到Hadoop集群中。
- JobTracker和TaskTracker之间采用pull通信模型,即JobTracker从不会主动与TaskTracker通信,而总是被动等待TaskTracker周期性地汇报信息并领取其对应命令,该过程即为心跳。
心跳发送过程
判断是否到达心跳发送时间
心跳发送时间由集群规模(TaskTracker数量)与任务运行状况决定
任务运行状况:当TaskTracker中存在某个任务运行完成或者失败,会缩短心跳间隔,以便快速汇报JobTracker,从而进行相应处理——带外心跳
mapreduce.tasktracker.outofband.heartbeat = false
决定是否启用心跳机制
mapreduce.tasktracker.outofband.heartbeat.damper = 1000000
为心跳收缩因子,心跳机制启用才能产生作用。如果某时刻有X个任务运行完成,则心跳间隔变为:
heartbeatIntervalX∗oobHeartbeatDamper+1 h e a r t b e a t I n t e r v a l X ∗ o o b H e a r t b e a t D a m p e r + 1heartbeatInterval
是从JobTracker获取的心跳间隔
oobHeartbeatDamper
是心跳收缩因子检查TaskTracker自身代码编译版本号与JobTracker 是否一致——不一致返回DENIED
检查是否有磁盘损坏——损坏返回STALE
MapReduce的中间结果输出目录是
mapred.local.dir
所指定,一般有多个目录组成,每个目录对应一块磁盘。因为无备份,目录损坏或者丢失则中间结果就需要重新计算。以
mapred.disk.healthChecker.interval = 60
秒为周期进行目录检查。发送心跳
TaskTracker将自身基本信息,节点资源使用情况,各个任务状态封装到可序列化类
TaskTrackerStatus
中。List<TaskStatus> taskReports;
保存了当前TaskTracker所有任务(Task Attempt)的运行状态private TaskTrackerHealthStatus healthStatus;
- 通过NodeHealthCheckerService线程周期性调用健康监测脚本计算
- 将状态差的节点标记为unhealthy,由TaskTracker移入黑名单
- 将状态好的节点标记为healthy,若在黑名单中则由TaskTracker移除
- 健康监测脚本可以自定义检测网络,磁盘,文件系统等问题,即自定义节点健康状态
private ResourceStatus resStatus;
resStatus是由可插拔组件ResourceCalculatorPlugin(抽象类)获取的。
只存在于linux版本的LinuxResourceCalculatorPlugin中,通过读取/proc下的meminfo,cpuinfo,stat获取节点上的内存,CPU等资源的实施情况实现。
接收并执行命令——没收到返回NORMAL,收到返回STALE
JobTracker将心跳应答封装到一个
HeartbeatResponse
对象中,由两部分组成:作业集合
recoveredJobs
,是上次关闭JobTracker时正在运行的作业集合(作业恢复);TaskTracker重置Reduce Task的FetchStatus信息,迫使其重新从Map Task拷贝数据需要执行的命令列表
启动新任务
协调者:JobTracker,参与者:TaskTracker上的任务
-
两阶段提交协议(two-phase commit protocol,2PC)
-
准备阶段。参与者Task执行完自己的操作,就可以将状态改为COMMIT PENDING,通过RPC发给TaskTracker,TaskTracker收缩心跳间隔将状态汇报给协调者JobTracker。
-
提交阶段
- 若可以提交,则协调者向参与者发送CommitTaskAction命令,参与者将状态改为SUCCEEDED(TaskTracker从JobTracker获取,TaskTracker将对应Task加入commitResponses中,Task通过对照commitResponses从而转移数据);
- 若不允许提交,则向参与者发送“提交失败”请求,参与者将状态改为“提交失败”后退出。
杀死任务
- JobTracker向TaskTracker发送KillTaskAction命令
- TaskTracker从runningJobs中将该任务清除,将运行状态由RUNNING改为KILLED_UNCLEAN,并通知directoryCleanupThread线程清理其工作目录,释放所占槽位。
- JobTracker将KILLED_UNCLEAN的Task Attempt添加到待清理队列并封装到LaunchTaskAction通过心跳交给TaskTracker
- TaskTracker启动JVM清理Task Attempt已写入的HDFS临时数据将KILLED_UNCLEAN改为SUCCEEDED
- JobTracker将检查tasksToKill列表后,其改为KILLED
- 先清理通过清理任务的方式各个TaskTracker
- 清理自身工作目录及相关内存结构
重新初始化
-
作业目录管理
TaskTracker上的目录可以分为两种
-
数据目录
- 使用轮询的方式使用目录 日志目录
- Hadoop只允许TaskTracker将日志目录存在一个磁盘上。
-
TaskTracker包含两种日志,
- 系统日志
存放在$hadoop.log.dir/<tasktracker-name>.log
以及$hadoop.log.dir/<tasktracker-name>.out
中 - 用户日志
存放在$hadoop.log.dir/userlogs/
下
Hadoop0.20.204.0引入了多磁盘日志目录,用户日志将被轮询查询的方式分布到$hadoop.log.dir
所指定的各个磁盘目录下。
- 系统日志