概述

监控节点健康状况和Container资源使用。

架构图

image.png

模块

0x01 NodeStatusUpdater

与RM唯一通道。向RM注册会上报总资源(心跳就不上报了)。主要就是使用ResourceTracker。

0x02 ContainerManager

YARN NM核心组件,管理所有Container的生命周期。接收到AM container启动请求,YARN NM开始校验Container Token及资源文件,创建应用实例和Container实例并存储至本地,结果返回后应用实例状态变为LAUNCHED;

RPC Server

主要是实现ContainerManagermentProtocol协议。和AM通信唯一通道。任何对容器的操作请求都会经由ContainerTokensSecretManager。

ResourceLocalizationService

负责资源本地化和资源回收。
资源本地化服务,负责Container所需资源的本地化。它能够按照描述从HDFS上下载Container所需的文件资源(jar包、可执行文件等),并尽量将它们分摊到各个磁盘上以防止出现访问热点。初始化各种服务组件、创建工作目录、从HDFS下载运行所需的各种资源至Container工作目录(路径为: ${yarn.nodemanager.local-dirs}/usercache/${user}/appcache//)。
资源回收则是资源本地化的逆过程,清理各种资源。

ContainersLauncher

维护一个线程池并行负责Container的具体操作,包括启动、重启、恢复和清理等。将待运行Container所需的环境变 量和运行命令写到Container工作目录下的launch_container.sh脚本中,然后运行该脚本启动Container。

ContainersMonitor

监控容器资源使用。如果内存使用超过虚拟内存大小,NM将杀死此容器,防止影响其他容器运行。只有内存通过此方式限制。CPU则使用Linux的Cgroups。

其他组件

AuxServices:附属服务在NM启动前配置好。
LogHandler:可插拔组件。日志保存本地磁盘还是上传到文件系统
ContainerEventDispatcher:将ContainerEvent类事件调度给Container状态机
ApplicationEventDispatcher:ApplicationEvent类事件调度给Application状态机

0x03 ContainerExecutor

启动容器是由ContainersLauncher服务完成的,而运行容器是由插拔式组件ContainerExecutor完成的。
提供两种实现:DefaultContainerExecutorLinuxContainerExecutorDefaultContainerExecutor以NM启动者身份去启停容器。LinuxContainerExecutor以应用程序拥有者启停容器,并允许用户通过Cgroups对CPU隔离。

0x04 NodeHealthCheckerService

NodeHealthScriptRunner周期性运行脚本,LocalDirsHandlerService周期性向磁盘写文件,来检查节点健康状况。通过NodeStatusUpdater向RM上报。如果不健康RM会把此NM加入黑名单,当状态变为健康再移除黑名单。被拉黑的NM上正在运行的容器不行被杀死,仍然会正常运行。

0x05 其他组件:

DeletionService

删除文件模块。独立成模块为了减少性能开销。

Security

ApplicaitonACLsManager确保访问NM用户合法,维护一张ACL列表。如在WEB UI为授权用户显示容器日志。
ContainerTokenSecretManager确保请求容器被RM授权过。

WebServer

显示节点所有应用的运行状态、容器列表、节点健康情况和容器产生日志等信息

健康检查

健康检查也可以用于动态升级。利用健康检查脚本机制告诉RM不在分配任务,等NM升级好了再分配。
两种策略判断健康情况:一、自定义Shell,一旦脚本输出ERROR开头的字符串,则认为节点不健康。二、判断磁盘好坏,NM上有周期性检测磁盘模块,如果坏磁盘数达到一定比例则认为不健康。

NodeHealthScriptRunner

周期性执行脚本发现标准输出有以ERROR开头的输出,则通过心跳告诉RM,RM将其拉黑,此后不会分配新容器,老容器继续运行。只要NM活着会一直运行该脚本,当不输出ERROR则通过心跳向RM汇报,移除拉黑。
实践:由于Yarn只对CPU和内存隔离。网络和磁盘IO不隔离。不同任务会互相干扰。健康检查脚本可以缓解此问题。脚本去检查网络、磁盘、文件系统等情况。发现网络拥塞、磁盘空间不足、文件系统故障,可将状态变为不健康。

LocalDirsHandlerService

一旦发现正常比例低于配置值则设为不健康状态。判断磁盘好坏方式是目录具有读、写、执行三权限。判断local-dirs和log-dirs所设置的目录。

分布式缓存

HDFS依赖缓存到节点本地磁盘,以便直接本地读取。
NM第一次启动容器任务会从HDFS同步依赖,并缓存到本地。如果NM不是第一次启动该应用,则从本地缓存读依赖文件。

缓存置换算法

由于磁盘有限,NM采用缓存置换算法定期清理文件。

缓存资源分类

可见性:

Public:所有用户共享此节点资源
Private:用户自己应用共享
Application:同一应用的容器共享

资源类型:

Archive:归档文件。目前支持jar、zip、tar.gz、tgz、tar五种。可自动解压缩,jar可自动放入CLASSPATH中。
File:普通文件,下载不作任何处理。
Pattern:上诉两种混合体。用户可以通过正则指定那些属于Archive文件。

文件上传协议

  1. resource #HDFS上的路径
  2. size #文件大小
  3. timestamp #最后修改时间
  4. type #资源类型
  5. visibility #可见性
  6. pattern #类型为PATTTERN时的正则

资源相同判断逻辑

四个属性resource、timestamp、type、pattern中任何一个属性修改,则下次使用更新缓存。

实现

Public放在${yarn.nodemanager.local-dirs}/filecache目录下,资源权限为755
Private放在${yarn.nodemanager.local-dirs}/usercache/${user}/filecache文件夹下,${user}是应用的提交者。权限为710
Application存放在${yarn.nodemanager.local-dirs}、usercache/${user}/appcache/${appid}/filecache/下。权限为710
容器的工作目录:在${yarn.nodemanager.local-dirs}、usercache/${user}/appcache/${appid}/${containerid}下,在container运行过程中需要用到的jar包等,会通过软连接连接到对应资源。

Public资源通过ResourceLocalizationService的PublicLocalizer维护线程池并行下载。Private和Application资源通过ResourceLocalizationService的LocalizerRunner(每个容器对应一个LocalizerRunner线程)下载。一个容器的所有资源串行下载(后续可能改成并行下载)。ContainerExecutor组件会设置资源目录权限。

过期缓存会被定时删除,时间有yarn.nodemanager.localizer.cache.cleanup-interval-ms(默认10分钟)决定。并确保目录大小小于yarn.nodemananger.localizer.cache.target-size-mb(默认10240,10GB),如果超过该值采用LRU(Least Recently Used)算法清除缓存文件直到大小低于配置阈值。

目录管理

数据目录local-dirs存放依赖和运行产生临时数据。日志目录log-dirs存放容器运行日志。为了提高并发读写性能,可配置多个挂在不同磁盘的目录(逗号隔开)。Yarn会在每个目录创建相同的目录结构,采用轮询策略使用这些目录。

数据目录管理

数据目录轮询方式是将目录轮询分配给每个容器的不同模块。容器输出的中间数据会在application整个都结束时才统一清理,这是为了避免application内的容器间的数据依赖(如reduce依赖map的输出)。

image.png

日志目录管理

注意:log-dirs是容器运行日志。NM参数日志是在${YARN_HOME}/logs下,文件名为yarn-${user}-nodemanager-${host}.log。
轮询三类日志到不同配置目录。stdout(System.out.print打印)、stderr、syslog(log4j打印)。通常只有syslog有内容。
日志文件存在${yarn.nodemanager.log-dirs}/${appid}/${containerid}下。
日志的清理由LogHandler组件的NonAggregatingLogHandler和LogAggregationService两种实现完成。
NonAggregatingLogHandler为定期删除,yarn.nodemanager.log.retain-seconds配置保留时间单位秒默认3小时。
LogAggregationService为日志转存,yarn.log-aggregation-enable配置开启。
默认采用定期删除。image.png

日志上传

应用运行结束所有日志会上传到HDFS的${remoteRootLogDir}/${user}/${suffix}/${appid}目录中。${remoteRootLogDir}是yarn.nmodemanager.remote-app-log-dir指定,默认/tmp/logs。${suffix}是yarn.nmodemanager.remote-app-log-dir-suffix指定,默认logs。一旦上传HDFS本地文件将删除。同一个节点所有日志保存为一个文件,以节点ID命名。为了节约资源,NM允许指定上传三种日志类型:ALL_CONTAINERS、APPLICATION_MASTER_ONLY、AM_AND_FAILED_CONTAINERS_ONLY。默认ALL_CONTAINERS。image.png

文件生命周期

上传HDFS后的日志NM不在管理,由JobHistory负责。yarn.log-aggregation.retain-seconds(即3小时)。查看可以从Web页面,或者命令。

  1. bin/yarn logs -applicationId xxxx
  2. bin/yarn logs -applicationId xx -containerId xxx -nodeAddress host_45454

状态机

https://www.yuque.com/deadwind/notes/rb631t