简体   繁体   English

如何安全地取消订阅 Kafka 中的主题

[英]How to safely unsubscribe to a topic in Kafka

I have a simple java program (dockerized) and deployed in kubernetes (pod) This java program is just a normal java project that listens and consumes to a specific topic.我有一个简单的 java 程序 (dockerized) 并部署在 kubernetes (pod) 这个 java 程序只是一个普通的 java 项目,它监听和消费特定主题。 eg.例如。 SAMPLE-SAFE-TOPIC样本安全主题

I have to unsubscribe to this topic safely, meaning no data will be lost even I deleted this pod (java consumer).我必须安全地取消订阅这个主题,这意味着即使我删除了这个 pod (java 消费者)也不会丢失任何数据。

This is the code that I saw from searching:这是我从搜索中看到的代码:

 public static void unsubscribeSafelyFromKafka() {  

  logger.debug("Safely unsubscribe to topic..");

  if (myKakfaConsumer != null) {
        myKafkaConsumer.unsubscribe();
        myKafkaConsumer.close();
     }
}

I need to run this via command line wherein the Java program has already an existing static main method.我需要通过命令行运行它,其中 Java 程序已经有一个现有的静态 main 方法。

My questions are:我的问题是:

  1. Is the code above guarantees no records will be lost?上面的代码是否保证不会丢失任何记录?
  2. How can I trigger the code above via command line when there is already an existing static main()当已经存在静态 main() 时,如何通过命令行触发上面的代码

Note: I am running the java project via command line.注意:我通过命令行运行 java 项目。 Eg java -jar MyKafkaConsumer.jar as this is the requirement.例如 java -jar MyKafkaConsumer.jar 因为这是要求。

Please help请帮忙

If I understand question 1 right you are concerned that after unsubscribing via one thread triggered by a console command there is a risk that the polling consumer is processing a batch of records that might be lost if the pod is killed?如果我对问题 1 的理解正确,您会担心在通过控制台命令触发的一个线程取消订阅后,是否存在轮询使用者正在处理一批记录的风险,如果 pod 被杀死,这些记录可能会丢失?

If you have other pods that are consuming as part of the same consumer group, or if this or any pod subscribes again with the same group ID then the last committed offset will ensure that no records are lost (though some could be processed more than once) as that is where the consumer that takes over will start from.如果您有其他 pod 作为同一消费者组的一部分正在消费,或者如果此 pod 或任何 pod 再次使用相同的组 ID 订阅,那么最后提交的偏移量将确保没有记录丢失(尽管有些可能会被处理多次) 因为这是接管的消费者将从哪里开始。

If you use auto-commit that is safest as each commit happens in a subsequent poll so you cannot possibly commit records that haven't been processed (as long as you don't spawn additional threads to do the processing).如果您使用最安全的自动提交,因为每次提交都发生在后续轮询中,因此您不可能提交尚未处理的记录(只要您不产生其他线程来进行处理)。 Manual commit leaves it to you to decide when records have been dealt with and hence when it is safe to commit.手动提交让您自己决定何时处理记录以及何时可以安全提交。

However, calling close after unsubscribe is a good idea and should ensure a clean completion of the current polled batch and commit of the final offsets as long as that all happens within a timeout period.但是,在取消订阅后调用 close 是一个好主意,并且只要所有这些都发生在超时期限内,就应该确保当前轮询批次的干净完成和最终偏移量的提交。

Re question 2, if you need to manually unsubscribe then I think you'd need JMX or expose an API or similar to call a method on the running JVM.关于问题 2,如果您需要手动取消订阅,那么我认为您需要 JMX 或公开 API 或类似的东西来调用正在运行的 JVM 上的方法。 However if you are just trying to ensure safe shutdown when the pod terminates, you could unsubscribe in a shutdown hook, or just not worry, given the safety provided by offset commits.但是,如果您只是想确保在 pod 终止时安全关闭,您可以在关闭挂钩中取消订阅,或者不用担心,因为偏移提交提供了安全性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM