scala - 如何在 Scala 中同时使用 gcs-connector 和 google-cloud-storage

标签 scala apache-spark google-cloud-storage

我正在尝试列出存储桶中的所有对象,然后将其中的部分或全部读取为 CSV。我现在已经花了两天时间,试图同时做两个,但如果我使用谷歌的图书馆,我一次只能让一个工作。

我认为问题在于谷歌自己的库之间不兼容,但我并不完全确定。首先,我认为我应该展示我是如何做每件事的。

这就是我读取单个文件的方式。在我的 Scala 版本中,您可以使用 gs://带有 spark.read.csv 的网址:

val jsonKeyFile = "my-local-keyfile.json"
ss.sparkContext.hadoopConfiguration.set("google.cloud.auth.service.account.json.keyfile", jsonKeyFile)

spark.read
  .option("header", "true")
  .option("sep", ",")
  .option("inferSchema", "false")
  .option("mode", "FAILFAST")
  .csv(gcsFile)

这实际上是单独工作的,我从中得到了一个有效的 DF。然后当我尝试添加谷歌的存储库时出现问题:

libraryDependencies += "com.google.cloud" % "google-cloud-storage" % "1.70.0"

如果我尝试再次运行相同的代码,我会从 .csv 调用中得到这个坏男孩:
Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties
19/05/14 16:38:00 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

An exception or error caused a run to abort: Class com.google.common.base.Suppliers$SupplierOfInstance does not implement the requested interface java.util.function.Supplier 
java.lang.IncompatibleClassChangeError: Class com.google.common.base.Suppliers$SupplierOfInstance does not implement the requested interface java.util.function.Supplier
    at com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystemBase.getGcsFs(GoogleHadoopFileSystemBase.java:1488)
    at com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystemBase.configure(GoogleHadoopFileSystemBase.java:1659)
    at com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystemBase.initialize(GoogleHadoopFileSystemBase.java:683)
    at com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystemBase.initialize(GoogleHadoopFileSystemBase.java:646)
    at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:3303)
    at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:124)
    ...(lots more trace, probably irrelevant)

然后,你可能会问,你为什么不直接使用这个库呢?嗯...这是列出存储桶中对象的代码:

StorageOptions
  .newBuilder()
  .setCredentials(ServiceAccountCredentials.fromStream(
    File(jsonKeyFile).inputStream()))
  .build()
  .getService
  .list(bucket)
  .getValues
  .asScala
  .map(irrelevant)
  .toSeq
  .toDF("irrelevant")

而且我还没有找到一种在没有指定库的情况下轻松做到这一点的方法。

最佳答案

我发现了导致问题的原因。 Guava:27.1-android 在某些时候是某个库的依赖项,我不知道它是哪个以及如何到达那里,但它正在使用中。在这个版本的 Guava 中,Supplier 接口(interface)没有扩展 Java Supplier 接口(interface)。

我通过将 Guava 27.1-jre 添加到我的依赖项来修复它。我不知道顺序是否重要,但我现在不敢碰任何东西。这是我放置它的地方:

libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test"
libraryDependencies += "org.apache.spark" %% "spark-sql" % "2.4.1" % "provided"
libraryDependencies += "com.google.guava" % "guava" % "27.1-jre"
libraryDependencies += "com.google.cloud" % "google-cloud-storage" % "1.70.0"
//BQ samples as of 27feb2019 use hadoop2 but hadoop3 seems to work fine and are recommended elsewhere
libraryDependencies += "com.google.cloud.bigdataoss" % "bigquery-connector" % "hadoop3-0.13.16" % "provided"
libraryDependencies += "com.google.cloud.bigdataoss" % "gcs-connector" % "hadoop3-1.9.16" % "provided"

希望这可以防止其他一些可怜的灵魂在这个 bs 上花费 2 天。

关于scala - 如何在 Scala 中同时使用 gcs-connector 和 google-cloud-storage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56133193/

相关文章:

regex - 已弃用 - Scala 正则表达式模式匹配

java - 将数据集写入组合 xls 文件

google-cloud-platform - 将图像数据 (tfrecords) 从 GCS 提供给模型的最佳方式是什么?

scala - org.apache.spark.SparkException : Job aborted due to stage failure: Task 98 in stage 11. 0失败4次

scala - Twitter future 与猫箭

scala - 为什么 Scala 无法实例化伴随对象?

apache-spark - 如何对 Spark MatrixFactorizationModel 中的所有用户产品组合进行评分?

python - 我无法使用 Python 将名称中包含空格的文件上传到 Google Cloud Storage。我究竟做错了什么?

scala - 在多项目 Build.sbt 中分解 libraryDependencies

python - Spark 执行时间与 AWS EMR 上的节点数量