Kafka

  • 生产者
  • 消费者

多层机制来保证消息不丢失。

生产者

  • 同步发送模式
  • acks=-1,确保所有副本都受到消息才算成功
  • 重试机制,发送失败时自动重试

服务器端

  • 多副本,每个分区有多个副本分布在不同的 Broker 上
  • ISR(In-Sync Replica)列表,只有跟得上 Leader 的副本才能成为候选
  • min.insync.replicas >= 2,确保至少两个副本同步才算写入成功

消费者

  • 手动提交偏移量,消息处理完成才提交

Kafka 消息保证生产的信息不丢失和重复消费问题.

1)使用同步模式的时候,有 3 种状态保证消息被安全生产,在配置为 1(只保证写入 leader 成功)的话,如果刚好 leader partition 挂了,数据就会丢失。 2)还有一种情况可能会丢失消息,就是使用异步模式的时候,当缓冲区满了,如果配置为 0(还没有收到确认的情况下,缓冲池一满,就清空缓冲池里的消息), 数据就会被立即丢弃掉。

在数据生产时避免数据丢失的方法: 只要能避免上述两种情况,那么就可以保证消息不会被丢失。

1)就是说在同步模式的时候,确认机制设置为-1,也就是让消息写入 leader 和所有的副本。

2)还有,在异步模式下,如果消息发出去了,但还没有收到确认的时候,缓冲池满了,在配置文件中设置成不限制阻塞超时的时间,也就说让生产端一直阻塞,这样也能保证数据不会丢失。 在数据消费时,避免数据丢失的方法:如果使用了 storm,要开启 storm 的 ackfail 机制;如果没有使用 storm,确认数据被完成处理之后,再更新 offset 值。低级 API 中需要手动控制 offset 值。

消费者丢数据

  • 关闭消费者的自动提交 offset
  • 消费者自己提交 offset, 自己实现幂等

Kafka 丢数据

可能发生的场景:

  • Kafka 的 leader 机器宕机了,将 follower 切换为 leader 之后,就会发现说这个数据就丢了

避免方式:

  • topic 设置 replication.factor 参数,保证 partition 两个副本
  • 在 Kafka 服务端设置 min.insync.replicas 参数:这个值必须大于 1,要求一个 leader 至少感知到有至少一个 follower 还跟自己保持联系,没掉队,这样才能确保 leader 挂了还有一个 follower
  • 在 producer 端设置 acks=all :这个是要求每条数据,必须是写入所有 replica 之后,才能认为是写成功了。
  • 在 producer 端设置 retries=MAX (设置很大的一个值,无限次重试的意思):这个是要求一旦写入失败,就无限重试,卡在这里了。

至少在 Kafka broker 端就可以保证在 leader 所在 broker 发生故障,进行 leader 切换时,数据不会丢失。

reference