如何使用kafka流以大块/批次处理数据?

时间:2018-09-17 11:23:36

标签: java scala apache-spark apache-kafka apache-kafka-streams

在大数据的许多情况下,最好一次处理一个小的记录缓冲区,而不是一次处理一个记录。

自然的例子是调用一些支持批处理以提高效率的外部API。

我们如何在Kafka Streams中做到这一点?在API中找不到我想要的东西。

到目前为止,我有:

var result = client.RequestCustomGrantAsync("custom", "read", customParams).Result;

我想要的是:

builder.stream[String, String]("my-input-topic")
.mapValues(externalApiCall).to("my-output-topic")

在Scala和Akka Streams中,该函数称为builder.stream[String, String]("my-input-topic") .batched(chunkSize = 2000).map(externalBatchedApiCall).to("my-output-topic") grouped。在Spark结构化流媒体中,我们可以进行batch

3 个答案:

答案 0 :(得分:1)

您可以使用队列。像下面这样,

@Component
@Slf4j
public class NormalTopic1StreamProcessor extends AbstractStreamProcessor<String> {

    public NormalTopic1StreamProcessor(KafkaStreamsConfiguration configuration) {
        super(configuration);
    }

    @Override
    Topology buildTopology() {
        KStream<String, String> kStream = streamsBuilder.stream("normalTopic", Consumed.with(Serdes.String(), Serdes.String()));
        // .peek((key, value) -> log.info("message received by stream 0"));
        kStream.process(() -> new AbstractProcessor<String, String>() {
            final LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(100);
            final List<String> collection = new ArrayList<>();

            @Override
            public void init(ProcessorContext context) {
                super.init(context);
                context.schedule(Duration.of(1, ChronoUnit.MINUTES), WALL_CLOCK_TIME, timestamp -> {
                    processQueue();
                    context().commit();
                });
            }

            @Override
            public void process(String key, String value) {
                queue.add(value);
                if (queue.remainingCapacity() == 0) {
                    processQueue();
                }
            }

            public void processQueue() {
                queue.drainTo(collection);
                long count = collection.stream().peek(System.out::println).count();
                if (count > 0) {
                    System.out.println("count is " + count);
                    collection.clear();
                }
            }
        });
        kStream.to("normalTopic1");
        return streamsBuilder.build();
    }

}

答案 1 :(得分:0)

我怀疑,Kafka流目前是否像其他工具一样支持固定大小的窗口。
但是有一些基于时间的窗口,由kafka流支持。 https://kafka.apache.org/11/documentation/streams/developer-guide/dsl-api.html#windowing

您可以定义带有时间的窗口大小,而不是记录数。

  1. 滚动时间窗口
  2. 滑动时间窗口
  3. 会话窗口
  4. 跳跃时间窗口

在您的情况下,可以使用“滚动时间窗口”作为选项。这些是不重叠的固定大小的时间窗口。

  

例如,大小为5000ms的滚动窗口具有可预测的   窗口边界[0; 5000),[5000; 10000),...-和非   [1000; 6000),[6000; 11000),...甚至是“随机”之类的东西   [1452; 6452),[6452; 11452),....

答案 2 :(得分:0)

似乎还不存在。观看此空间https://issues.apache.org/jira/browse/KAFKA-7432