AWS EMR引导动作安装的Python库遭默认库覆盖,脚本状态持续Pending
问题分析与解决方案
核心原因:引导动作与实例配置的死循环
你遇到的问题本质是引导动作本身属于实例配置流程的一部分,在引导脚本未执行完成前,实例的nodeProvisionCheckinRecord状态会一直处于PENDING。而你的脚本一直在等待该状态变为SUCCESSFUL,这就形成了死循环——脚本不退出,配置流程无法完成;配置流程不完成,状态永远不会更新为SUCCESSFUL。
AWS知识库的旧脚本可能适配的是早期EMR版本,当时引导动作的执行时机与现在不同,导致现在的版本中逻辑失效。
修复方案
方案1:替换状态检查逻辑,等待实例初始化完成的可靠标志
放弃监听job-flow-state.txt中的状态,改为等待实例初始化完成的实际信号(比如核心服务启动、关键文件存在)。以下是修改后的脚本:
#!/bin/bash # 等待Hadoop核心服务启动(适配EMR 5.x/6.x) while ! systemctl is-active --quiet hadoop-hdfs-namenode 2>/dev/null; do sleep 10 done # 额外等待10秒确保所有依赖服务稳定 sleep 10 echo "Running post-provision dependency installation" # 卸载默认库并安装指定版本(示例) sudo python3 -m pip uninstall -y numpy==1.16.5 sudo python3 -m pip install --upgrade numpy==1.20.1
如果是Core/Task节点,可将hadoop-hdfs-namenode替换为hadoop-hdfs-datanode,或者用更通用的检查:
# 等待YARN命令可用 while [ ! -f /yarn/bin/yarn ]; do sleep 10 done
方案2:改用EMR Step安装依赖(更推荐)
将依赖安装逻辑放在EMR的自定义Step中,Step会在集群完全启动后执行,完全避免初始化流程的冲突:
- 编写安装脚本(上传至S3存储桶,比如
s3://your-bucket/install-deps.sh):
#!/bin/bash sudo python3 -m pip uninstall -y numpy==1.16.5 sudo python3 -m pip install --upgrade numpy==1.20.1
- 创建EMR集群时,添加一个"自定义JAR"类型的Step,选择"运行命令",输入:
bash s3://your-bucket/install-deps.sh
- 设置Step在所有节点上运行(选择"All nodes")。
方案3:修复原脚本的sed语法(不推荐,仍可能有死循环风险)
原脚本的sed命令存在语法冗余(多余的/[}]/a命令),导致无法正确提取状态。简化后的状态提取命令:
NODEPROVISIONSTATE=$(grep -A 20 "nodeProvisionCheckinRecord" /emr/instance-controller/lib/info/job-flow-state.txt | grep "status:" | awk '{print $2}')
但即使修复sed,死循环问题仍存在,因此不建议采用这种方式。
额外注意事项
- 优先使用
--user参数安装依赖到用户目录,避免修改系统库:python3 -m pip install --user numpy==1.20.1 - 对于EMR 6.x+版本,推荐使用Conda环境隔离依赖,避免与系统库冲突。
内容的提问来源于stack exchange,提问作者rahuls_
相关产品推荐
相关产品推荐

