单节点Kafka开发环境读取失败报NotEnoughReplicasException
我之前在单节点开发环境里也碰到过一模一样的问题——哪怕是空主题,Akka Persistence在初始化阶段会触发对内部主题(比如你报错里提到的__transaction_state)的元数据检查或者写入操作,这时候Kafka会验证同步副本的数量,但它的默认配置和单节点只有1个副本的场景不匹配,所以就抛出了*NotEnoughReplicasException*。
下面是具体的解决步骤:
1. 修改Kafka核心配置
打开Kafka的server.properties配置文件,调整以下两个参数适配单节点环境:
- 设置
min.insync.replicas=1:这个参数规定了生产者要求的最少同步副本数,单节点只有1个副本,所以必须设为1,这样只要当前唯一的副本处于同步状态就满足条件。 - 设置
default.replication.factor=1:这是创建新主题时的默认副本数,单节点环境下只能设为1,避免创建主题时出现副本分配失败的问题。
修改完成后,一定要重启Kafka服务让配置生效。
2. 修复已存在的Akka内部主题
Akka Persistence可能已经自动创建了相关的内部主题,这些主题大概率还是用了默认的副本配置,需要手动修改它们的副本分配:
kafka-topics.sh --alter --topic __transaction_state --bootstrap-server localhost:9092 --replica-assignment 0
这里的0是你的Kafka Broker ID,根据自己的实际环境调整即可。如果还有其他Akka相关的内部主题,也需要执行同样的命令修改。
3. 调整Akka Persistence的Kafka生产者配置
Akka Persistence Kafka的生产者默认可能设置了acks=all(要求所有同步副本确认写入),配合上面的min.insync.replicas=1是可以正常工作的,但也可以直接把acks设为1来简化配置,在你的Akka配置文件(比如application.conf)里添加:
akka.persistence.kafka.producer { acks = 1 }
这样生产者只需要收到当前唯一的Broker的确认就会完成写入,避免不必要的副本数检查。
验证修复效果
重启Kafka和你的Akka应用后,再尝试读取消息,*NotEnoughReplicasException*应该就不会再出现了。单节点开发环境不需要考虑副本冗余,这些配置调整完全能满足需求。
内容的提问来源于stack exchange,提问作者Marty Pitt

