YARN——Container启动上下文

本文详细介绍了YARN中ApplicationMaster和container的启动上下文,包括资源、环境变量和启动参数的传递方式。当客户端提交任务到ResourceManager,上下文信息通过NodeManager传递,NodeManager根据上下文构造启动脚本并启动任务。具体处理过程包括变量替换、添加额外环境变量、资源文件处理和启动参数写入。文章以MapReduce任务为例展示了启动脚本的生成过程,并探讨了资源文件的本地化和管理问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【概述】


在YARN中,不管是ApplicationMaster(后面均简称AM),还是一般的container(例如MR中的map任务、reduce任务;Spark中的executor或者Flink中的TaskManager),都有各自的启动上下文(ContainerLaunchContext)。

上下文中包含了任务启动所依赖的资源(包括jar,资源文件等)、环境变量、启动参数等。

那么启动上下文具体是怎样传递给yarn,yarn是否进行了处理,进行了怎样的处理,本文就来聊聊这些相关内容。

【参数传递流程】


对于AM而言,客户端向ResourceManager(RM)提交任务,提交的任务请求中就包含了上下文信息,RM收到请求后进行调度,最后通过NodeManager(NM)的心跳告知NM启动AM,在这个过程中将上下文信息传递给NM,NM拿到上下文信息构造出AM的启动脚本,并启动AM。

对于一般container,是由AM直接向NM发起请求,要求启动container,请求中同样携带了上下文信息。同样,NM根据这个上下文信息,构造出对应的启动脚本,然后启动container。

【示例】


先来看个实际的例子:

上图是客户端向RM提交MR任务时的抓包情况,结合protobuf文件与源码中上下文的数据结构,可以整理出,上下文信息包含了四个资源文件:

  • job.split、

  • job.xml、

  • job.splitmetainfo

  • job.jar

上下文中还指定了环境变量HADOOP_CLASSPATH,以及AM的启动参数。

该任务最终对应的启动脚本是这样的:

#!/bin/bash


export HADOOP_CONF_DIR="/opt/service/hadoop/etc/hadoop"
export MAX_APP_ATTEMPTS="2"
export JAVA_HOME="/usr/java/jdk1.8.0_231"
export APP_SUBMIT_TIME_ENV="1617090350054"
export NM_HOST="172.19.6.60"
export HADOOP_CLASSPATH="$PWD:job.jar/job.jar:job.jar/classes/:job.jar/lib/*:$PWD/*:/opt/service/hadoop/contrib/capacity-scheduler/*.jar"
export LD_LIBRARY_PATH="$PWD:$HADOOP_COMMON_HOME/lib/native"
export HADOOP_HDFS_HOME="/opt/service/hadoop-2.8.5"
export LOGNAME="root"
export JVM_PID="$$"
export PWD="/opt/data/hadoop/yarn/nodemanager/local/user/cache/root/appcache/application_1616833932566_0011/container_e21_1616833932566_0011_01_000001"
export HADOOP_COMMON_HOME="opt/service/hadoop"
export LOCAL_DIRS="/opt/data/hadoop/yarn/nodemanager/local/usercache/root/appcache/application_1616833932566_0011"
export APPLICATION_WEB_PROXY_BASE="/proxy/application_1616833932566_0011"
export SHELL="/bin/bash"
export NM_HTTP_PORT="8042"
export LOG_DIRS="/opt/data/hadoop/yarn/nodemanager/log/application_1616833932566_0011/container_e21_1616833932566_0011_01_000001"
export NM_AUX_SERVICE_mapreduce_shuffle="AAAAO+gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
export NM_PORT="9100"
export USER="root"
export HADOOP_YARN_HOME="/opt/service/hadoop-2.8.5"
export CLASSPATH="$PWD:$HADOOP_CONF_DIR:$HADOOP_COMMON_HOME/share/hadoop/common/*:$HADOOP_COMMON_HOME/share/hadoop/common/lib/*:$HADOOP_HDFS_HOME/share/hadoop/hdfs/*:$HADOOP_HDFS_HOME/share/hadoop/hdfs/lib/*:$HADOOP_YARN_HOME/share/hadoop/yarn/*:$HADOOP_YARN_HOME/share/hadoop/yarn/lib/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*:job.jar/job.jar:job.jar/classes/:job.jar/lib/*:$PWD/*"
export HADOOP_TOKEN_FILE_LOCATION="/opt/data/hadoop/yarn/nodemanager/local/usercache/root/appcache/application_1616833932566_0011/container_e21_1616833932566_0011_01_000001/container_tokens"
export HOME="/home/"
export CONTAINER_ID="container_e21_1616833932566_0011_01_000001"
export MALLOC_ARENA_MAX="4"
ln -sf "/opt/data/hadoop/yarn/nodemanager/local/usercache/root/appcache/application_1616833932566_0011/filecache/11/job.jar" "job.jar"
hadoop_shell_errorcode=$?
if [ $hadoop_shell_errorcode -ne 0 ]
then
    exit $hadoop_shell_errorcode
