java - Kafka 生产者无法发送带有 NOT_LEADER_FOR_PARTITION 异常的消息
问题描述
我们正在使用 spring-cloud-stream-binder-kafka (3.0.3.RELEASE) 向我们的 Kafka 集群 (2.4.1) 发送消息。不时有一个生产者线程收到 NOT_LEADER_FOR_PARTITION 异常,甚至超过重试次数(当前设置为 12,由依赖 spring-retry 激活)。我们限制了重试,因为我们发送了大约 1k msg/s(每个生产者实例)并且担心缓冲区的大小。这样我们会经常丢失消息,这对下游消费者不利,因为我们不能简单地复制传入的流量。
错误信息是
[Producer clientId=producer-5] Received invalid metadata error in produce request on partition topic-21 due to org.apache.kafka.common.errors.NotLeaderForPartitionException: This server is not the leader for that topic-partition.. Going to request metadata update now
[Producer clientId=producer-5] Got error produce response with correlation id 974706 on topic-partition topic-21, retrying (8 attempts left). Error: NOT_LEADER_FOR_PARTITION
[Producer clientId=producer-5] Got error produce response with correlation id 974707 on topic-partition topic-21, retrying (1 attempts left). Error: NOT_LEADER_FOR_PARTITION
有什么已知的方法可以避免这种情况吗?我们应该回到默认的 MAX_INT 重试吗?为什么它一直发送到同一个代理,即使它用 NOT_LEADER_FOR_PARTITION 响应?
欢迎任何提示。
编辑:我们刚刚注意到代理指标 kafka_network_requestmetrics_responsequeuetimems 大约在那个时候上升,但我们看到的最大值约为 2.5s
解决方案
Produce 和 Fetch 请求都发送到分区的领导副本。NotLeaderForPartitionException 当请求被发送到现在不是该分区的领导副本的分区时抛出异常。
客户端将有关每个分区的领导者的信息作为缓存进行维护。缓存管理的完整过程如下图所示。
客户端需要通过设置metadata.max.age.ms
in producer 配置来刷新此信息。此标签的默认值为 300000 毫秒
您可以浏览以下 Apache Kafka 文档。
https://kafka.apache.org/documentation/
请浏览 Sender.java 代码。
您将在发件人代码中找到这两条错误消息。默认值为metadata.max.age.ms
3 秒。我认为你应该减少这个值,然后观察行为。
推荐阅读
- performance - 为什么这个睡眠功能比它应该花费的时间长得多?
- apache-spark - 我们可以从 Spark 的 StructType 为 Hive 创建一个 avsc 文件吗?
- python - 导入 Scipy.io 时出错我正在使用 python 3.5.0 这个错误出来了
- python - 如何使用 Python 替换 PE 文件中的指令?
- reactjs - 按类别和关键字过滤数组
- python - 将 json 文件传递给无服务器 lambda
- sql-server - 为 SQL Server 的 ODBC 驱动程序 17 配置字符集
- c# - Unity HingeJoint 在旋转的自动生成问题中有奇怪的行为?
- php - 用于视频嵌入的 php 的 HTTP 范围请求,用于解决视频中的特定时间
- python - 在 M1 Mac 上安装 TensorFlow