HDFS文件接收器输出作为另一个流的文件流输入-竞争条件?

时间:2018-07-13 09:21:00

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

我正在使用结构化流评估15节点Spark集群中的特定数据流。我在应用程序中定义了2个流查询:

  • SQ1-从Kakfa读取数据->进程->写入HDFS文件接收器(路径-hdfs:// tmp / output)
  • SQ2-从HDFS(与上面相同的路径)中读取数据作为文件流->进一步处理->使用ForeachWriter写入外部数据库

两个查询均设置为每15秒触发一次。

我的问题-我是在这里查看竞争状况吗,SQ2从HDFS提取部分写入的文件(由SQ1生成)?一个更笼统的问题是,HDFS的文件接收器编写器是否“原子”的?我试图在Spark中浏览流式源代码,但是并没有取得太大进展。

1 个答案:

答案 0 :(得分:0)

此方法的主要问题是Spark结构化流中的所有文件接收器(例如HDFS)只能在追加模式下运行。此外,创建文件后即会立即读取文件。任何后续的写入更新或完成将被忽略。

根据“学习Spark-第二版”一书中的有关读取文件的内容

“每个文件必须以原子方式显示在目录中-也就是说,整个文件必须立即可供读取,一旦可用,就无法更新或修改该文件。”

“ [写入文件] ...它仅支持附加模式,因为虽然很容易在输出目录中写入新文件(即,将数据附加到目录中),但是很难修改现有数据文件(如更新和完整模式所预期的那样。”

要解决您面临的问题,可以将流式查询更改为:

  • SQ1-从Kafka读取数据->进程->进一步处理->缓存/持久存储
  • SQ2a将缓存的DataFrame写入HDFS文件接收器(路径-hdfs:// tmp / output)
  • SQ2b使用ForeachWriter将缓存的DataFrame写入外部数据库 ->使用ForeachWriter写入外部数据库