首页 > 解决方案 > 我应该在 Akka 流中的 Kafka 源之后添加缓冲区吗

问题描述

根据这篇博文

如果流的源轮询外部实体以获取新消息并且下游处理不统一,则插入缓冲区对于实现良好的吞吐量至关重要。例如,在来自 Reactive Streams Kafka 库的 Kafka Consumer 之后插入的大缓冲区可以在某些情况下将性能提高一个数量级。否则,源可能无法以足够快的速度轮询 Kafka,以保持下游的工作饱和,源在背压和轮询 Kafka 之间摇摆不定。

alpakka kafka 连接器的文档没有提到这一点,所以我想知道在这种情况下使用缓冲区是否有意义。同样的事情也适用于 Kafka 接收器(我之前应该添加一个缓冲区)吗?

标签: apache-kafkaakkabufferakka-stream

解决方案


...我想知道在这种情况下使用缓冲区是否有意义

考虑您引用的博客文章中的以下部分:

...下游处理不均匀....

文章该部分的要点之一是说明用户定义的缓冲区和异步边界可能对流产生的类似影响。没有缓冲区或异步边界的默认行为是启用operator fusion,它在单个 actor 中运行流。这实质上意味着,对于每条消费的 Kafka 消息,该消息必须通过流的整个管道,从源到接收器,然后下一条消息通过管道。换句话说,在前一条消息完成处理m2之前,一条消息不会通过管道。m1

如果 Kafka 连接器源下游发生的处理是“不统一的”(即,它可能需要不同的时间:有时处理发生得很快,有时需要一段时间),那么引入缓冲区或异步边界可以提高整体吞吐量。这是因为缓冲区或异步边界可以允许源继续消费 Kafka 消息,即使下游处理恰好需要很长时间。也就是说,如果m1需要很长时间来处理,源可以使用消息m2m3等等(直到缓冲区已满),而无需等待m1完成。正如 Colin Breck 在他的帖子中所说:

缓冲区通过解耦阶段来提高性能,平均而言,允许上游或下游继续处理元素,即使其中一个正忙于处理相对昂贵的工作负载。

这种潜在的性能提升并不适用于所有情况。再次引用布雷克:

与上一节讨论的方法类似,async需要注意的是,不加选择地插入缓冲区并不会提高性能,只会消耗额外的资源。如果相邻的工作负载相对一致,则添加缓冲区不会改变性能,因为流的整体性能将仅由最慢的处理阶段主导。

确定在您的情况下使用缓冲区(即.buffer)是否有意义的一种明显方法是尝试一下。您也可以尝试添加一个异步边界(即.async)。比较以下三种方法——(1) 没有缓冲的默认融合行为,(2).buffer和 (3) .async——看看哪一种产生了最好的性能。


推荐阅读