You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark YARN集群模式下间歇性资源下载失败问题排查求助

问题根因

报错核心信息是Resource ... is not publicly accessible and as such cannot be part of the public cache,具体原因如下:
Spark以YARN集群模式提交时,会将脚本依赖的本地文件(比如file_event.json)上传到HDFS的sparkStaging临时目录。YARN的NodeManager会尝试将这些资源下载到公共本地缓存供后续容器复用,但如果上传到HDFS的文件没有开放其他用户可读权限(即o+r权限),NodeManager就无法读取该文件,导致AM容器启动失败。

间歇性出现的诱因可能是:

  • 文件上传时权限设置未稳定生效(比如HDFS权限同步延迟)
  • 部分NodeManager节点的权限校验逻辑触发时机不一致
解决方法

1. 提交时指定文件分发权限

在spark-submit命令中添加配置,强制设置上传文件的权限:

spark-submit \
  --master yarn \
  --deploy-mode cluster \
  --conf spark.yarn.dist.files.permissions=664 \
  # 其他参数和脚本路径

664表示文件所有者和组可读可写,其他用户可读,满足公共缓存的权限要求;若文件需要执行权限,可改为775。

2. 修复sparkStaging目录权限

如果临时目录本身权限不足,手动递归修改目录及文件权限:

hdfs dfs -chmod -R o+r /user/user01/sparkStaging

该命令会给sparkStaging下所有文件和子目录添加其他用户的读权限。

3. 禁用NodeManager公共缓存(备选方案)

如果不需要复用缓存,可直接关闭公共缓存功能,绕开权限校验:

spark-submit \
  --master yarn \
  --deploy-mode cluster \
  --conf spark.yarn.use.node-manager-local-cache=false \
  # 其他参数和脚本路径

注意:此方案会导致每个容器都重新下载资源,可能降低集群性能,仅在权限问题无法快速修复时临时使用。

调试文件上传失败的方法

1. 开启Spark调试日志

提交时增加日志级别配置,查看文件上传的详细过程:

spark-submit \
  --master yarn \
  --deploy-mode cluster \
  --conf spark.driver.logLevel=DEBUG \
  --verbose \
  # 其他参数和脚本路径

日志中会包含文件上传到HDFS的状态、路径、权限设置等信息,可直接定位是否上传失败或权限异常。

2. 直接检查HDFS临时目录

提交任务后,立即查看对应sparkStaging目录下的文件状态:

# 替换为实际的application ID
hdfs dfs -ls hdfs://hdfserver/user/user01/sparkStaging/application_1704800602555_46873

确认文件是否存在,以及权限是否包含o+r(比如权限列显示-rw-rw-r--即符合要求)。

3. 查看YARN应用日志

通过YARN命令拉取应用的完整日志,定位文件下载失败的具体细节:

# 替换为实际的application ID
yarn logs -applicationId application_1704800602555_46873

日志中会包含AM容器启动时的资源下载报错,可进一步确认权限问题或HDFS访问异常。

4. 在脚本中添加文件校验逻辑

如果是脚本中手动处理文件上传,可在PySpark脚本开头添加HDFS文件检查代码:

import subprocess

# 检查HDFS文件是否存在及权限
def check_hdfs_file(hdfs_path):
    # 执行ls命令获取文件信息
    result = subprocess.run(["hdfs", "dfs", "-ls", hdfs_path], capture_output=True, text=True)
    if result.returncode != 0:
        print(f"文件不存在: {hdfs_path}")
        return False
    # 解析权限列(输出的第二列)
    permissions = result.stdout.split()[0]
    if 'r' not in permissions[-1]:
        print(f"文件无其他用户读权限: {permissions}")
        return False
    print(f"文件状态正常: {hdfs_path}")
    return True

# 替换为实际的文件路径
check_hdfs_file("hdfs://hdfserver/user/user01/sparkStaging/application_1704800602555_46873/file_event.json")

内容的提问来源于stack exchange,提问作者LeoMan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 23:15:32