繁体   English   中英

spark结构化流和批处理的相同接收器?

[英]Same sink for spark structured streaming and batch?

我有两个火花工作。 一个是批处理作业,另一个是结构化流式作业。 两者都写入同一个文件接收器。 两者具有相同的架构。 但是,在从该接收器读取数据时,Spark 仅读取流作业创建的文件并跳过批处理作业创建的文件。 我可以在文件接收器文件夹中看到一个目录 _spark_metadata。 当我删除此文件夹时,火花开始读取所有文件。 但是,这并不总是可能的,因为在下一个微批处理 spark 将在那里创建另一个 _spark_metadata 文件夹。 如何在 spark 中读取此接收器中的所有文件。

我有相同和以下的问题。 我使用下面的代码来解决这些问题,它对我有用。 可能下面的代码会帮助你。

Issue-1 :如果您从流目录读取数据,Spark 将抛出以下异常。

java.IO.FileNotFoundException ... The underlying files may have been updated. You can explicitly invalidate the cache in Spark by running 'REFRESH TABLE tableName' command in SQL or by recreating the Dataset/DataFrame involved.

Issue - 2 :如果 hdfs 目录为空,Spark 将抛出以下异常并尝试从该目录加载数据。 我在加载数据时没有传递架构,如果您传递架构,您可能不会遇到这个问题。

org.apache.spark.sql.AnalysisException: Unable to infer schema for JSON. It must be specified manually.

而不是在加载数据时指向 HDFS 目录并获取所需的文件路径并将这些路径传递给火花load方法。

在下面的代码中,您可以更好地控制要读取和忽略的文件。

import org.apache.hadoop.fs.{FileSystem, Path, RemoteIterator}

implicit def convertToScalaIterator[T](remoteIterator: RemoteIterator[T]): Iterator[T] = {
    case class wrapper(remoteIterator: RemoteIterator[T]) extends Iterator[T] {
      override def hasNext: Boolean = remoteIterator.hasNext
      override def next(): T = remoteIterator.next()
    }
    wrapper(remoteIterator)
}

def listFiles(spark: SparkSession,path: String) = {
    FileSystem.get(spark.sparkContext.hadoopConfiguration)    
    .listFiles(new Path(path),true)
    .toList.map(_.getPath)
    .filter(!_.toString.contains("_spark_metadata"))
    .map(_.toString)
}

val files = listFiles(spark,kafka.read.hdfsLocation)
require(files.isEmpty, s"Files are not available to process data.")
spark
    .read
    .format(read.format)
    .options(read.options)
    .load(files:_*)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM