当前位置: 首页 > article >正文

深入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的核心设计实现,本篇内容主要是帮助大家拓宽一下视野。


http://www.kler.cn/a/520515.html

相关文章:

  • React 前端框架实战教程
  • FreeRtos的使用教程
  • 数据结构:二叉树—面试题(二)
  • [操作系统] 进程地址空间管理
  • OLMo:开启AI研究新纪元的开放利器
  • 牛客周赛 Round 78 A-C
  • 应用层协议 HTTP 讲解实战:从0实现HTTP 服务器
  • Kubectl 与 Helm 详解
  • 《DeepSeek R1:大模型的安装与部署全攻略》
  • 2024年度总结——理想的风,吹进现实
  • 移动光猫怎么自己改桥接模式?
  • Linux——网络(udp)
  • 非根目录部署 nextjs 项目,资源文件 请求404 的问题
  • windows蓝牙驱动开发-查询蓝牙接口
  • 在Windows系统中本地部署属于自己的大语言模型(Ollama + open-webui + deepseek-r1)
  • python3+TensorFlow 2.x(四)反向传播
  • 使用Python爬虫获取1688商品拍立淘API接口(item_search_img)的实战指南
  • UE骨骼模拟物理
  • 【Python】类
  • QT:tftp client 和 Server
  • 查找地理处理工具
  • Scrapy如何设置iP,并实现IP重用, IP代理池重用
  • python3+TensorFlow 2.x(三)手写数字识别
  • PostgreSQL数据库的运行机制和架构体系
  • RabbitMQ 架构分析
  • 探索前端的未来:深度使用 SolidJS 构建高性能用户界面