深入MapReduce——MRv1设计

引入

通过前面篇章,我们对于MapReduce已经有了不错的了解,由于现在几乎没有使用MapReduce去开发业务需求的场景,甚至MapReduce这个引擎都随着时代变化,快要完全被淘汰了,所以我们就不去水看使用MapReduce编程相关的东西,而是把重点放到一些我们比较感兴趣的点上。

今天我们先来看看MRv1计算框架的核心设计实现。

MR Job生命周期

首先,我们梳理 MR Job 的生命周期流程如下:

  1. Job提交与初始化
    1. JobClient将作业的相关文件上传到HDFS
    2. JobClient通知JobTracker
    3. JobTracker的作业调度模块对作业进行初始化( JobInProgress和TaskInProgress)
  2. Job 调度与监控
    JobTracker的任务调度器(TaskScheduler)按照一定策略,将task调度到空闲的TaskTracker
  3. Job JVM启动
    TaskTracker下载任务所需的文件,并为每个Task启动一个独立的JVM
  4. Job执行
    TaskTracker启动Task,Task通过RPC将其状态汇报给TaskTracker,再由TaskTracker汇报给JobTracker
  5. 完成Job
    数据写到HDFS

MRv1架构设计

通过前面篇章,我们知道MRv1是基于Hadoop1.x的架构的,如下图所示:

左边是我们很熟悉的HDFS的架构,右边则是MapReduce架构设计。

我们继续深入涉及的核心组件:

JobTracker

核心设计

  • 负责集群资源监控和作业调度
  • 通过心跳监控所有TaskTracker的健康状况
  • 监控Job的运行情况、执行进度、资源使用,交由任务调度器负责资源分配
  • 任务调度器可插拔:FIFO Scheduler、Capacity Scheduler、FIFO Scheduler

JobTracker本质是一个后台服务进程,启动之后,会一直监听并接收来自各个TaskTracker发送的心跳信息,这里面包含节点资源使用情况和任务运行情况等信息。JobTracker会将这些信息统一保存起来,并将这些信息告诉任务调度器,而调度器会在资源出现空闲时,选择合适的任务使用这些资源。

这种将新作业通知TaskScheduler的操作,类似于观察者设计模式。

核心功能

JobTracker的核心功能是作业调度资源监控

作业控制

JobTracker在其内部以"三层多叉树"的方式描述和跟踪每个作业的运行状态。

作业被抽象成三层,从上往下依次为:作业监控层、任务监控层和任务执行层。

  • 在作业监控层中,每个作业由一个JobInProgress(JIP)对象描述和跟踪其整体运行状态以及每个任务的运行情况;
  • 在任务监控层中,每个任务由一个TaskInProgress(TIP)对象描述和跟踪其运行状态;
  • 在任务执行层中,考虑到任务在执行过程中可能会失败,因而每个任务可能尝试执行多次,直到成功。

JobTracker将每次尝试运行一次任务称为"任务运行尝试"​,而对应的任务运行实例称为Task Attempt(TA)​。当任何一个Task Attempt运行成功后,其上层对应的TaskInProgress会标注该任务运行成功;而当所有的TaskInProgress运行成功后, JobInProgress则会标注整个作业运行成功。

资源管理

JobTracker不断接收各个TaskTracker周期性发送过来的资源量和任务状态等信息,并综合考虑TaskTracker(所在DataNode)的数据分布、资源剩余量、作业优先级、作业提交时间等因素,为TaskTracker分配最合适的任务。

Hadoop引入了 slot 概念表示各个节点上的计算资源。为了简化资源管理,Hadoop将各个节

点上的资源(CPU、内存和磁盘等)等量切分成若干份,每一份用一个slot表示,同时规定一个Task

可根据实际需要占用多个slot。

容错机制

JobTracker容错的关键技术点是如何保存和恢复作业的运行时信息。

从作业恢复粒度角度看,当前存在三种不同级别的恢复机制,级别由低到高依次是作业级别、任务级别和记录级别,其中,级别越低,实现越简单,但造成的资源浪费越严重。

  • 在1.0.0以及之前版本中,Hadoop采用了任务级别的恢复机制 ,即以任务为基本单位进行恢复,这种机制是基于事务型日志完成作业恢复的,它只关注两种任务:运行完成的任务和未运行完成的任务。作业执行过程中,JobTracker会以日志的形式将作业以及任务状态记录下来,一旦JobTracker重启,则可从日志中恢复作业的运行状态,其中已经运行完成的任务无须再运行,而未开始运行或者运行中的任务需重新运行。
  • 上一种方案实现比较复杂,需要处理的特殊情况比较多,为了简化设计,从0.21.0版本开始,Hadoop采用了作业级别的恢复机制 。该机制不再关注各个任务的运行状态,而是以作业为单位进行恢复,它只关注两种作业状态:运行完成或者未运行完成。当JobTracker重启后,凡是未运行完成的作业将自动被重新提交到Hadoop中重新运行。

作业恢复的机制处理比较简单。每个新的作业(Job)会在JobTracker的工作目录下为该作业创建一个以该作业的JobId为命名的目录,目录底下放该作业的Job-info和JobToken文件。如果该作业成功运行结束,那么就会在作业的Cleanup工作中删除掉该文件夹。

