【Kafka 权威指南】初识 Kafka

发布-订阅模型

经过发布-订阅模型,各个子模块之间作到解耦。各个子模块只须要知道本身须要往中间件——Kafka 里取值仍是存值便可。简单的抽象模型以下图所示:前端

发布-订阅模型

走近 Kafka

Kafka 的出现,作到了子系统之间的解耦合。所以,它也被称为「分布式日志提交系统」或者「分布式流处理系统」。下面是 Kafka 的一些基本概念:数据库

消息和批处理

Kafka 处理的数据单元叫作「消息」,一种相似于数据库中「行」或者「记录」的概念。这些数据单元,对于 Kafka 而言,并无特殊意义,都是字节数组。可是,每一个消息能够拥有描述性的元数据——Key,这些 Key 一般用来表示消息应该存放的分区。为了效率,Kafka 里的消息都是批处理的,同一批(Batch)的消息主题和分区相同,这样的设计有助于减小单消息在网络传输带来的开销。固然,这种处理方式,也是一种在吞吐量和网络时延里的折中方案。后端

模式

为了让消息具有更加的可读性,Kafka 使用模式(Schema)来管理数据类型,如 JSON、XML 等等。为了向后兼容,或者作到可拓展性,选择合适的 Schema 很是重要。数组

主题和分区

Kafka 里的消息按主题分类。鉴于 Kafka 里的消息是按追加、从头至尾读取的方式,使用分区能够大大提升 Kafka 的读取效率,也提供了系统的可拓展性。消息写入分区的方式入下图所示:安全

Kafka 消息写入分区

一个主题的消息,在相似于 Kafka 这样的系统中,被称为——「流」。服务器

生产者和消费者

Kafka 有两个重要的概念:生产者和消费者;两个高级的客户端(Kafka 使用者)接口:集成 Kafka 的 Kafka Connect API 和操做 Kafka 的 Kafka Stream 接口。网络

生产者:建立消息的主体。能够经过不一样的 Key 把消息发往不一样的主题中去,还能够根据用户自定义的行为发送日志。
消费者:读取消息的主体。消费者追踪每一个分区的 offset 的值,决定从哪里读取消息。Zookeeper 或者 Kafka 能够存储 offset 的值。共同消费一个主题的消费者,被称为「消费组」。消费组中的消费者和主题中的分区的队列关系,被称为「消费者全部权」。使用以下图所示的消费组,可使 Kafka 更便于水平拓展:分布式

消费组模型

中间人和集群

中间人:单个的 Kafka 服务器叫作「中间人」(Broker)。一个 Kafka 中间人,接收生产者发来的消费,分配偏移量,并存储入物理空间中去;同时,中间人还接收消费者的请求,把物理空间里的消息响应回去。
集群:一组协同工做的中间人叫作集群。在一个集群中,会有一个中间人充当集群控制器的角色,该控制器负责监控中间人的状态。在集群中,独占分区的中间人叫作该分区的「头头」(Leader)。多个中间人共享分区,可使消息进行「主从复制」。当一个中间人挂掉,其它的中间人可接管头头的角色。固然前提是,接管头头角色的中间人以前能够和前头头联通。下图是一个集群里,不一样中间人间复制消息的图示:微服务

消息复制

Kafka 还有一个重要的概念:保质期(Retention),表示消息在 Kafka 服务器里能够保留的时长。Kafka 能够根据不一样的策略,配置服务器里消息的保质期。如:根据消息的大小(达到特定大小后失效)、根据时间(指定时间后过时)配置。工具

多集群

随着业务的拓展,以下需求一般会被提出:

  • 数据类型分离
  • 安全因素的数据隔离
  • 多数据中心(灾备)

举个例子,不一样集群间能够经过 MirrorMaker 工具进行数据复制。简而言之,就是经过该工具,从一个集群消费消息,而后向另一个集群生产消息。下面是一个经过 MirrorMaker 进行集群中消息复制的图例:

集群消息复制

为何选择 Kafka

虽然有不少发布/订阅式的系统,可是选择 Kafka 是出于如下缘由。

多生产者