fi
mkdir -p jobSubmitDir
hadoop_shell_errorcode=$?
if [ $hadoop_shell_errorcode -ne 0 ]
then
    exit $hadoop_shell_errorcode
fi
ln -sf "/opt/data/hadoop/yarn/nodemanager/local/usercache/root/appcache/application_1616833932566_0011/filecache/12/job.split" "jobSubmitDir/job.split"
hadoop_shell_errorcode=$?
if [ $hadoop_shell_errorcode -ne 0 ]
then
    exit $hadoop_shell_errorcode
fi
ln -sf "/opt/data/hadoop/yarn/nodemanager/local/usercache/root/appcache/application_1616833932566_0011/filecache/13/job.xml" "job.xml"
hadoop_shell_errorcode=$?
if [ $hadoop_shell_errorcode -ne 0 ]
then
    exit $hadoop_shell_errorcode
fi
mkdir -p jobSubmitDir
hadoop_shell_errorcode=$?
if [ $hadoop_shell_errorcode -ne 0 ]
then
    exit $hadoop_shell_errorcode
fi
ln -sf "/opt/data/hadoop/yarn/nodemanager/local/usercache/root/appcache/application_1616833932566_0011/filecache/10/job.splitmetainfo" "jobSubmitDir/job.splitmetainfo"
hadoop_shell_errorcode=$?
if [ $hadoop_shell_errorcode -ne 0 ]
then
    exit $hadoop_shell_errorcode
fi
exec /bin/bash -c "$JAVA_HOME/bin/java -Djava.io.tmpdir=$PWD/tmp -Dlog4j.configuration=container-log4j.properties -Dyarn.app.container.log.dir=/opt/data/hadoop/yarn/nodemanager/log/application_1616833932566_0011/container_e21_1616833932566_0011_01_000001 -Dyarn.app.container.log.filesize=0 -Dhadoop.root.logger=INFO,CLA -Dhadoop.root.logfile=syslog -Xmx1024m org.apache.hadoop.mapreduce.v2.app.MRAppMaster 1>/opt/data/hadoop/yarn/nodemanager/log/application_1616833932566_0011/container_e21_1616833932566_0011_01_000001/stdout 2>/opt/data/hadoop/yarn/nodemanager/log/application_1616833932566_0011/container_e21_1616833932566_0011_01_000001/stderr "
hadoop_shell_errorcode=$?
if [ $hadoop_shell_errorcode -ne 0 ]
then
    exit $hadoop_shell_errorcode
fi

【上下文的处理】


从上面的实例中可以看到,客户端请求中的上下文仅描述了资源名称与位置,环境变量以及具体启动的参数,那么NM是如何处理这个上下文并最终构造出启动脚本的呢?

通过源码分析,NM在启动任务前,根据上下文信息,转换成具体的启动脚本,具体处理包括:

  • 创建脚本构造器

    根据不同的平台(windows或unix)创建不同的脚本构建器,然后写入脚本的头,例如unix中的"#!/bin/bash"。

  • 变量替换

    变量替换指的是对上下文中环境变量、启动参数中的变量进行替换,主要替换的是日志的路径。

    可以仔细观察下上图中客户端传递的上下文启动参数中,标准输出和错误输出指向的路径均为<LOG_DIR>。

    这其实是代码中的一个公共常量。

    MR、Flink、Spark任务提交时,均使用了该值作为日志的输出路径。

    在NM中则根据实际配置文件中配置的路径进行替换。

  • 添加额外的环境变量

    除了客户端上下文中所携带的环境变量外,NM还会额外添加一些环境变量,包括

    CONTAINER_ID

    NM_PORT

    NM_HOST

    NM_HTTP_PORT

    LOCAL_DIRS

    LOG_DIRS

    USER

    LOGNAME

    HOME

    PWD

    HADOOP_CONF_DIR

    JVM_PID

    另外,对于AM而言,RM在处理的过程中还额外添加了三个环境变量:

    APPLICATION_WEB_PROXY_BASE

    MAX_APP_ATTEMPTS

    APP_SUBMIT_TIME_ENV

  • 环境变量写入脚本

    所有环境变量都存放在一个map中,然后遍历该map表,逐个转换成下面的格式:

    export KEY="VALUE"
    
  • 资源文件的处理

    环境变量写完后,对所有资源文件按需创建目录,并建立软链接。

    注意:每个资源文件建立软链接后,均会进行错误检查。

  • 写入启动参数

    最后将上下文中的启动参数写入脚本中。

整个流程下来就构成了完整的启动脚本,随后真正启动对应进程。

【总结】


本文简单总结了container启动上下文包括哪些内容,如何传递的,yarn是如何进行处理的。

这里留个引子,前面示例中客户端提交任务的上下文中,其资源文件指定的是HDFS的路径,那么这些资源文件最终是如何下载的本地的?

从NM构造的启动脚本中看到对这些资源文件都做了软链接,那么软链接的路径又是如何决定的?

这些资源文件能否给其他任务使用?资源文件什么时候删除。。。

