如何在至少有N行的情况下执行流处理?

时间:2017-11-27 09:54:35

标签: apache-spark apache-kafka apache-spark-sql spark-structured-streaming

我在Kafka消费者处有以下spark SQL / Streaming查询,如何在批量大小达到特定大小N时指定fetch应该是有条件的,否则消费者应该在处理之前缓冲元素,所以每当我想要执行我的逻辑,保证我有一个大小为N的精确Dataset<VideoEventData>。当前代码:

Dataset<VideoEventData> ds = spark
      .readStream()
      .format("kafka")
      .option("kafka.bootstrap.servers", prop.getProperty("kafka.bootstrap.servers"))
      .option("subscribe", prop.getProperty("kafka.topic"))
      .option("kafka.max.partition.fetch.bytes", prop.getProperty("kafka.max.partition.fetch.bytes"))
      .option("kafka.max.poll.records", prop.getProperty("kafka.max.poll.records"))
      .load()
      .selectExpr("CAST(value AS STRING) as message")
      .select(functions.from_json(functions.col("message"),schema).as("json"))
      .select("json.*")
      .as(Encoders.bean(VideoEventData.class));

2 个答案:

答案 0 :(得分:1)

  

我想执行我的逻辑,我知道我有一个大小为N的精确数据集

开箱即用的Spark Structured Streaming(以及一般的Spark)是不可能的。

您有以下选择:

  1. 使用Kafka Consumer属性配置位于kafka源后面的Kafka使用者。

  2. 自行缓冲行,作为任意有状态聚合的一部分。

  3. 编写自定义源来处理缓冲本身。

  4. 对于2.我可以使用KeyValueGroupedDataset.flatMapGroupsWithState,其状态会积累在&#34; chunks&#34;最终会给你N的大小。

    For 3.实施一个自定义有状态流媒体Source,以getOffset只能提供补偿的方式实施getBatchgetOffset当至少有N行时。

    免责声明:我以前从未做过任何一种解决方案,但看起来很可行。

答案 1 :(得分:0)

您可以通过配置Kafka消费者本身来实现。将fetch.min.bytes设置为您想要的最小值。这将告诉Kafka等到它有足够的数据。

有一个相关的设置fetch.max.wait.ms,可以控制卡夫卡最多等待的时间。默认情况下,此值为500毫秒。您可以阅读更多here