当Kafka Server停机几分钟时,Kafka Producer正在失去信息

时间:2018-01-22 13:11:46

标签: apache-kafka kafka-producer-api

我编写的Java程序正在使用Kafka库,我听说Kafka Producer有内部缓冲区来保存消息,以便以后可以重试。所以我用重试属性创建了Idempotent Kafka Producer。

    props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, System.getenv(KafkaConstants.KAFKA_URL));
    props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
    props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
            "org.apache.kafka.common.serialization.StringSerializer");
    props.put("linger.ms", 1000);
    props.put("acks", "all");
    props.put("request.timeout.ms",60000);
    props.put("retries",3);
    props.put("retry.backoff.ms",1000);
    props.put("max.in.flight.requests.per.connection",1);
    props.put("enable.idempotence",true);

在运行程序之前,我保留了Kafka Server(只有一个代理)。当我运行该程序时,我得到一个例外“60000ms后无法更新元数据”。但是,当我重新启动Kafka服务器时,它应该将数据推送到kafka主题,因为我已经给出了重试属性。

请在这方面提供帮助。

谢谢, Priyam Saluja

2 个答案:

答案 0 :(得分:0)

Kafka客户端发送的第一个请求之一是获取元数据。请记住,客户端尝试连接到引导服务器列表中的代理,但它可能想要发送的主题可能不是其中之一。例如,考虑拥有3个代理B01,B02,B03和引导服务器只是B01,但是生产者希望将消息发送到以B02作为领导者的主题分区:生产者需要第一个元数据请求来获取此信息然后打开与B02的连接以发送消息。我猜测重试机制在此步骤之后发挥作用,因为生产者内部的批处理利用已知分区及其所在位置。在获取元数据步骤正确完成并且生产者知道分区负责人是谁之后,您应该检查重试工作是否关闭服务器。

答案 1 :(得分:0)

我发现了问题,每当Kafka Producer尝试生成消息时,首先要更新元数据(以检查Kafka集群中的领导者和分区)。如果它无法获取信息,那么它将抛出错误“无法在60000毫秒后更新元数据”。

第二部分是重试,如果消息由于暂时性错误而失败,Kafka Producer将尝试。