所以,当某个时刻JobTracker如果突然因为故障重启了,那么该工作目录下如果JobId工作目录,就说明重启之前还有作业未运行结束*(因为运行结束的Job都会把自己的目录清除掉)*,此时就会把目录中包含的作业重新提交运行,并且JobTracker会把这些重新提交运行的Job的Id信息通过心跳信息的回复告知TaskTracker。

那些之前就已经运行在TaskTracker上的任务就是根据TaskID和JobID来更新JobTracker中的作业和任务的信息状态的。原本就正在运行的任务仍然能够正常的更新JobTracker。已经运行结束的Task会把新提交的作业的Task直接更新为运行结束。

TaskTracker

TaskTracker是JobTracker与Task之间的"中间人"

核心设计

  • 具体执行Task的单元
  • 以slot为单位等量划分本节点的资源,分为Map Slot和Reduce Slot
  • 通过心跳周期性向JobTracker汇报本节点的资源使用情况和任务运行进度
  • 接收JobTracker的命令执行相应的操作*(启动新任务、杀死任务等)*

TaskTracker与JobTracker和Task之间采用了RPC协议进行通信。对于TaskTracker和JobTracker而言,它们之间采用InterTrackerProtocol协议,其中,JobTracker扮演RPC Server的角色,而TaskTracker扮演RPC Client的角色;对于TaskTracker与Task而言,它们之间采用TaskUmbilicalProtocol协议,其中,TaskTracker扮演RPC Server的角色,而Task扮演RPC Client的角色。

关于RPC可以看这篇文章

核心功能

TaskTracker核心功能是汇报心跳执行命令。

汇报心跳

TaskTracker周期性地将所在节点上各种信息通过心跳机制汇报给JobTracker。这些信息包括两部分:机器级别信息,如节点健康状况、资源使用情况等;任务级别信息,如任务执行进度、任务运行状态、任务Counter值等。

心跳是Jobtracker和Tasktracker的桥梁,它实际上是一个RPC函数,Tasktracker周期性的调用该函数汇报节点和任务状态信息,从而形成心跳。在Hadoop中,心跳主要有三个作用:

  1. 判断Tasktracker是否活着
  2. 及时让Jobtracker获取各个节点上的资源使用情况和任务运行状态
  3. 为Tasktracker分配任务

Tasktracker周期性的调用RPC函数heartbeat向Jobtracker汇报信息和领取任务。

JobTracker与TaskTracker之间采用了Pull而不是Push模型,是JobTracker不会主动向TaskTracker发送任何信息,而是由TaskTracker主动通过心跳领取属于自己的消息,JobTracker只能通过心跳应答的形式为各个TaskTracker分配任务。

执行命令

JobTracker收到TaskTracker心跳信息后,会根据心跳信息和当前作业运行情况为该TaskTracker下达命令,主要包括启动任务(LaunchTaskAction)​、提交任务(CommitTaskAction)​、杀死任务(KillTaskAction)​、杀死作业(KillJobAction)和重新初始化(TaskTrackerReinitAction)5种命令。其中,过程比较复杂的是启动任务。为了防止任务之间的干扰,TaskTracker为每个任务创建一个单独的JVM​,并有专门的线程监控其资源使用情况,一旦发现超量使用资源就直接将其杀掉。

容错机制

TaskTracker负责执行来自JobTracker的各种命令,并将命令执行结果定时汇报给它。在一个Hadoop集群中,TaskTracker数量通常非常多,设计合理的TaskTracker容错机制对于及时发现存在问题的节点显得非常重要。

Hadoop提供了三种TaskTracker容错机制:

  1. 超时机制
    超时机制是一种在分布式环境下常用的发现服务故障的方法。如果一种服务在一定时间未响应,则可认为该服务出现了故障,从而启动相应的故障解决方案。
  2. 灰名单与黑名单机制
    这两种名单中的TaskTracker均不可以再接收作业。
  3. Exclude list与Include list
    Exclude list是一个非法节点列表,所有位于该列表中的节点将无法与JobTracker连接(在RPC层抛出异常)。Include list是一个合法节点列表(类似于节点白名单),只有位于该列表中的节点才允许向JobTracker发起连接请求。默认情况下,这两个列表是空的,表示允许任何节点接入JobTracker。这两个名单中的节点均由管理员配置,并可以动态加载生效。

总结

今天深入梳理了MRv1的核心设计实现,本篇内容主要是帮助大家拓宽一下视野。

相关推荐
乙卯年QAQ1 小时前
【Elasticsearch】Elasticsearch的查询
大数据·elasticsearch·搜索引擎
XianxinMao3 小时前
科技巨头AI投资引领未来增长
大数据·人工智能·科技
言之。3 小时前
【Spark速通】
大数据·分布式·spark
WHYBIGDATA6 小时前
Hive安装教程
大数据·hive·hadoop
乙卯年QAQ6 小时前
【Hadoop】Hadoop 概述
大数据·hadoop·分布式
天选之子1236 小时前
spark运行流程
大数据·分布式·spark
李匠20246 小时前
大数据学习之Kafka消息队列、Spark分布式计算框架一
大数据·学习·kafka
黄雪超8 小时前
深入MapReduce——从MRv1到Yarn
大数据·hadoop·mapreduce
Neil Parker15 小时前
搭建Spark分布式集群
大数据·分布式·spark
请为小H留灯15 小时前
Python 数据清洗与处理常用方法全解析
大数据·python·jupyter·pandas