Kafka 能够无缝接入多个生产者。多个消费者能够消费同一个主题内的消息,而无需知道该主题内的消息来自哪一个生产者。一个简单的例子就是:多个微服务往同一个主题中投放消息,而后该主题的消息「聚合」了多个应用。

多消费者

Kafka 多消费者模型,表现为多个消费者互不干扰地消费同一主题内的消息。这也是 Kafka 和其它消息队列不一样的地方。

基于磁盘的有效期

Kafka 中的消息会被写入磁盘,得益于 Kafka 灵活的消息过时策略,磁盘中的消息的有效期是可配置的。鉴于此,Kafka 不会有丢消息的危险。即使应用重启,它仍可以借助 Kafka 从结束的地方从新开始。

拓展性

Kafka 拥有灵活的拓展性配置,这意味着:用户能够根据需求拓展 Kafka 的 Broker 的数量来接收和处理任意数量的数据;多 Broker 能够接管单 Broker 中的错误。

高性能

上述 多生产者/消费者可拓展性灵活的有效期配置 造就了 Kafka 的高性能。

Kafka 生态系统

基于 Kafka 的生产/消费模型,有一系列的生产和消费的技术。各类处理消息的技术,以统一的接口方式,构成了 Kafka 的生态系统。Kafka 生态系统以下图所示:

Kafka 生态系统

应用

活动跟踪

Kafka 能够记录用户访问前端应用的活动日志,这也是 LinkedIn 开发 Kafka 的初衷。Kafka 搜集的用户点击鼠标的事件、浏览页面的事件、更改我的主页的事件,都可以用做后端程序处理,使其变成有价值的产物。

系统监控和日志记录

能够向 Kafka 中发送系统的运行日志,经过分析这些日志,能够对系统的各个指标进行评估。同时,Kafka 记录的日志可供其它的日志分析系统消费。

发消息

Kafka 能够向其它应用发送中间件的消息,如:数据库有改动,能够将改动的信息发往应用程序。

流式处理

Kafka 提供的对数据的流式操做,和 Hadoop 的 Map/Reduce 模型相似,能够作到数据的实时处理。

Kafka.原点 1

Kafka 设计的初衷是处理不一样类型的数据,实现一个简单、结构化的高性能系统,以实时地分析用户行为和监控系统状态。
—— Jeff Weiner LinkedIn CEO

LinkedIn 问题

LinkedIn 内部最初策划的系统监控平台,在监控常规的项目上,如:CPU 利用率、系统性能上难以让人满意。开发人员没法灵活地监控本身的系统状态,大多状况下还有系统错误。并且,时间间隔长、须要人为介入也是一个大的问题。

同时,LinkedIn 还建立了一个经过前端向后台传输 XML 文件,让后台处理 XML 文件以达到分析用户行为的监控应用。该应用一样很差用:更改 XML 的格式,须要先后台同时更改;对用户行为的分析不是实时的。

系统监控平台和用户活动分析平台不能共用同样的数据模型,可是两者之间却有相同点。即:接收特定格式的数据 --> 返回处理结果。在使用开源解决方案——RocketMQ 也没法真正解决现有问题后,LinkedIn 决定本身开发一个程序。

Kafka 的诞生

由 Jay kreps 主导的开发团队但愿构建一个能同时知足监控系统和追踪系统的消息系统,最初的目标是:

  • 经过 push-pull 模型对生产者和消费者解耦
  • 提供消息持久性支持多消费者
  • 优化消息的高吞吐率
  • 容许系统水平拓展

最终,开发出来的 Kafka 在接口上和典型的消息系统的 发布/订阅 一致,但在存储层上,更像一个日志聚合系统。借助 Apache Avro 进行消息序列化,Kafka 可以作到大规模的消息处理。

开源

Kafka 在 2010 年终的时候,发布到了 GitHub 上,2011 年 7 月进入 Apache 孵化器,2012 年 10 月从 Apache 孵化器毕业,并成为 Apache 的顶级项目。此后,Kafka 一直在开源社区和 LinkedIn 内部工程师的优化下强壮发展,并逐渐成为大数据处理的必要工具。


  1. 「个人英雄学院」