如何最大限度地减少kafka消息传递框架中涉及的延迟?

时间:2013-12-11 13:30:32

标签: apache-kafka

场景:我有一个低容量主题(~150msgs / sec),我们希望有一个 从生产者到消费者的低传播延迟。

我从生产者添加了一个时间戳,并在消费者处读取它以记录传播延迟,默认配置msg(20个字节)显示传播延迟为1960ms到1230ms。因为没有涉及网络延迟,我在同一台机器上尝试了1个生产者和1个简单消费者。

当我尝试将主题刷新间隔调整为20毫秒时,它会下降 到1100ms到980ms。然后我尝试将消费者"fetcher.backoff.ms"调整为10毫秒,它降至1070毫秒 - 860毫秒。

问题:对于msg的20个字节,我希望传播延迟尽可能低,并且~950ms是更高的数字。

问题:我在配置中遗漏了什么? 我欢迎您的评论,延迟至少。

假设:Kafka系统涉及消费者从生产者获取msg之前的磁盘I / O,这与硬盘RPM等有关。

<小时/>的更新: 试图调整日志刷新政策以获得持久性&amp;延迟。
以下是配置:

# The number of messages to accept before forcing a flush of data to disk
log.flush.interval=10
# The maximum amount of time a message can sit in a log before we force a flush
log.default.flush.interval.ms=100
# The interval (in ms) at which logs are checked to see if they need to be 
# flushed to disk.
log.default.flush.scheduler.interval.ms=100

对于20字节的相同消息,延迟为740ms -880ms。

以下陈述在配置本身中已明确说明 有一些重要的权衡:

  1. 耐用性:未发生冲突的数据在发生崩溃时更容易丢失。
  2. 延迟:在刷新消费者数据之前,消费者无法使用数据(这会增加延迟)。
  3. 吞吐量:冲洗通常是最昂贵的操作。
  4. 所以,我相信没有办法达到150毫秒--250毫秒的标记。 (没有硬件升级)。

4 个答案:

答案 0 :(得分:35)

我并不想回答这个问题,但我认为kafka对于这个用例来说是一个糟糕的选择。虽然我认为卡夫卡很棒(我一直是我在工作场所使用它的巨大支持者),但它的优势并不是低延迟。它的优势在于高生产者吞吐量以及对快速和慢速消费者的支持。虽然它确实提供了耐用性和容错性,但像RabbitMQ这样的通用系统也是如此。 RabbitMQ还支持各种不同的客户端,包括node.js.与Kafka相比,当你处理极高的音量(比如150K msg / s)时,rabbitMQ不足。那时,兔子的耐久性方法开始分崩离析,卡夫卡真的脱颖而出。兔子的耐用性和容错能力超过20K msg / s(根据我的经验)。

此外,为了实现如此高的吞吐量,Kafka分批处理消息。虽然批量很小,而且它们的大小是可配置的,但是不能在不产生大量开销的情况下使它们太小。不幸的是,消息批处理使低延迟变得非常困难。虽然您可以调整Kafka中的各种设置,但我不会将Kafka用于任何延迟需要始终小于1-2秒的事情。

另外,如果你要推出一个新的应用程序,Kafka 0.7.2不是一个好的选择。现在所有关注的焦点都是0.8,所以如果你遇到问题我会独自一人,我绝对不会期待任何新功能。有关未来的稳定版本,请点击此处的链接stable Kafka release

同样,我认为Kafka非常适合某些非常具体的用户案例。在我的工作场所,我们同时使用Rabbit和Kafka。虽然这似乎是无偿的,但它们确实是免费的。

答案 1 :(得分:14)

我知道自问这个问题已经过了一年多了,但是我刚刚建立了一个用于开发目的的Kafka集群,而且我们看到从生产者延迟到1毫秒的延迟消费者。我的集群由三个在具有SAN存储的云VM服务(Skytap)上运行的VM节点组成,因此它远非理想的硬件。我使用的是Kafka 0.9.0.0,它足够新,我确信提问者正在使用更旧的东西。我对旧版本没有经验,因此您只需升级即可获得性能提升。

我通过运行我写的Java生产者和消费者来衡量延迟。两者都运行在同一台机器上,位于同一Skytap环境中的第四台VM上(以最大限度地减少网络延迟)。生产者记录当前时间(System.nanoTime()),将该值用作Avro消息中的有效负载,并发送(acks = 1)。使用者配置为以1ms超时连续轮询。当它收到一批消息时,它会记录当前时间(再次System.nanoTime()),然后从发送时间中减去接收时间以计算延迟。当它有100条消息时,它会计算所有100个延迟的平均值并打印到stdout。请注意,在同一台计算机上运行生产者和使用者非常重要,这样延迟计算就不会出现时钟同步问题。

我对制作人生成的消息量起到了相当大的作用。肯定有一个点太多,延迟开始增加,但它大大高于150 /秒。偶尔的消息需要20ms才能完成,但绝大多数都在0.5ms到1.5ms之间。

所有这一切都是通过Kafka 0.9的默认配置完成的。我没有做任何调整。我使用batch-size = 1进行初始测试,但后来发现它在低音量时没有效果,并且在延迟开始增加之前对峰值音量施加了显着限制。

值得注意的是,当我在本地计算机上运行我的生产者和消费者时,完全相同的设置会报告100毫秒范围内的消息延迟 - 如果我只是ping我的Kafka代理,则会报告完全相同的延迟。

我稍后会使用我的制作人和消费者的示例代码以及其他详细信息来编辑此消息,但我想在忘记之前发布一些内容。

答案 2 :(得分:5)

来自here的结果显示,Kafka的现代版本似乎具有非常小的延迟:

2 ms(中位数) 3毫秒(第99百分位数) 14毫秒(99.9百分位数)

答案 3 :(得分:3)

Kafka可以通过使用同步消息传递实现大约毫秒的延迟。使用同步消息传递,生产者不会在发送之前将消息收集到补丁中。

bin/kafka-console-producer.sh --broker-list my_broker_host:9092 --topic test --sync

以下具有相同的效果:

--batch-size 1