Kafka 会不会丢消息?

一、认识 Kafka

Kafka 是分布式发布-订阅消息系统。它最初由 LinkedIn 公司开发,之后成为 Apache 项目的一部分。

Kafka 是一个分布式的,可划分的,冗余备份的持久性的日志服务。它主要用于处理活跃的流式数据。

1. kafka 架构

Kafka 的整体架构非常简单,是显式分布式架构,主要由 producer、broker(kafka)和 consumer 组成。

Producer(生产者)可以将数据发布到所选择的 topic(主题)中。生产者负责将记录分配到 topic 的哪一个 partition(分区)中。可以使用循环的方式来简单地实现负载均衡,也可以根据某些语义分区函数(如记录中的key)来完成。

Consumer(消费者)使用一个consumer group(消费组)名称来进行标识,发布到 topic 中的每条记录被分配给订阅消费组中的一个消费者实例。消费者实例可以分布在多个进程中或者多个机器上。

二、Kafka 到底会不会丢失消息?

在讨论 kafka 是否丢消息前先来了解一下什么是消息传递语义。

message delivery semantic 也就是消息传递语义,简单说就是消息传递过程中消息传递的保证性。主要分为三种:

  • at most once:最多一次。消息可能丢失也可能被处理,但最多只会被处理一次。
  • at least once:至少一次。消息不会丢失,但可能被处理多次。可能重复,不会丢失。
  • exactly once:精确传递一次。消息被处理且只会被处理一次。不丢失不重复就一次。

理想情况下肯定是希望系统的消息传递是严格 exactly once,也就是保证不丢失、只会被处理一次,但是很难做到。

回到主角 Kafka,Kafka 有三次消息传递的过程:

  • 生产者发消息给 Kafka Broker。
  • Kafka Broker 消息同步和持久化
  • Kafka Broker 将消息传递给消费者。

在这三步中每一步都有可能会丢失消息,下面详细分析为什么会丢消息,如何最大限度避免丢失消息。

三、生产者丢失消息

先介绍一下生产者发送消息的一般流程(部分流程与具体配置项强相关,这里先忽略):

  1. 生产者是与 leader 直接交互,所以先从集群获取 topic 对应分区的 leader 元数据;
  2. 获取到 leader 分区元数据后直接将消息发给过去;
  3. Kafka Broker 对应的 leader 分区收到消息后写入文件持久化;
  4. Follower 拉取 Leader 消息与 Leader 的数据保持一致;
  5. Follower 消息拉取完毕需要给 Leader 回复 ACK 确认消息;
  6. Kafka Leader 和 Follower 分区同步完,Leader 分区会给生产者回复 ACK 确认消息。

生产者采用 push 模式将数据发布到 broker,每条消息追加到分区中,顺序写入磁盘。消息写入 Leader 后,Follower 是主动与 Leader 进行同步。

Kafka 消息发送有两种方式:同步(sync)和异步(async),默认是同步方式,可通过 producer.type 属性进行配置。

Kafka 通过配置 request.required.acks 属性来确认 Producer 的消息:

  • 0:表示不进行消息接收是否成功的确认;不能保证消息是否发送成功,生成环境基本不会用。
  • 1:默认值,表示当 Leader 接收成功时确认;只要 Leader 存活就可以保证不丢失,保证了吞吐量。所以默认的 producer 级别是 at least once。
  • all:保证 leader 和 follower 不丢,但是如果网络拥塞,没有收到 ACK,会有重复发的问题。

如果 acks 配置为 0,发生网络抖动消息丢了,生产者不校验 ACK 自然就不知道丢了。

如果 acks 配置为 1 保证 leader 不丢,但是如果 leader 挂了,恰好选了一个没有 ACK 的 follower,那也丢了。

如果 acks 配置为 all 保证 leader 和 follower 不丢,但是如果网络拥塞,没有收到 ACK,会有重复发的问题。

四、Kafka Broker 丢失消息

Kafka Broker 接收到数据后会将数据进行持久化存储,你以为是下面这样的:

没想到是这样的:

操作系统本身有一层缓存,叫做 Page Cache,当往磁盘文件写入的时候,系统会先将数据流写入缓存中,至于什么时候将缓存的数据写入文件中是由操作系统自行决定。

Kafka 提供了一个参数 producer.type 来控制是不是主动 flush,如果 Kafka 写入到 mmap 之后就立即 flush 然后再返回 Producer 叫同步 (sync);写入 mmap 之后立即返回 Producer 不调用 flush 叫异步 (async)。

Kafka 通过多分区多副本机制中已经能最大限度保证数据不会丢失,如果数据已经写入系统 cache 中但是还没来得及刷入磁盘,此时突然机器宕机或者掉电那就丢了,当然这种情况很极端。

五、消费者丢失消息

消费者通过 pull 模式主动的去 kafka 集群拉取消息,与 producer 相同的是,消费者在拉取消息的时候也是找 leader 分区去拉取。

多个消费者可以组成一个消费者组(consumer group),每个消费者组都有一个组id。同一个消费者组的消费者可以消费同一 topic 下不同分区的数据,但是不会出现多个消费者消费同一分区的数据。

消费者消费的进度通过 offset 保存在 kafka 集群的 __consumer_offsets 这个 topic 中。

消费消息的时候主要分为两个阶段:

  1. 标识消息已被消费,commit offset坐标;
  2. 处理消息。

先 commit 再处理消息。如果在处理消息的时候异常了,但是 offset 已经提交了,这条消息对于该消费者来说就是丢失了,再也不会消费到了。

