微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从 GCP 外部配置从 Apache Spark 到 Google Cloud Platform 的授权和身份验证参数?

如何解决如何从 GCP 外部配置从 Apache Spark 到 Google Cloud Platform 的授权和身份验证参数?

我正在尝试使用 Spark 从 GCP 外部(来自我们的本地集群之一)将数据加载到 GCP。为此,我编写了以下代码

val conf = new SparkConf()
  .set("spark.network.timeout","12000s")
  .set("spark.kryoSerializer.buffer.max","512m")
  .set("temporaryGcsBucket","GCS_BUCKET_LOCATION")
  .setAppName(args(1))
conf.registerKryoClasses(Array(classOf[Loader]))

val spark = SparkSession.builder().
  appName("app").
  master("yarn").
  config( "spark.serializer","org.apache.spark.serializer.KryoSerializer").
  config(conf).
  getorCreate()
spark.conf.set("temporaryGcsBucket","GCS_BUCKET_LOCATION")
spark.conf.set("parentProject","PROJECTID")

spark.sparkContext.hadoopConfiguration.set("google.cloud.auth.service.account.enable","true")
spark.sparkContext.hadoopConfiguration.set("fs.gs.impl","com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem")
spark.sparkContext.hadoopConfiguration.set("google.cloud.auth.service.account.json.keyfile","/path/to/application_default_credentials.json")
spark.sparkContext.hadoopConfiguration.set("fs.gs.auth.client.id","CLIENTID")
spark.sparkContext.hadoopConfiguration.set("fs.gs.auth.client.secret","SECRETKEY")
spark.sparkContext.hadoopConfiguration.set("fs.AbstractFileSystem.gs.impl","com.google.cloud.hadoop.fs.gcs.GoogleHadoopFS")
spark.sparkContext.hadoopConfiguration.set("fs.gs.project.id","PROJECTID")

火花阅读:

val dataframe = spark.read.format("jdbc")
          .option("url",s"jdbc:sqlserver://$server;DatabaseName=$databasename")
          .option("driver","com.microsoft.sqlserver.jdbc.sqlServerDriver")
          .option("user","USERNAME")
          .option("password","PASSWORD")
          .option("dbtable",query)
          .option("partitionColumn",partitionColumn)
          .option("lowerBound",SOMEVALUE)
          .option("upperBound",SOMEVALUE)
          .option("numPartitions",numPartitions)
          .option("fetchsize",10000)
          .load()

Spark 写入:

dataframe.drop(s"${partitionColumn}1")
          .write.format("parquet")
          .option("parentProject","PROJECTNAME")
          .option("path",s"gs://SOME_GCS_PATH/${tablename}")
          .option("credentialsFile","/path/of/jsonfile/on/local/application_default_credentials.json")
          .mode("append")
          .save()

当我运行代码时,我看到以下错误消息:

java.lang.IllegalArgumentException: No valid credential configuration discovered:  [CredentialOptions{serviceAccountEnabled=false,serviceAccountPrivateKeyId=<redacted>,serviceAccountPrivateKey=<redacted>,serviceAccountEmail=hadoop-distp-sa-hadoop@ktest.imp.gserviceaccount.com,serviceAccountKeyFile=null,serviceAccountJsonKeyFile=/path/of/jsonfile/on/local/application_default_credentials.json,nullCredentialEnabled=false,transportType=JAVA_NET,tokenServerUrl=https://oauth2.googleapis.com/token,proxyAddress=null,proxyUsername=null,proxyPassword=null}]

所以我尝试按照 this 页面的 Authentication 部分中存在的 method3 添加配置。

并对我的配置进行了以下更改:

spark.sparkContext.hadoopConfiguration.set("google.cloud.auth.service.account.enable","false")
spark.sparkContext.hadoopConfiguration.set("fs.gs.auth.impersonation.service.account.for.user.<USER_NAME>","username@companyname.com")
spark.sparkContext.hadoopConfiguration.set("fs.gs.auth.impersonation.service.account.for.group.<GROUP_NAME>","gcp_projectid")
spark.sparkContext.hadoopConfiguration.set("fs.gs.auth.impersonation.service.account","service-account-name@.iam.gserviceaccount.com")

但即使按照上述链接更改配置后,我仍然遇到相同的异常。

在这里做错了什么吗? 任何人都可以让我知道如何解决这个问题,以及在 spark 代码中提供哪些强制性配置参数以使用 GCP 进行身份验证? 非常感谢任何帮助。

解决方法

我从您链接的文档中了解到,您使用的是 GCS 连接器,因此我相信:

spark.sparkContext.hadoopConfiguration.set("fs.gs.auth.impersonation.service.account.for.user.<USER_NAME>","username@companyname.com")
spark.sparkContext.hadoopConfiguration.set("fs.gs.auth.impersonation.service.account.for.group.<GROUP_NAME>","gcp_projectid")

实际上应该包含与以下相同的值:

spark.sparkContext.hadoopConfiguration.set("fs.gs.auth.impersonation.service.account","service-account-name@.iam.gserviceaccount.com")

因为 <USER_NAME><GROUP_NAME> 部分应该分别更改为 username@companyname.comgcp_projectid,至少根据 section in the documentation pertaining to these values
鉴于第三个配置的值是帐户,我相信其他配置也应该如此...它们只是在您想指定要使用的特定于用户或特定于组的服务帐户时使用。

话虽如此,我相信这些值会被忽略,因为您的项目中可能没有用户名为“”的用户,而是想了解更多有关此配置的信息:

spark.sparkContext.hadoopConfiguration.set("google.cloud.auth.service.account.enable","false")

正如您在之前的文档中提到的那样,但我似乎在那里找不到它?我可以快速找到所述配置选项的唯一实例是 enabled,也就是说该选项设置为“true”,如果没有此选项,将不会使用服务帐户,考虑到您,这似乎很奇怪已声明要使用哪个服务帐户。或者至少这是我可以从以下描述性文本中收集到的信息:

    Whether to use a service account for GCS authorization.
    Setting this property to `false` will disable use of service accounts for
    authentication.

但是,如果是这种情况,我相信,当此属性设置为 false 而另一个设置为非空值时,它肯定会警告您。

所以,再次阅读您的帖子......我相信您正在用“配置的后续更改”覆盖您放置的原始配置,但这些更改不包括google.cloud.auth.service.account.json.keyfile,我相信是必要的,但我不能肯定地说,因为我在 Google 的文档中发现的唯一内容是使用 Cloud Interconnect,所以我很难说它是否适用于您的情况,因为您'正在从 Spark 执行此操作,并且未使用 DiskCTP

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。