Kafka是由 Apache 软件基金会开发的一个开源流处理平台, 是一个分布式的基于发布/订阅模式的消息队列(Message Queue),支持多分区、多副本,主要应用于大数据实时处理领域。

Kafa基础架构图

copyFromJvaaKeeper

  • Producer :消息生产者,就是向 kafka broker 发消息的客户端;
  • Consumer :消息消费者,向 kafka broker 取消息的客户端;
  • Consumer Group (CG):消费者组,由多个 consumer 组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
  • Broker :一台 kafka 服务器就是一个 broker。一个集群由多个 broker 组成。一个 broker 可以容纳多个 topic;
  • Topic :可以理解为一个队列,Kafka 的消息通过 Topics(主题) 进行分类,生产者和消费者面向的都是一个 topic;
  • Partition:为了实现扩展性,一个非常大的 topic 可以分布到多个 broker(即服务器)上, 一个 topic 可以分为多个 partition,每个 partition 是一个有序的队列; partition 中的每条消息都会被分配一个有序的 id( offset)。 kafka 只保证按一个 partition 中的顺序将消息发给 consumer,不保证一个 topic 的整体(多个 partition 间)的顺序;
  • Replica:副本,为保证集群中的某个节点发生故障时,该节点上的 partition 数据不丢失,且 kafka 仍然能够继续工作,kafka 提供了副本机制,一个 topic 的每个分区都有若干个副本, 一个 leader 和若干个 follower;
  • leader:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是 leader
  • follower:每个分区多个副本中的“从”,实时从 leader 中同步数据,保持和 leader 数据的同步。leader 发生故障时,某个 follower 会成为新的 follower;
  • Offset: kafka 的存储文件都是按照 offset.kafka 来命名,用 offset 做名字的好处是方便查找。例如你想找位于 2049 的位置,只要找到 2048.kafka 的文件即可。当然 the first offset 就是 00000000000.kafka。

Kafka基本概念

五个核心API

API文档

  • Producer API 允许应用程序发布记录流至一个或多个 Kafka 的话题(Topics)
  • Consumer API 允许应用程序订阅一个或多个主题,并处理这些主题接收到的记录流
  • Streams API 允许应用程序充当流处理器(stream processor),从一个或多个主题获取输入流,并生产一个输出流至一个或多个的主题,能够有效地变换输入流为输出流
  • Connector API 允许构建和运行可重用的生产者或消费者,能够把 Kafka 主题连接到现有的应用程序或数据系统。例如,一个连接到关系数据库的连接器(connector)可能会获取每个表的变化
  • Admin API 允许管理和检查主题、brokes 和其他 Kafka 对象。(这个是新版本才有的)

主题和日志

主题是一个逻辑概念,表示同一类别消息记录的集合,一个主题可以由0~N个消费者订阅并消费数据。
日志则是实际存储数据的文件,一般按照分区进行存储,每个分区下都有一个log文件和index文件。

日志中记录的文件是有序的,并且只能追加记录。Kafka会保留消息记录,并根据配置的策略进行删除旧的数据。如果没有删除,则消息一直可以被消费,而消费者可以控制从哪个位置开始消费。

分布式

日志的分区会跨服务器的分布在 Kafka 集群中,每个服务器会共享分区进行数据请求的处理。每个分区可以配置一定数量的副本分区提供容错能力

每个分区都有一个服务器充当“leader”和零个或多个服务器充当“followers”。 leader 处理所有的读取和写入分区的请求,而 followers 被动的从领导者拷贝数据。如果 leader 失败了,followers 之一将自动成为新的领导者。每个服务器可能充当一些分区的 leader 和其他分区的 follower,所以 Kafka 集群内的负载会比较均衡。

生产者

生产者发布数据到他们所选择的主题。生产者负责选择把记录分配到主题中的哪个分区。这可以使用轮询算法( round-robin)进行简单地平衡负载,也可以根据一些更复杂的语义分区算法(比如基于记录一些键值)来完成。

