向Kafka生成消息时,您会遇到两种错误:可重试错误和不可重试错误。处理它们时应如何区分它们?
我想异步生成记录,将callback object
收到不可重试的异常的记录保存在另一个主题(或HBase)中,并让生产者为我处理所有接收到不可重试的异常的记录(最大数量)尝试,当它最终达到时,便成为最早的尝试之一。
我的问题是:尽管有callback object
,生产者仍将自行处理可检索的异常吗?
因为在Interface Callback中说:
可恢复的异常(瞬态,可以通过增加#来覆盖 .retries)
可能是这样的代码吗?
producer.send(record, callback)
def callback: Callback = new Callback {
override def onCompletion(recordMetadata: RecordMetadata, e: Exception): Unit = {
if(null != e) {
if (e == RecordTooLargeException || e == UnknownServerException || ..) {
log.error("Winter is comming")
writeDiscardRecordsToSomewhereElse
} else {
log.warn("It's no that cold") //it's retriable. The producer will keep trying by itself?
}
} else {
log.debug("It's summer. Everything is fine")
}
}
}
Kafka版本:0.10.0
任何光将不胜感激! :)
答案 0 :(得分:0)
正如卡夫卡圣经(又名Kafka-The Definitive Guide)所说:
缺点是,尽管commitSync()会重试提交,直到它提交为止 成功或遇到不可修复的失败,commitAsync() 不会重试。
原因:
它不会重试,直到commitAsync()收到一个 来自服务器的响应,可能是后来的提交 已经成功了。
想象一下,我们发送了一个提交偏移量的请求 2000。存在临时通信问题,因此代理永远不会收到请求,因此永远不会响应。同时,我们处理了 另一个批次并成功提交偏移量3000。 sync()现在重试先前失败的提交,它可能会成功执行 在偏移3000已经处理后提交偏移2000,并且 承诺。在重新平衡的情况下,这将导致更多 重复。
除此之外,您仍然可以创建一个递增的序列号,每次提交时都可以增加它,并将该数字添加到Callback对象中。重试时间到了,只需检查Acc的当前值是否等于您提供给Callback的数字即可。如果这样做,那是安全的,您可以执行提交。否则,将有一个新的提交,您不应重试此偏移量的提交。
似乎有很多麻烦,那是因为如果您正在考虑这一点,则应该更改策略。