1.HTTP请求流程
- 应用层:分解url(服务器和请求资源);生成http请求消息;DNS域名解析;发给操作系统;
- 传输层:添加TCP头部;三次握手建立连接;操作系统缓存区累积一个网络包大小的数据或最大等待时间后发送给IP模块;
- 网络层:添加IP头部和MAC头部;(如果为局域网会发送给路由器,路由器拆封到Ip层,根据路由控制表,封装上目标局域网的头信息后转发给目标局域网上的主机);IP中包含网络ID和主机ID,可通过子网掩码与IP按位与操作获取网络ID;
- 链路层:添加报头、帧校验序列;变为电信号;
- 物理层:最终网卡中的PHY模块会将通用电信号转换成网络传输所需的格式,通过网线发送出去。经过网络转发后,最终到达服务器;
- 服务器: 服务器反向重复上述步骤,把电信号逐步转换回http请求信息并进行处理;
- 服务器 服务器返回请求响应,先发送头信息,然后发送一个空白行来表示头信息的发送到此结束,最后以Content-Type应答头信息所描述的格式发送用户所请求的实际数据;
- 服务器关闭TCP连接或者保持连接。
2.MapReduce作业流程(Yarn)
下图中重要的实体:
-
客户端:用于提交job
-
Yarn的资源管理器(ResourceManager,RM):负责协调集群上的资源分配(资源调度器)
-
Yarn的节点管理器(NodeManager,NM):负责节点内所有容器的生命周期的管理,监视资源和跟踪节点健康并上报给AM。
-
Yarn的应用管理器(ApplicationMaster,AM):负责协调运行MapReduce作业的任务,向RM申请资源,跟踪job状态和进度。
-
HDFS:用来与其他实体共享作业文件。
- 作业提交(
RM分配ID,客户端计算分片和上传作业资源)
- client 调用 job.waitForCompletion 方法,向整个集群提交 MapReduce 作业 (第 1 步) 。
- 新的作业 ID(应用 ID) 由RM分配 (第 2 步)。
- 作业的 client 核实作业的输出, 计算输入的 split, 将作业的资源 (包括 Jar 包,配置文件, split 信息) 拷贝给 HDFS(第 3 步)。
- 最后, 通过调用RM的 submitApplication() 来提交作业 (第 4 步)。
- 作业初始化(
启动AM,AM创建map/reduce任务对象,AM创建输出路径)
- 当RM收到 submitApplciation() 的请求时, 就将该请求发给调度器 (scheduler), 调度器分配 container, 然后RM在该 container 内启动AM, 由节点管理器监控 (第 5 步)。
- AM通过创造一些 bookkeeping 对象来监控作业的进度, 得到任务的进度和完成报告 (第 6 步)。
- 然后AM通过分布式文件系统得到由客户端计算好的输入 split(第 7 步),然后为每个输入 split 创建一个 map 任务, 根据
mapreduce.job.reduces创建 reduce 任务对象。 - 最后,在任何任务运行之前,application master调用setupJob()方法设置OutputCommitter,创建输出路径。
- 任务分配(
AM向RM申请资源,RM调度器提供最优资源分配)
- 如果作业很小, AM会选择在其自己的 JVM 中运行任务。
- 如果不是小作业, 那么AM向RM请求 container 来运行所有的 map 和 reduce 任务 (第 8 步)。这些请求是通过心跳来传输的, 包括每个 map 任务的数据位置,比如存放输入 split 的主机名和机架 (rack),调度器利用这些信息来调度任务,尽量将任务分配给存储数据的节点, 或者分配给和存放输入 split 的节点相同机架的节点。
- 任务运行(
AM启动container,资源本地化,运行map/reduce)
- 当一个任务由RM的调度器分配给一个 container 后,AM通过联系NM来启动 container(第 9 步)。
- 任务由一个主类为 YarnChild 的 Java 应用执行, 在运行任务之前首先本地化任务需要的资源(从HDFS下载),比如作业配置,JAR 文件, 以及分布式缓存的所有文件 (第 10 步)。
- 最后, 运行 map 或 reduce 任务 (第 11 步)。
-
进度和状态更新
YARN 中的任务将其进度和状态 (包括 counter) 返回给应用管理器, 客户端每秒 (通 mapreduce.client.progressmonitor.pollinterval 设置) 向AM请求进度更新, 展示给用户。 -
作业完成
除了向应用管理器请求作业进度外, 客户端每 5 分钟都会通过调用 waitForCompletion() 来检查作业是否完成,时间间隔可以通过 mapreduce.client.completion.pollinterval 来设置。作业完成之后, 应用管理器和 container 会清理工作状态, OutputCommiter 的作业清理方法也会被调用。作业的信息会被作业历史服务器存储以备之后用户核查。