我使用带有幂等生成器配置的spring-kafka:
这些是我的配置道具:
Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, Joiner.on(",").join(appProps.getBrokers()));
//configure the following three settings for SSL Encryption
props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SSL");
props.put(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG, appProps.getJksLocation());
props.put(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG, appProps.getJksPassword());
props.put(ProducerConfig.ACKS_CONFIG, "all");
props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG,true);
props.put(ProducerConfig.RETRIES_CONFIG, 5);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
我的kafka生产者抛出OutOfOrderSequenceException:
2019-03-06 21:25:47发件人[错误] [生产者clientId = producer-1]代理返回org.apache.kafka.common.errors.OutOfOrderSequenceException:代理收到了主题分区的乱序序列号偏移-1处的topic-1。这表明代理上的数据丢失,应该进行调查。 2019-03-06 21:25:47 TransactionManager [INFO] [Producer clientId = producer-1] ProducerId设置为-1,带epoch -1 2019-03-06 21:25:47 ProducerKafka [ERROR]我们在发送时遇到错误到卡夫卡,请重试这份工作
我不确定为什么会抛出这个异常。我找不到具体的答案。该例外的官方javadoc声明如下:
此异常表示代理从生产者收到了意外的序列号,这意味着数据可能已丢失。如果生成器仅配置为幂等性(即,如果设置了enable.idempotence并且未配置transactional.id),则可以继续使用相同的生成器实例进行发送,但这样做可能会重新排序已发送的记录。对于事务生成器,这是致命错误,您应该关闭生产者。
这是否意味着我需要使用事务生产者来避免这个问题?
KafkaProducer doc陈述了一些使上述陈述含糊不清的内容:https://kafka.apache.org/0110/javadoc/index.html?org/apache/kafka/clients/producer/KafkaProducer.html
要启用幂等性,必须将enable.idempotence配置设置为true。如果设置,重试配置将默认为Integer.MAX_VALUE,max.in.flight.requests.per.connection配置将默认为1,并且acks配置将默认为all。幂等生成器没有API更改,因此不需要修改现有应用程序以利用此功能。
要利用幂等生成器,必须避免应用程序级别重新发送,因为这些不能重复数据删除。因此,如果应用程序启用幂等性,建议保留重试配置未设置,因为它将默认为Integer.MAX_VALUE。此外,如果send(ProducerRecord)即使无限次重试也会返回错误(例如,如果消息在发送之前在缓冲区中到期),则建议关闭生产者并检查上一次生成的消息的内容以确保它没有重复。最后,生产者只能保证在单个会话中发送的消息的幂等性。
上面的陈述清楚地表明,我对幂等生产者所需要的只是使用enable.idempotence
属性。但是,例外情况表明我必须使用transactional.id
属性。
什么是创建幂等异步生成器的正确方法,而不必处理致命的OutOfOrderSequenceException
。
对我来说似乎很清楚;从你的第二个报价...
要利用幂等生成器,必须避免应用程序级别重新发送,因为这些不能重复数据删除。因此,如果应用程序启用幂等性,建议保留重试配置未设置,因为它将默认为Integer.MAX_VALUE。
你有
props.put(ProducerConfig.RETRIES_CONFIG, 5);