在我的场景中,我将CSV文件连续上传到HDFS。
一旦上传新文件,我就想用Spark SQL处理新文件(例如,计算文件中字段的最大值,将文件转换为parquet
)。即我在每个输入文件和转换/处理的输出文件之间有一对一的映射。
我正在评估Spark Streaming以侦听HDFS目录,然后使用Spark处理“流式文件”。
但是,为了处理整个文件,我需要知道“文件流”何时完成。我想将转换应用于整个文件,以保持文件之间的端到端一对一映射。
如何转换整个文件而不是微批?
据我所知,Spark Streaming只能将转换应用于批次(DStreams
映射到RDDs
),而不能同时应用于整个文件(当有限流完成时)。
这是对的吗?如果是这样,我应该为我的方案考虑哪种替代方案?
答案 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