【SparkStreaming实时项目】精确一次消费问题

92 阅读2分钟

问题定义:指Kafka消息一定会被处理且只会被处理一次。不多不少就一次处理。如果达不到精确一次消费,可能会达到另外两种情况(至少一次消费和最多一次消费)。

  • 至少一次消费(数据重复问题):先写出数据再提交offset,结果数据写出成功,offset提交失败。
  • 最多一次消费(漏消费问题):先提交offset再写出数据,结果offset提交成功,数据写出失败。 解决策略:手动的将偏移量存储到redis中,每次消费数据需要使用存储的offset进行消费,每次消费数据后,要将本次消费的offset存储到redis中。下游幂等处理用于数据去重。

offset存储结构:kafka中offset的维护结构:groupId+topic+partition=>offset。Redis中offset的维护结构:采用hash数据结构,key:groupId+topic, field:partition, value:offset

引申问题:kafka缓冲区问题。

问题原因:确实是先发了数据,再写入offset,但是数据发送后并不一定就代表写入成功了。

问题定义:Kafka的生产者将消息进行发送时,会先将消息发送到缓冲区中,待缓冲区写满或者到达指定的时间,才会真正的将缓冲区的数据写到 Broker。 假设消息发送到缓冲区中还未写到Broker,我们认为数据已经成功写给了Kafka,接下来会手动的提交 offset, 如果 offset 提交成功,但此刻 Kafka 集群突然出现故障。 缓冲区的数据会丢失,最终导致的问题就是数据没有成功写到 Kafka ,而offset 已经提交,此部分的数据就会被漏掉。

解决策略:在手动提交offset 之前,强制将缓冲区的数据flush到broker。