在GCP Dataproc上使用Spark,我成功地将整个RDD写入GCS,如下所示:
rdd.saveAsTextFile(s"gs://$path")
产品是同一路径中每个分区的文件。
如何为每个分区写文件(具有基于分区信息的唯一路径)
下面是一个发明的无法正常运行的代码示例
rdd.mapPartitionsWithIndex(
(i, partition) =>{
partition.write(path = s"gs://partition_$i", data = partition_specific_data)
}
)
当我从Mac上的分区中调用以下函数并将其写入本地磁盘时,在Dataproc上,我收到一个错误,无法将gs识别为有效路径。
def writeLocally(filePath: String, data: Array[Byte], errorMessage: String): Unit = {
println("Juicy Platform")
val path = new Path(filePath)
var ofos: Option[FSDataOutputStream] = null
try {
println(s"\nTrying to write to $filePath\n")
val conf = new Configuration()
conf.set("fs.gs.impl", "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem")
conf.set("fs.AbstractFileSystem.gs.impl", "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFS")
// conf.addResource(new Path("/home/hadoop/conf/core-site.xml"))
println(conf.toString)
val fs = FileSystem.get(conf)
val fos = fs.create(path)
ofos = Option(fos)
fos.write(data)
println(s"\nWrote to $filePath\n")
}
catch {
case e: Exception =>
logError(errorMessage, s"Exception occurred writing to GCS:\n${ExceptionUtils.getStackTrace(e)}")
}
finally {
ofos match {
case Some(i) => i.close()
case _ =>
}
}
}
这是错误:
java.lang.IllegalArgumentException: Wrong FS: gs://path/myFile.json, expected: hdfs://cluster-95cf-m
答案 0 :(得分:2)
如果在Dataproc集群上运行,则无需在配置中显式填充“ fs.gs.impl”; new Configuration()
应该已经包含必要的映射。
这里的主要问题是val fs = FileSystem.get(conf)
正在使用conf的fs.defaultFS
属性;它无法知道您是否要获取特定于HDFS或GCS的文件系统实例。通常,在Hadoop和Spark中,FileSystem
实例从根本上绑定到单个URL scheme
。您需要为每个不同的方案(例如hdfs://
或gs://
或s3://
提取特定于方案的实例。
解决问题的最简单方法是始终使用Path.getFileSystem(Configuration)而不是FileSystem.get(Configuration)
。并确保您的path
完全符合该计划的要求:
...
val path = "gs://bucket/foo/data"
val fs = path.getFileSystem(conf)
val fos = fs.create(path)
ofos = Option(fos)
fos.write(data)
...