我在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));
答案 0 :(得分:1)
我想执行我的逻辑,我知道我有一个大小为N的精确数据集
开箱即用的Spark Structured Streaming(以及一般的Spark)是不可能的。
您有以下选择:
使用Kafka Consumer属性配置位于kafka源后面的Kafka使用者。
自行缓冲行,作为任意有状态聚合的一部分。
编写自定义源来处理缓冲本身。
对于2.我可以使用KeyValueGroupedDataset.flatMapGroupsWithState,其状态会积累在&#34; chunks&#34;最终会给你N的大小。
For 3.实施一个自定义有状态流媒体Source,以getOffset
只能提供补偿的方式实施getBatch
和getOffset
当至少有N
行时。
免责声明:我以前从未做过任何一种解决方案,但看起来很可行。
答案 1 :(得分:0)
您可以通过配置Kafka消费者本身来实现。将fetch.min.bytes
设置为您想要的最小值。这将告诉Kafka等到它有足够的数据。
有一个相关的设置fetch.max.wait.ms
,可以控制卡夫卡最多等待的时间。默认情况下,此值为500毫秒。您可以阅读更多here。