java - Kafka 重试配置和性能影响
问题描述
我正在考虑将重试机制设置为在这里和那里覆盖网络信号,我认为如果重试机制覆盖几分钟,比如 2-5 分钟,就足以解决轻微的网络问题。根据this question的答案和文档,要设置的配置主要是retries
,max.in.flight.requests.per.connection
(建议kafka设置为1)retry.backoff.ms
和delivery.timeout.ms
。
我担心设置max.in.flight.requests.per.connection
为 1 可能会对性能产生影响?有人有这方面的经验吗?kafka 生产者与代理集群的默认连接数是多少?我在网上找不到关于它的东西。
解决方案
max.in.flight.requests.per.connection
事实上,这是关于生产者性能的最重要的配置参数之一,特别是生产者的吞吐量和延迟。此参数控制生产者在阻塞之前将在单个连接上发送到某个分区的未确认请求的最大数量。
换句话说,它将发送一个请求,并且在收到确认之前,它不会向代理发送另一个请求(针对该分区)。作为建议,如果您不要求对所有消息进行排序,请不要将此参数设置为 1。
关于retries
及其与此参数的链接:
在不将 max.in.flight.requests.per.connection 设置为 1 的情况下允许重试可能会改变记录的顺序,因为如果将两个批次发送到单个分区,并且第一个批次失败并被重试,但第二个批次成功,那么记录在第二批中可能首先出现。
所以真的不建议被 kafka 设置为 1;当您需要订购交货时,建议使用。如果您不需要发生这种情况,请不要设置max.in.flight.requests.per.connection
为1,因为您的生产者的吞吐量确实会降低。
在简历中:仅当您正在寻找事件的有序交付时才将其设置为 1 。
在这个测试max.in.flight.requests
中,当从 1 增加到 2时,吞吐量和延迟显示出可观的改进。
acks
这里还涉及另一个参数,以及您已经引用的参数,即acks
集合的数量。
例如,acks = 0
将使两者retries
和max.in.flight
参数完全无关,因为生产者不会等待来自任何代理的任何确认,并且会假设每个请求都是成功的。就像 UDP 发件人一样。
与acks=0
:
1- retries
不生效,因为无法知道是否发生任何故障。
2- max.in.flight
不生效,因为没有任何可能的未确认请求。
例如,将 acks 设置为高于 0acks=2
也会对性能产生直接影响,因为要成功识别请求,必须acks
从集群接收到 2。这意味着,例如,仅指定 1 个正在运行的请求的生产者的阻塞时间通常会增加,因为它必须等待 2 个 ack 消息才能解除阻塞并能够为该分区发送下一个请求。
Idempotence
关于您的问题还有另一个概念,即幂等生产者。这可能是实现性能和效率之间平衡的最佳选择。
假设您设置了一些retries
以保证消息正确到达。代理收到消息,当它向您发送消息时ack
,网络错误使您的生产者无法接收它。如果设置了重试,则将再次发送相同的消息,在代理中producer
创建重复的消息。
Kafka 0.11.0 包括对生产者中的幂等和事务功能的支持。幂等传递确保消息 在单个生产者的生命周期内仅传递一次到特定主题分区
幂等生产者具有唯一的生产者 ID,并为每条消息使用序列 ID,这允许代理确保它在每个分区的基础上提交无重复的有序消息。
这个幂等生产者,在较新版本的 Kafka 客户端中,默认使用 5 max.in.flight.requests
,从“旧”方式提高性能以确保交付顺序。这也是幂等生产者的最大值(从 1 到 5 是飞行中请求的有效范围),如果您需要有序、安全的管道,同时保持生产者的高性能,这是恢复的最佳选择。
幂等生产者导致了仅一次语义概念,在链接中进行了更深入的解释。
Design for max.in.flight > 1 with idempotence enabled
在 resume中,您应该判断用例的要求是什么。像这样的问题:
是否需要订购交货?
重复消息是否可以接受?
您是否重视吞吐量和延迟到可以接受某些消息丢失/无序的程度?
幂等生产者是否可以满足您的要求,以便在性能和消息排序/成功请求保证之间取得平衡?
本次演示或多或少地恢复了这些配置对生产者端的影响,值得一看。
推荐阅读
- postgresql - SELECT FROM 查询与 PostGIS 几何不工作
- c - 我们可以称之为 Switch() 的“案例”吗?代码中其他任何地方的语句 [C 编程语言]
- python - Colab 无法(如何)从 git 导入文件
- java - Java:创建对象数组
- android - 矢量绘图在某些设备上未正确显示
- python - Traceback(最近一次调用最后一次):ValueError:对已关闭文件的 I/O 操作
- javascript - YouTube 数据 API Node.js quickstart.js 问题
- apache-flink - 我们可以调用 SourceFunction#collectWithTimestamp 摄取时间中指定的时间戳吗
- apache-spark - 如何在结构化流中正确使用 foreachBatch.batchDF.unpersist()?(继续出错)
- php - Jquery Datepicker - 如何从另一个函数中的选择选项中获取日期数组,并将其传递给 datepicker 中的 disabledate