如何在写作最终完成后处理HDFS目录中的新文件?

时间:2017-06-05 19:05:58

标签: apache-spark hadoop hdfs spark-structured-streaming

在我的场景中,我将CSV文件连续上传到HDFS。

一旦上传新文件,我就想用Spark SQL处理新文件(例如,计算文件中字段的最大值,将文件转换为parquet)。即我在每个输入文件和转换/处理的输出文件之间有一对一的映射。

我正在评估Spark Streaming以侦听HDFS目录,然后使用Spark处理“流式文件”。

但是,为了处理整个文件,我需要知道“文件流”何时完成。我想将转换应用于整个文件,以保持文件之间的端到端一对一映射。

如何转换整个文件而不是微批?

据我所知,Spark Streaming只能将转换应用于批次(DStreams映射到RDDs),而不能同时应用于整个文件(当有限流完成时)。

这是对的吗?如果是这样,我应该为我的方案考虑哪种替代方案?

2 个答案:

答案 0 :(得分:2)

我可能在第一次尝试时误解了你的问题......

  

据我所知,Spark Streaming只能将转换应用于批处理(DStreams映射到RDD),而不能同时应用于整个文件(当有限流完成时)。

     

这是对的吗?

没有。这是正确。

Spark Streaming会在Spark Streaming的批处理间隔时间内写入HDFS时立即对整个文件应用转换。

Spark Streaming将获取文件的当前内容并开始处理它。

  

一旦上传新文件,我需要使用Spark / SparkSQL

处理新文件

几乎几乎不可能使用Spark,因为它的架构需要花费一些时间才能上传"和Spark处理它。

您应该考虑使用全新且有光泽的Structured Streaming或(很快过时)Spark Streaming

两个解决方案都支持查看新文件的目录,并在上传新文件后触发Spark作业(这正是您的用例)。

引用结构化流媒体' Input Sources

  

在Spark 2.0中,有一些内置源。

     
      
  • 文件来源 - 将目录中写入的文件作为数据流读取。支持的文件格式为text,csv,json,parquet。有关更新的列表,请参阅DataStreamReader接口的文档,以及每种文件格式支持的选项。请注意,文件必须原子放置在给定目录中,在大多数文件系统中,可以通过文件移动操作来实现。
  •   

另请参阅Spark Streaming' Basic Sources

  

除了套接字之外,StreamingContext API还提供了从文件创建DStream作为输入源的方法。

     

文件流:对于从与HDFS API兼容的任何文件系统(即HDFS,S3,NFS等)上的文件读取数据,可以创建DStream:

streamingContext.fileStream[KeyClass, ValueClass, InputFormatClass](dataDirectory)
     

Spark Streaming将监视目录dataDirectory并处理在该目录中创建的任何文件(不支持在嵌套目录中编写的文件)。

但有一点需要注意:

  

我需要知道"文件流"完成。

不要用Spark做这件事。

再次引用Spark Streaming' Basic Sources

  
      
  • 必须通过原子移动或将数据重命名为数据目录,在dataDirectory中创建文件。

  •   
  • 移动后,不得更改文件。因此,如果连续追加文件,则不会读取新数据。

  •   

结束...你应该将文件移动到Spark在文件完成并且准备好使用Spark进行处理时监视的目录。这超出了Spark的范围。

答案 1 :(得分:0)

您可以使用DFSInotifyEventInputStream来监视Hadoop目录,然后在创建文件时以编程方式执行Spark作业。

看这篇文章: HDFS file watcher