我对Kafka和流媒体还不是很陌生。我有一个要求,比如每次运行kafka生产者和消费者时,我都应该获得生产者产生的唯一消息。
下面是生产者和消费者的基本代码
制作人
val props = new Properties()
props.put("bootstrap.servers", "localhost:9092")
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer")
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer")
val producer = new KafkaProducer[String, String](props)
val record = new ProducerRecord[String, String]("test", "key", jsonstring)
producer.send(record)
producer.close()
消费者
val props = new Properties()
props.put("bootstrap.servers", "localhost:9092")
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
props.put("auto.offset.reset", "earliest")
props.put("group.id", "13")
val consumer: KafkaConsumer[String, Map[String,Any]] = new KafkaConsumer[String, Map[String,Any]](props)
consumer.subscribe(util.Arrays.asList("test"))
while (true) {
val record = consumer.poll(1000).asScala
for (data <- record.iterator){
println(data.value())
}
我正在使用的输入Json是以下
{
“ id”:1,
“名称”:“ foo”
}
现在我面临的问题是每次运行程序时我都会得到重复的值。例如,如果我两次运行代码,则消费者输出看起来像这样
{
“ id”:1,
“名称”:“ foo”
}
{
“ id”:1,
“名称”:“ foo”
}
我想要输出,就像我运行程序一样,生产者处理的唯一消息应该被消耗并打印。
我尝试了一些操作,例如将消费者属性更改为偏移量为最新
props.put("auto.offset.reset", "latest")
我也尝试了以下提到的方法,但对我没有用 How can I get the LATEST offset of a kafka topic?
请问您有其他建议吗?
答案 0 :(得分:2)
消费者从主题分区按顺序读取消息。 如果调用poll(),它将返回写入Kafka的记录,而我们组中的消费者尚未读取这些记录。 Kafka在每个分区上跟踪其消耗偏移量,以了解在重新启动的情况下从何处开始消耗。 消费者通过使用提交在主题__consumer_offsets中维护其分区偏移量。
提交是在中更新当前位置的操作 __consumer_offsets。
如果使用者重新启动,为了知道从哪里开始使用,使用者将读取每个分区的最新提交的偏移量,然后从那里继续。
您可以通过两种方式控制提交,或者使用提交间隔将auto commit设置为true
1。启用。auto.committrue
props.put("enable.auto.commit", "true");
props.put("auto.commit.interval.ms", "1000");
2。手动提交
consumer.commitAsync();//asyn commit
or
consumer.commitSync();//sync commit
如果提交失败,它将从最后提交的位置重新开始,如下图所示
自动偏移重置:
消费者第一次重启后,会使用 auto.offset.reset 来确定每个分配分区的初始位置。请注意,首次使用唯一的组ID创建组时,在使用任何消息之前,位置均根据可配置的偏移重置策略 (auto.offset.reset) 进行设置。之后,它将继续逐渐消耗消息,并使用commit(如上所述)跟踪最新的消耗消息
注意:在如果使用者在提交任何偏移量之前崩溃, 那么接管其分区的使用者将使用重置 政策。
所以就您而言
参考:https://www.confluent.io/resources/kafka-the-definitive-guide/