org.apache.kafka.common.errors.UnknownTopicOrPartitionException: This server does not host this topic-partition

1. 问题出现的场景

producer 向一个之前不存在的 topic 写数据

2. UnknownTopicOrPartitionException

字面意思是:topic 或 partition 不存在。
例如:topic 一共有 3 个 partition,p0,p1,p2,而你指定向 p3写数据,则会报这个异常。

3. 问题原因分析

理论上 kafka 会自动创造不存在的 topic。
在这个场景下,producer 向一个新的 topic 写数据,则 kafka 会自动创建这个 topic,并按默认配置给出 partition。

3.1 既然会自动创建 topic,为什么还会报UnknownTopicOrPartitionException?

创建 topic 不是一个瞬间就能完成的动作,kafka 需要将 topic 信息写入 zk,zk 为了保证一致性,需要zk 集群内大部分节点都写成功。因此这个过程是需要耗费一定时间的。(未测试具体耗时)

所以当 kafka 正在创建这个 topic 的时候,producer 就向其发数据,那肯定 topic 是不存在的,因此报这个异常。

4. UnknownTopicOrPartitionException是可重试异常

根据官方 API 文档 解释:

This topic/partition doesn't exist. 
This exception is used in contexts where a topic doesn't seem to exist based on possibly stale metadata. 
This exception is retriable because the topic or partition might subsequently be created.

UnknownTopicOrPartitionException是可重试异常,因为可能 topic 正在创建中,过一会就创建好了。
因此为了保证程序健壮性, producer 需要捕获此异常,并做重试。

4.1 两种重试方案

4.1.1 kafka 客户端配置

spring.kafka.producer.retries = 3

4.1.2 producer 代码捕获异常并手工重试

可以通过实现ListenableFutureCallback<SendResult<String, String>>接口,设置回调。

// 实现这个回调方法,判断 Throwable 类型,手工处理重试
void onFailure(Throwable var1);

参考

  1. Kafka常见错误整理
  2. Kafka运维填坑
Logo

Kafka开源项目指南提供详尽教程,助开发者掌握其架构、配置和使用,实现高效数据流管理和实时处理。它高性能、可扩展,适合日志收集和实时数据处理,通过持久化保障数据安全,是企业大数据生态系统的核心。

更多推荐