消费者

消费者以消费群(consumer group )的名称来标识自己,每个发布到主题的消息都会发送给订阅了这个主题的消费群里面的一个消费者的一个实例。消费者的实例可以在单独的进程或单独的机器上。

如果所有的消费者实例都属于相同的消费群,那么记录将有效地被均衡到每个消费者实例。

如果所有的消费者实例有不同的消费群,那么每个消息将被广播到所有的消费者进程。

这是 kafka 用来实现一个 topic 消息的广播(发给所有的 consumer) 和单播(发给任意一个 consumer)的手段。一个 topic 可以有多个 CG。 topic 的消息会复制 (不是真的复制,是概念上的)到所有的 CG,但每个 partion 只会把消息发给该 CG 中的一 个 consumer。如果需要实现广播,只要每个 consumer 有一个独立的 CG 就可以了。要实现单播只要所有的 consumer 在同一个 CG。用 CG 还可以将 consumer 进行自由的分组而不需 要多次发送消息到不同的 topic;Kafka消费群的实现方式是通过分割日志的分区,分给每个 Consumer 实例,使每个实例在任何时间点的都可以“公平分享”独占的分区

使用场景

消息队列

Kafka 被当作传统消息中间件的替代品。消息中间件的使用原因有多种(从数据生产者解耦处理,缓存未处理的消息等)。与大多数消息系统相比,Kafka 具有更好的吞吐量,内置的分区,多副本和容错功能,这使其成为大规模消息处理应用程序的良好解决方案。

网站行为跟踪

Kafka 的初衷就是能够将用户行为跟踪管道重构为一组实时发布-订阅数据源。这意味着网站活动(页面浏览量,搜索或其他用户行为)将被发布到中心主题,这些中心主题是每个用户行为类型对应一个主题的。这些数据源可被订阅者获取并用于一系列的场景,包括实时处理,实时监控和加载到 Hadoop 或离线数据仓库系统中进行离线处理和报告。用户行为跟踪通常会产生巨大的数据量,因为用户每个页面的浏览都会生成许多行为活动消息。

日志聚合

日志聚合通常从服务器收集物理日志文件,并将它们集中放置(可能是文件服务器或HDFS),以便后续处理。kafka 抽象出文件的细节,并将日志或事件数据作为消息流清晰地抽象出来。这为低时延的处理提供支持,而且更容易支持多个数据源和分布式的数据消费。相比集中式的日志处理系统(如 Scribe 或 Flume),Kafka 性能同样出色,而且因为副本备份提供了更强的可靠性保证和更低的端到端延迟。

流处理

Kafka 的流数据管道在处理数据的时候包含多个阶段,其中原始输入数据从 Kafka 主题被消费然后汇总,加工,或转化成新主题用于进一步的消费或后续处理。例如,用于推荐新闻文章的数据流处理管道可能从 RSS 源抓取文章内容,并将其发布到“文章”主题; 进一步的处理可能是标准化或删除重复数据,然后发布处理过的文章内容到一个新的主题, 最后的处理阶段可能会尝试推荐这个内容给用户。这种处理管道根据各个主题创建实时数据流图。从版本 0.10.0.0 开始,Apache Kafka 加入了轻量级的但功能强大的流处理库 Kafka Streams,Kafka Streams 支持如上所述的数据处理。

事件源

事件源是一种应用程序设计风格,是按照时间顺序记录的状态变化的序列。Kafka 的非常强大的存储日志数据的能力使它成为构建这种应用程序的极好的后端选择。

提交日志

Kafka 可以为分布式系统提供一种外部提交日志(commit-log)服务。日志有助于节点之间复制数据,并作为一种数据重新同步机制用来恢复故障节点的数据。Kafka 的 log compaction 功能有助于支持这种用法。Kafka 在这种用法中类似于Apache BookKeeper 项目。