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

Spark独立集群与客户端分属不同用户的权限问题咨询

Spark独立集群跨用户数据持久化权限问题解决方案

问题背景

多台虚拟机以sparkcluster用户运行Spark 3.3独立集群(1主3从),本地Windows机器部署客户端应用连接集群执行数据加载、持久化与转换操作。Spark UI确认连接成功,但持久化数据时抛出IO异常,已排查出原因是集群运行用户与客户端应用运行用户不一致。不想将应用部署到集群机器(违背分布式设计初衷),询问是否可通过配置用户/客户端白名单允许特定客户端执行操作。

异常信息

核心异常

java.io.IOException: Mkdirs failed to create file:/share/data/spark/load/TESTCACHE/f1ab4f4b-0b95-490b-b05c-5154cec2ae6b/fb51846b-c20d-42b3-bb3c-74abf71d10a2.part/_temporary/0/_temporary/attempt_202211301636564407278350514085268_0003_m_000000_34 (exists=false, cwd=file:/app/spark/spark-3.3.0-bin-hadoop3/work/app-20221129201401-0055/0)

完整堆栈

17:33:21.372 [task-result-getter-2] WARN  org.apache.spark.scheduler.TaskSetManager - Lost task 0.0 in stage 2.0 (TID 2) (30.103.216.22 executor 0): java.io.IOException: Mkdirs failed to create file:/share/data/spark/tmp_load/b0ef0b46-da4c-474a-b381-72d79ba38161.part/_temporary/0/_temporary/attempt_202211292233192374251041408678060_0002_m_000000_2 (exists=false, cwd=file:/app/spark/spark-3.3.0-bin-hadoop3/work/app-20221129201401-0055/0)
    at org.apache.hadoop.fs.ChecksumFileSystem.create(ChecksumFileSystem.java:515)
    at org.apache.hadoop.fs.ChecksumFileSystem.create(ChecksumFileSystem.java:500)
    at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:1195)
    at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:1175)
    at org.apache.parquet.hadoop.util.HadoopOutputFile.create(HadoopOutputFile.java:74)
    at org.apache.parquet.hadoop.ParquetFileWriter.<init>(ParquetFileWriter.java:329)
    at org.apache.parquet.hadoop.ParquetOutputFormat.getRecordWriter(ParquetOutputFormat.java:482)
    at org.apache.parquet.hadoop.ParquetOutputFormat.getRecordWriter(ParquetOutputFormat.java:420)
    at org.apache.parquet.hadoop.ParquetOutputFormat.getRecordWriter(ParquetOutputFormat.java:409)
    at org.apache.spark.sql.execution.datasources.parquet.ParquetOutputWriter.<init>(ParquetOutputWriter.scala:36)
    at org.apache.spark.sql.execution.datasources.parquet.ParquetFileFormat$$anon$1.newInstance(ParquetFileFormat.scala:155)
    at org.apache.spark.sql.execution.datasources.SingleDirectoryDataWriter.newOutputWriter(FileFormatDataWriter.scala:161)
    at org.apache.spark.sql.execution.datasources.SingleDirectoryDataWriter.<init>(FileFormatDataWriter.scala:146)
    at org.apache.spark.sql.execution.datasources.FileFormatWriter$.executeTask(FileFormatWriter.scala:317)
    at org.apache.spark.sql.execution.datasources.FileFormatWriter$.$anonfun$write$21(FileFormatWriter.scala:256)
    at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:90)
    at org.apache.spark.scheduler.Task.run(Task.scala:136)
    at org.apache.spark.executor.Executor$TaskRunner.$anonfun$run$3(Executor.scala:548)
    at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1504)
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:551)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)

原因分析

客户端提交任务后,Spark Executor以集群节点的sparkcluster用户运行,但客户端的本地用户与sparkcluster用户权限隔离,导致Executor无法在共享存储目录下创建临时文件/目录,触发权限报错。

解决方案

1. 配置Spark独立集群用户白名单与访问控制

通过Spark内置的ACL(访问控制列表)功能,允许指定客户端用户在集群执行操作:

  • 修改主节点spark-env.sh:
    export SPARK_MASTER_OPTS="-Dspark.authenticate=true -Dspark.authenticate.secret=your-secure-secret -Dspark.acls.enable=true -Dspark.admin.acls=sparkcluster,your-windows-username"
    
    参数说明:
    • spark.authenticate=true:开启集群节点间身份认证
    • spark.authenticate.secret:设置集群共享密钥,所有节点需保持一致
    • spark.acls.enable=true:启用访问控制列表
    • spark.admin.acls:添加拥有管理员权限的用户,包含集群用户sparkcluster和客户端Windows用户名
  • 修改spark-defaults.conf:
    spark.ui.view.acls=sparkcluster,your-windows-username
    spark.modify.acls=sparkcluster,your-windows-username
    
    分别设置UI查看权限和任务修改权限,确保客户端用户可正常操作。
  • 同步配置到所有Worker节点,然后重启Spark集群。

2. 统一任务执行用户身份

客户端提交任务时,强制指定任务以sparkcluster用户身份执行,绕开用户权限差异:

  • 提交命令添加参数:
    spark-submit --conf spark.executorEnv.USER=sparkcluster --conf spark.driverEnv.USER=sparkcluster --class your.main.class your-app.jar
    
  • 代码中设置配置:
    import org.apache.spark.sql.SparkSession
    
    val spark = SparkSession.builder()
      .appName("YourApp")
      .master("spark://master-ip:7077")
      .config("spark.executorEnv.USER", "sparkcluster")
      .config("spark.driverEnv.USER", "sparkcluster")
      .getOrCreate()
    

3. 配置共享存储代理权限(适用于HDFS场景)

如果共享存储使用HDFS,可通过Hadoop代理用户配置,允许sparkcluster代理客户端用户操作:

  • 修改HDFS的hadoop-env.sh:
    export HADOOP_OPTS="-Dhadoop.proxyuser.sparkcluster.hosts=your-windows-client-ip -Dhadoop.proxyuser.sparkcluster.groups=*"
    
    允许sparkcluster用户代理来自指定Windows客户端IP的所有用户组,操作HDFS资源。

4. 调整共享存储目录权限(测试环境临时方案)

直接为共享存储目录添加全局写入权限(不推荐生产环境使用):

chmod -R 777 /share/data/spark/

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 11:01:08