Kafka Producer丢消息

是的,如果消息仅写入 Page Cache(未刷盘)时 Broker 崩溃,消息会丢失

核心原因:Page Cache 的本质是“内存缓存”,不具备持久化能力

Page Cache 是操作系统的内存级缓存,数据存储在内存中。而内存的特性是“断电/进程崩溃后数据丢失”——当 Broker 进程崩溃或服务器宕机时,Page Cache 中的数据会随着内存清空而丢失。

结合 acks=1 的场景来看:

  • 生产者收到“写入成功”的确认(因为 Leader 已将消息写入 Page Cache);
  • 但此时消息尚未被操作系统异步刷到磁盘(.log 文件);
  • 若 Broker 崩溃,Page Cache 中的消息丢失,且没有其他副本(若副本数为 1)或 Follower 尚未同步该消息,则这条消息彻底丢失。

延伸:如何避免这种丢失?

若要防止“仅在 Page Cache 中”的消息丢失,需要从两个维度优化:

  1. 增加副本冗余(replication.factor > 1
    即使 Leader 崩溃,Follower 可能已同步该消息(Follower 同步时也会先写入自己的 Page Cache),此时集群会选举 Follower 为新 Leader,消息可从新 Leader 读取。
    注意:Follower 同步也依赖自身 Page Cache,若 Follower 未同步完成时 Leader 崩溃,仍有丢失风险。

  2. 强制刷盘(不推荐,会牺牲性能)
    通过 log.flush.interval.messages=1log.flush.interval.ms=0 配置,让消息写入后立即刷盘(不再依赖操作系统异步刷盘)。但这会将内存操作变为磁盘 IO 操作,严重降低写入性能,违背 Kafka 高吞吐设计初衷,通常仅在极致可靠性场景下使用。

总结

  • 结论:仅写入 Page Cache 未刷盘时 Broker 崩溃,消息会丢失(内存数据无法持久化)。
  • Kafka 的权衡:这种“允许短暂内存级确认,牺牲部分可靠性换性能”的设计,是 acks=1 的核心特性——适合对吞吐要求高、可容忍少量消息丢失的场景(如日志采集)。若需绝对不丢失,需使用 acks=-1(等待所有 ISR 副本确认)+ 副本数 ≥ 2。
posted @ 2025-07-17 10:11  认真的刻刀  阅读(18)  评论(0)    收藏  举报