所有这些问题都涉及NM中的资源管理,下篇文章,我们就来分析下NM中的资源管理。

<think>好的,我需要回答用户关于如何启动Yarn以及解决Yarn启动问题的询问。首先,我得回忆一下Yarn的基本启动方法,尤其是在Hadoop集群中的常见步骤。Yarn作为资源管理器,通常通过Hadoop的脚本启动。记得启动前需要确保HDFS已经运行,所以可能需要先启动HDFS,再启动Yarn。 接下来,用户可能遇到的问题包括配置错误、端口冲突、资源不足或依赖问题。比如,配置文件路径错误是常见的,像yarn-site.xml或core-site.xml中的配置不正确会导致启动失败。需要检查这些文件的路径和内容是否正确。另外,防火墙设置也可能拦截端口,比如ResourceManager的8088端口或NodeManager的随机端口,需要开放相应端口或关闭防火墙测试。 然后,资源不足的情况,比如内存或CPU分配不当,可能导致节点无法启动。需要调整yarn-site.xml中的参数,如yarn.nodemanager.resource.memory-mb和yarn.scheduler.maximum-allocation-mb。还有类加载错误,尤其是提交应用到Flink on Yarn时,版本不兼容可能导致类找不到,需要确认Flink和Hadoop版本的匹配。 另外,用户提到的引用中有关于Fair Scheduler和Capacity Scheduler的负载均衡配置,这可能和任务分配不均有关,但用户的问题主要是启动失败,所以这部分可能暂时不需要深入,除非启动问题与调度器配置错误有关。 然后,我需要整理常见问题及解决方案,如配置错误、端口冲突、资源不足、依赖缺失、权限问题等,每个问题给出具体的解决步骤,比如检查配置文件、使用netstat查看端口、调整内存参数、安装node-sass前切换淘宝源等。还要注意引用对应的参考资料,比如引用5提到的Fair Scheduler配置,引用4提到的类加载问题。 最后,生成相关问题,可能涉及性能调优、日志分析、安全配置、调度器选择等,这些需要基于常见问题扩展,确保问题相关且有参考价值。需要确保所有LaTeX格式正确,行内公式用$包裹,独立公式用$$,但当前内容可能涉及较少数学公式,可能需要检查是否有必要添加。同时保持回答结构清晰,分步骤说明,并正确标注引用来源。</think>### Yarn启动方法与常见问题解决方案 #### 一、Yarn启动方法 1. **基于Hadoop集群启动** YarnHadoop的资源管理器,启动前需确保HDFS已正常运行: ```bash # 启动HDFS $HADOOP_HOME/sbin/start-dfs.sh # 启动Yarn $HADOOP_HOME/sbin/start-yarn.sh ``` 验证启动状态: - 访问ResourceManager的Web UI:`http://<ResourceManager_IP>:8088` - 检查节点状态:`yarn node -list` 2. **单机模式启动(调试用)** 使用以下命令直接启动Yarn服务: ```bash yarn resourcemanager # 启动ResourceManager yarn nodemanager # 启动NodeManager ``` --- #### 二、Yarn启动失败常见问题及解决方案 1. **配置错误** - **问题描述** 配置文件(如`yarn-site.xml`、`core-site.xml`)路径或参数错误,导致服务无法初始化[^2]。 - **解决方案** - 检查配置文件的XML语法:`xmllint --format yarn-site.xml` - 验证关键参数(如资源分配): ```xml <!-- yarn-site.xml示例 --> <property> <name>yarn.nodemanager.resource.memory-mb</name> <value>8192</value> <!-- 根据物理内存调整 --> </property> ``` 2. **端口冲突或防火墙拦截** - **问题描述** ResourceManager默认使用8088端口,若端口被占用或防火墙拦截,导致服务无法启动[^3]。 - **解决方案** - 检查端口占用:`netstat -tuln | grep 8088` - 开放防火墙:`sudo ufw allow 8088/tcp` - 修改默认端口(在`yarn-site.xml`中设置`yarn.resourcemanager.webapp.address`) 3. **资源不足** - **问题描述** 内存或CPU分配超出物理资源限制,导致NodeManager启动失败。 - **解决方案** - 调整`yarn.nodemanager.resource.memory-mb`和`yarn.nodemanager.resource.cpu-vcores`参数 - 确保总分配值不超过节点物理资源(如内存需预留部分给系统进程) 4. **依赖缺失或版本冲突** - **问题描述** 如`node-sass`安装卡死,或Flink on Yarn因版本不兼容报类加载错误[^1][^4]。 - **解决方案** - 切换镜像源加速依赖下载: ```bash yarn config set registry https://registry.npm.taobao.org ``` - 确保Flink与Hadoop版本匹配(如Flink 1.14需Hadoop 3.x) 5. **权限问题** - **问题描述** 用户未获权限执行Yarn操作,或HDFS目录权限不足。 - **解决方案** - 创建专用HDFS目录并授权: ```bash hdfs dfs -mkdir /user/yarn hdfs dfs -chown yarn:supergroup /user/yarn ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值