限制每次执行结构化流式查询时扫描的S3分区

时间:2018-05-11 21:15:07

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

我们目前将一堆Avro文件上传到S3,这些文件按上传时间进行分区,我们希望将它们转换为Parquet并由该事件的customerId重新分区。

我们已经使用火花结构流传输了一个解决方案,它似乎在语义上是正确的。我们的代码有一堆看起来像

的查询
Dataset<Row> sourceStream = sparkSession.readStream()
  .format("com.databricks.spark.avro")
  .load("/avro/input/path");

sourceStream
  .drop("ingestion_hour")
  .withColumn("c_id", new Column("customer_id"))
  .repartition(new Column("c_id"))
  .writeStream()
  .trigger(Trigger.Once())
  .outputMode(OutputMode.Append())
  .format("parquet")
  .option("checkpointLocation", "/checkpoint/path/")
  .partitionBy("c_id")
  .start("/parquet/output/path");

然而,似乎存在一个问题,/avro/input/path前缀下的文件数量不断增加,从而导致每次执行ETL需要更长时间才能列出S3中的文件以便计算新文件。

我尝试将单个流式传输查询拆分为多个流式查询,这些查询每小时消耗一次,例如/avro/input/path/ingestion_hour=yyyy-MM-dd-HH并使用检查点路径/parquet/output/path输出到/checkpoint/path/yyyy-MM-dd-HH的同一个接收器。然后我可以限制作业只执行过去的查询,比如12小时。但是,这项工作似乎不像在多个查询之间共享接收器是正确的事情,因为大多数记录都没有显示在输出中。

我想知道是否有某种方法可以使这种方法起作用,或者是否有不同的方法来限制列出的文件数量?

0 个答案:

没有答案