先处理消息再 commit。如果在 commit 之前发生异常,下次还会消费到该消息,重复消费的问题可以通过业务保证消息幂等性来解决。

六、总结

那么问题来了,kafka到底会不会丢消息?答案是:会!

Kafka可能会在三个阶段丢失消息:

  1. 生产者发送数据;
  2. Kafka Broker 存储数据;
  3. 消费者消费数据;

在生产环境中严格做到 exactly once 其实是难的,同时也会牺牲效率和吞吐量,最佳实践是业务侧做好补偿机制,万一出现消息丢失可以兜底。

原文链接:面试被问:Kafka 会不会丢消息?我是这么答的

(0)

相关推荐

  • Kafka到底会不会丢消息

    目录1.kafka是什么一种高吞吐量的分布式.发布订阅消息系统,它可以处理消费者规模的,网站中的所有动作流数据,具有高性能.持久化.多副本备份.横向扩展能力--以时间复杂度为 O(1) 的方式提供消息 ...

  • java开发之开源平台Kafka知识总结分享

    kafka的基本体系结构 一个完整的kafka消息中间件应该包含如下几个节点: 生产者:生产消息的节点 消费者:消费消息的节点 broker:接收生产者发送消息存储的节点 zookeeper:管理维护 ...

  • 曾经我以为我很懂Kafka,直到我看了这篇文章

    为什么需要消息队列 周末无聊刷着手机,某宝网APP突然蹦出来一条消息"为了回馈老客户,女朋友买一送一,活动仅限今天!".买一送一还有这种好事,那我可不能错过!忍不住立马点了去.于是 ...

  • 九张图带你了解Kafka

    Kafka非常重要,每个人都应该了解本文的内容. 现在,每个公司都在互联网系统中使用Kafka. Kafka似乎是解决分布式并提高系统吞吐量的最佳松耦合解决方案之一. 我大约6年前开始使用Kafka. ...

  • 真的,关于 Kafka 入门看这一篇就够了

    ImportNew 前天 以下文章来源于Java极客技术 ,作者cxuan Java极客技术java教程 java开发 java入门 java学习 java小课 java进阶 java知识 java技 ...

  • Kafak探究之路- 内部结构小结

    Kafak探究之路- 内部结构小结

  • Java分布式面试题集合

    (给ImportNew加星标,提高Java技能) 转自:乐知者, 链接:cnblogs.com/expiator/p/10201004.html 分布式分为分布式缓存(Redis).分布式锁(Redi ...

  • 在规模上使用Apache Kafka的20个最佳实践

    Apache Kafka是一种广受欢迎的分布式流媒体平台,New Relic,Uber和Square等数千家公司使用它来构建可扩展,高吞吐量,可靠的实时流媒体系统.例如,New Relic的生产Kaf ...

  • Kafka系列1:Kafka概况

    Kafka是当前分布式系统中最流行的消息中间件之一,凭借着其高吞吐量的设计,在日志收集系统和消息系统的应用场景中深得开发者喜爱.本篇就聊聊Kafka相关的一些知识点.主要包括以下内容: Kafka简介 ...

  • Kafka,RabbitMQ,ZeroMQ,RocketMQ,ActiveMQ消息队列的对比

    本文将从,Kafka.RabbitMQ.ZeroMQ.RocketMQ.ActiveMQ 17 个方面综合对比作为消息队列使用时的差异. 内容目录 一.资料文档 二.开发语言 三.支持的协议 四.消息 ...

  • Kafka 如果丢了消息,怎么处理的?

    Kafka存在丢消息的问题,消息丢失会发生在Broker,Producer和Consumer三种. Broker Broker丢失消息是由于Kafka本身的原因造成的,kafka为了得到更高的性能和吞 ...

  • Kafka如果丢了消息,怎么处理的?

    Kafka存在丢消息的问题,消息丢失会发生在Broker,Producer和Consumer三种.Java面试宝典PDF完整版 Broker Broker丢失消息是由于Kafka本身的原因造成的,ka ...

  • Kafka如何做到1秒处理1500万条消息?

    " 一位软件工程师将通过本文向您呈现 Apache Kafka 在大型应用中的 20 项最佳实践. Apache Kafka 是一款流行的分布式数据流平台,它已经广泛地被诸如 New Rel ...

  • Redis、Kafka 和 Pulsar 消息队列对比

    刘德恩 云时代架构 一.最基础的队列 最基础的消息队列其实就是一个双端队列,我们可以用双向链表来实现,如下图所示: push_front:添加元素到队首: pop_tail:从队尾取出元素. 有了这样 ...

  • 图解Kafka消息发送者核心参数与工作机制

    丁威 中间件兴趣圈 做积极的人,越努力越幸运! 掌握一到两门java主流中间件,是敲开BAT等大厂必备的技能,送给大家一个Java中间件学习路线,助力大家实现职场的蜕变.java中间件进阶路线(三本电 ...

  • 下班后的工作消息,要不要回?不回,丢了工作;回了,没了生活 ......

    小编相信这个辩题一定戳中了无数打工人的泪点. 工作与生活的平衡,这是一个在职场中永远存在的话题.我们都想努力平衡工作与生活,但最后又不得不对残忍现实而妥协.相信大家肯定在各类媒体上看到过「某某员工因不 ...

  • Kafka中消息丢失和重复消费,以及Leader选举机制

    一.Kafka中的消息是否会丢失和重复消费 要确定Kafka的消息是否丢失或重复,从两个方面分析入手:消息发送和消息消费 1.消息发送 kafka消息发送有同步(sync).异步(async)两种,以 ...