【发布时间】:2018-07-04 08:07:55
【问题描述】:
当 Kafka 消费者在属性中具有事务语义时,它无法使用任何消息。但是当我删除该属性或将该属性更新为 read_uncommited 时,它会消耗消息。
以下是我的 Kafka 消费者属性:-
Properties props = new Properties();
props.put("bootstrap.servers", "10.2.200.15:9092");
String consumeGroup = "cg3";
props.put("group.id", consumeGroup);
// Below is a key setting to turn off the auto commit.
props.put("enable.auto.commit", "false");
props.put("heartbeat.interval.ms", "2000");
props.put("session.timeout.ms", "6001");
// Control maximum data on each poll, make sure this value is bigger than the
// maximum // single message size
props.put("max.partition.fetch.bytes", "140");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("isolation.level","read_committed");
Kafka Producer 在其属性中有一个 Transactional id,并且在推送一些消息后,它正在提交整个事务。以下是 Kafka 生产者属性:-
log.info("初始化属性"); 属性 props = new Properties();
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",30000);
props.put("retries", 3);
props.put("retry.backoff.ms", 1000);
props.put("max.in.flight.requests.per.connection", 1); // if its greater than 1, it can change the order or records. Maximum no. of unacknowledge request a client can send.
props.put("enable.idempotence", true);
props.put(ProducerConfig.TRANSACTIONAL_ID_CONFIG,"Transaction8");
sn-p下面负责提交事务:-
public boolean send(ProducerRecordImpl record) {
try {
producer.beginTransaction();
for (int i = 0; i < 10; i++) {
Future<RecordMetadata> futureResult = producer
.send(new ProducerRecord<String, String>(record.getTopic(), record.getPayload()));
/*
* It will wait till the thread execution completes and return true.
*/
//RecordMetadata ack = futureResult.get();
//log.debug("RecordMetadta offset {} and partiton {} ", ack.offset(), ack.partition());
}
producer.commitTransaction();
log.info("Commited");
return true;
我无法理解提交是否没有从生产者端正确发生,这导致 Kafka 消费者无法通过事务语义读取它,或者 Kafka 消费者端仍然存在问题。
任何帮助将不胜感激。
【问题讨论】:
-
我深入研究了这个问题,发现我的最后一个稳定偏移量是 45。但我在消费者端的当前偏移量是 365。所以当我更改我的当前偏移量为 30 ,Kafka Consumer 开始使用具有 read_commited 属性的消息。
-
所以我的问题是为什么当我从那一侧提交事务时,Kafka Producer 没有更新我的最后一个稳定偏移量。
标签: java apache-kafka kafka-consumer-api kafka-producer-api