首页 > 解决方案 > 尝试在 Kerberos 环境中使用 Spark on Yarn 以 sftp 模式写入 csv 文件

问题描述

我正在尝试将 Dataframe 写入 csv 文件并将此 csv 文件放入远程机器中。Spark 作业在 Yarn 上运行到 Kerberos 集群中。

下面,当作业尝试在远程机器上写入 csv 文件时出现的错误:

诊断:用户类抛出异常:org.apache.hadoop.security.AccessControlException:权限被拒绝:user=dev,access=WRITE,inode="/data/9/yarn/local/usercache/dev/appcache/application_1532962490515_15862/container_e05_1532962490515_15862_02_000001/ tmp/spark_sftp_connection_temp178/_temporary/0":hdfs:hdfs:drwxr-xr-x

为了编写此 csv 文件,我在以 sftp 模式编写此文件的方法中使用以下参数:

def writeToSFTP(df: DataFrame, path: String) = {
    df.write
      .format("com.springml.spark.sftp")
      .option("host", "hostname.test.fr")
      .option("username", "test_hostname")
      .option("password", "toto")
      .option("fileType", "csv")
      .option("delimiter", ",")
      .save(path)
  }

我正在使用链接中描述的 Spark SFTP 连接器库:https ://github.com/springml/spark-sftp

用于启动作业的脚本是:

#!/bin/bash

kinit -kt /home/spark/dev.keytab dev@CLUSTER.HELP.FR

spark-submit --class fr.edf.dsp.launcher.LauncherInsertion \
--master yarn-cluster \
--num-executors 1 \
--driver-memory 5g \
--executor-memory 5g \
--queue dev \
--files /home/spark/dev.keytab#user.keytab,\
/etc/krb5.conf#krb5.conf,\
/home/spark/jar/dev-application-SNAPSHOT.conf#app.conf \
--conf "spark.executor.extraJavaOptions=-Dapp.config.path=./app.conf -Djava.security.auth.login.config=./jaas.conf" \
--conf "spark.driver.extraJavaOptions=-Dapp.config.path=./app.conf -Djava.security.auth.login.config=./jaas.conf" \
/home/spark/jar/dev-SNAPSHOT.jar > /home/spark/out.log 2>&1&

csv 文件不会写入 HDFS。构建数据框后,我尝试将其发送到机器。我怀疑 sftp Spark 连接器存在 Kerberos 问题:纱线无法联系远程机器...

欢迎任何帮助,谢谢。

标签: scalaapache-sparksftphadoop-yarnkerberos

解决方案


添加您具有写入权限的临时位置,不要担心清理它,因为最终在 ftp 完成后这些文件将被删除,

def writeToSFTP(df: DataFrame, path: String) = {
        df.write
          .format("com.springml.spark.sftp")
          .option("host", "hostname.test.fr")
          .option("username", "test_hostname")
          .option("password", "toto")
          .option("fileType", "csv")
          **.option("hdfsTempLocation","/user/currentuser/")**
          .option("delimiter", ",")
          .save(path)
      }

推荐阅读