如何保证Kafka消息不丢失?

Kafka是大型架构核心,下面我详解Kafka消息不丢失方案@mikechen

生产端:防止消息发送丢失

生产端是消息的入口,一旦消息未成功发送到 Kafka,就等于“消息消失在路上”。

解决方案:可靠生产 + 幂等机制。

如何保证Kafka消息不丢失?-mikechen

关键配置:

acks=all retries=5 enable.idempotence=true max.in.flight.requests.per.connection=1

参数说明:

acks=all:必须等待所有副本写入成功后,Producer 才认为消息发送成功。

retries:失败后自动重试,避免临时网络问题导致丢失。

enable.idempotence=true:开启幂等性,保证即使重试也不会重复写入。

max.in.flight.requests.per.connection=1:防止乱序导致幂等失效。

效果:

确保生产者“至少成功写入一次”,同时避免重复消息。

 

Broker端:防止消息存储丢失

Broker 是消息的中转与持久化中心,即使 Producer 发成功。

如果 Broker 未正确同步副本或日志损坏,也会丢消息,所以需要,解决Broker端。

解决方案:多副本 + 同步机制 。

如何保证Kafka消息不丢失?-mikechen

关键配置:

replication.factor=3 min.insync.replicas=2 unclean.leader.election.enable=false

参数说明:

replication.factor=3:每条消息存3份副本,提高可靠性。

min.insync.replicas=2:至少两个副本同步成功才算写入成功,结合 acks=all 实现强一致。

unclean.leader.election.enable=false:防止非同步副本被误选为Leader,避免数据回滚。

补充措施:

调整 log.flush.interval.ms,确保消息及时刷盘落地。

 

消费端:防止消息消费丢失

消费端最容易“误报成功”——消息还没处理完。

offset 就提交了,一旦服务重启,这条消息就永久丢失。

解决方案:手动提交 offset + 幂等消费。

如何保证Kafka消息不丢失?-mikechen

while (true) {
    ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
    for (ConsumerRecord<String, String> record : records) {
        process(record); // 执行业务逻辑
    }
    consumer.commitSync(); // 业务完成后再手动提交offset
}

补充优化:

对重要业务增加 幂等消费机制(如 Redis 标记、唯一业务ID 去重)。

Kafka 0.11+ 可开启 Exactly Once(EOS)语义,实现端到端“消息仅处理一次”。

关于mikechen

mikechen睿哥,10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

评论交流
    说说你的看法