首页 > 解决方案 > 由于文件损坏,Kafka 代理无法重新启动

问题描述

如何从 Kafka 中的损坏文件中恢复?

我们正在运行一个复制因子为 2 且 ISR=1 的三节点集群。最近我们几乎同时发生了所有经纪人都同时失败的情况。这导致了代理 id 102 关闭而其他两个代理恢复的情况。不幸的是,一个主题的至少一个分区有 102 作为领导者,而 isr 也只有 102。这意味着其他代理丢失了该分区中的一些(未知)数据量,因此他们拒绝接收/发送来自该主题的数据。

由于我想恢复我的集群和我的数据,我正在尝试重新启动代理 102。但它在某些未知文件上失败并显示此消息

[2018-07-18 14:44:44,806] ERROR There was an error in one of the threads during logs loading: org.apache.kafka.common.KafkaException: java.io.EOFException: Failed to read `log header` from file channel `sun.nio. ch.FileChannelImpl@375a9d12`. Expected to read 17 bytes, but reached end of file after reading 0 bytes. Started read from position 2147483631. (kafka.log.LogManager) [2018-07-18 14:44:44,809] ERROR [KafkaServer id=102] Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer) org.apache.kafka.common.KafkaException: java.io.EOFException: Failed to read `log header` from file channel `sun.nio.ch.FileChannelImpl@375a9d12`. Expected to read 17 bytes, but reached end of file after reading 0 bytes. Started read from position 2147483631.

不幸的是,这并没有告诉我哪个文件坏了。我曾多次尝试重新启动代理 102,希望它所做的所有重新索引都会以某种方式恢复文件,但没有运气。

我的猜测是,有问题的文件不是来自 102 是死领导的分区。所以我在想

a) 我可以删除 102 上的所有日志文件,以删除 102 不是领导者的分区,当它重新联机时,它会简单地重新同步而不会出现问题?

b)如果我以某种方式找到正确的文件并将其删除,我可以重新启动 102 吗?

c) 有没有办法找出卡夫卡阻塞的文件?

标签: apache-kafka

解决方案


3 节点集群上的 RF=2 和 ISR=1 可能会在分区收缩到 1 个节点时导致状态不一致,并且在此期间更改领导者可能会导致 2 个节点接受写入作为领导者。因此,您可能会获得 2 个历史版本。
为了保证一致性,您可能更喜欢在未来的 RF=3 和 ISR=2 中使用 acks=all。

您可以尝试使用DumpLogSegments实用程序检查102日志文件的有效性并从中转储数据:

bin/kafka-run-class.sh kafka.tools.DumpLogSegments --files 000000000000000xxx.log

解析日志文件并将其内容转储到控制台,这对于调试看似损坏的日志段很有用。

您需要与当前的分区领导代理检查哪些消息不存在,然后重新发布它们。


推荐阅读