在正式讨论Apache Kafka (如下简称Kafka)以前,先来了解发布与订阅消息系统的概念, 并认识这个系统的重要性。数据(消息)的发送者(发布者)不会直接把消息发送给接收 者,这是发布与订阅消息系统的一个特色。发布者以某种方式对消息进行分类,接收者 (订阅者)订阅它们,以便接收特定类型的消息。发布与订阅系统通常会有一个 broker,也就是发布消息的中心点。前端
发布与订阅消息系统的大部分应用场景都是从一个简单的消息队列或一个进程间通讯开始的。好比电商系统中,包含会员模块、订单模块、商品模块、推荐模块、配送物流模块等,多个模块(子系统)间涉及消息的传递。数据库
最先的应用解决方案就是采用(子系统间)直连的方式,使得不少子系统交错复杂。这种点对点的链接方式,造成网状的链接,弊端不少,不一一赘述。
数组
后来,为了解决子系统间直连交错的问题,出现了队列系统。下图所示的架构包含了 3 个独立的发布与订阅系统。服务器
这种方式比直接使用点对点的链接要好得多,但这里有太多重复的地方。你的公司所以要为数据队列维护多个系统,每一个系统又有各自的缺陷和不足。并且,接下来可能会有更多的场景须要用到消息系统。 此时,你真正须要的是一个单一的集中式系统,它能够用来发布通用类型的数据,其规模能够随着公司业务的增加而增加。这时Kafka登场了。网络
Kafka就是为了解决上述问题而设计的一款基于发布与订阅的消息系统。它通常被称为 “分布式提交日志”或者“分布式流平台”。文件系统或数据库提交日志用来提供全部事务 的持久记录 , 经过重放这些日志能够重建系统的状态。一样地, Kafka 的数据是按照 必定顺序持久化保存的,能够按需读取 。 此外, Kafka 的数据分布在整个系统里,具有数据故障保护和性能伸缩能力。架构
Kafka的数据单元被称为消息。若是你在使用 Kafka以前已经有数据库使用经验,那么可 以把消息当作是数据库里的一个“数据行”或一条“记录”。消息由字节数组组成,因此 对于 Kafka来讲,消息里的数据没有特别的格式或含义。消息能够有一个可选的元数据, 也就是键(key)。键也是一个字节数组,与消息同样,对于 Kafka来讲也没有特殊的含义。 当消息以一种可控的方式写入不一样的分区时,会用到键。最简单的例子就是为键生成一个一致 性散列值,而后使用散列值对主题分区数进行取模,为消息选取分区 。这样可 以保证具备 相同键的消息老是被写到相同的分区上。分布式
为了提升效率,消息被分批次写入 Kafka。 批次就是一组消息,这些消息属于同一个主题 和分区。若是每个消息都单独穿行于网络,会致使大量的网络开销,把消息分红批次传 输能够减小网络开销。不过,这要在时间延迟和吞吐量之间做出权衡;批次越大,单位时间内处理的消息就越多,单个消息的传输时间就越长。批次数据会被压缩,这样能够提高 数据的传输和存储能力,但要作更多的计算处理。微服务
Kafka 的悄息经过 主题进行分类。主题就比如数据库的表,或者文件系统里的文件夹。主题能够被分为若干个分区 , 一个分区就是一个提交日志。消息以追加的方式写入分区,而后以先入先出的顺序读取。要注意,因为一个主题通常包含几个分区,所以没法在整个主题范围内保证消息的顺序,但能够保证消息在单个分区内的顺序。下图 所示的主题有 4 个分区,消息被迫加写入每一个分区的尾部。 Kaflca经过分区来实现数据冗余和伸缩性。分区能够分布在不一样的服务器上,也就是说, 一个主题能够横跨多个服务器,以此来提供比 单个服务器更强大的性能。oop
咱们一般会使用流这个词来描绘Kafka这类系统对数据。不少时候,人们把一个主题的数据当作一个流,无论它有多少个分区。流是一组从生产者移动到消费者的数据。当咱们讨 论流式处理时,通常都是这样描述消息的。 Kaflca Streams、 Apache Samza 和 Storm 这些框 架以实时的方式处理消息,也就是所谓的流式处理。咱们能够将流式处理与离线处理进行比较,好比 Hadoop 就是被设计用于在稍后某个时刻处理大量的数据。性能
Kafka 的客户端就是 Kafka 系统的用户,它们被分为两种基本类型 : 生产者和消费者。除此以外,还有其余高级客户端 API——用于数据集成的 Kaflca Connect API 和用于流式处理 的 Kaflca Streams。这些高级客户端 API 使用生产者和消费者做为内部组件,提供了高级的 功能。
生产者建立消息。在其余发布与订阅系统中,生产者可能被称为发布者或写入者。通常情 况下,一个消息会被发布到一个特定的主题(topic)上。生产者在默认状况下把消息均衡地分布到主题的全部分区上,而并不关心特定消息会被写到哪一个分区。不过,在某些状况下,生产者会把消息直接写到指定的分区。这一般是经过消息键和分区器来实现的,分区器为键生 成一个散列值,并将其映射到指定的分区上。这样能够保证包含同一个键的消息会被写到 同一个分区上。生产者也可使用自定义的分区器,根据不一样的业务规则将消息映射到分 区。下一章将详细介绍生产者。
消费者读取消息。在其余发布与订阅系统中,消费者可能被称为订阅者或读者 。 消费者订阅一个或多个主题,并按照消息生成的顺序读取它们。消费者经过检查消息的偏移盘来区 分已经读取过的消息。 偏移量是另外一种元数据,它是一个不断递增的整数值,在建立消息 时, Kafka 会把它添加到消息里。在给定的分区里,每一个悄息的偏移量都是惟 一 的。消费 者把每一个分区最后读取的悄息偏移量保存在 Zookeeper或 Kafka上,若是悄费者关闭或重 启,它的读取状态不会丢失。
消费者是消费者群组的一部分,也就是说,会有一个或多个消费者共同读取一个主题。 群组保证每一个分区只能被一个消费者使用 。下图所示的群组中,有 3 个消费者同时读取一 个主题。其中的两个消费者各自读取一个分区,另一个消费者读取其余两个分区。消费 者与分区之间的映射一般被称为悄费者对分区的全部权关系 。
经过这种方式,消费者能够消费包含大量消息的主题。并且,若是一个消费者失效,群组 里的其余消费者能够接管失效悄费者的工做。第 4章将详细介绍消费者和悄费者群组。
一个独立的 Kafka服务器被称为 broker。 broker接收来自 生产者的消息,为消息设置偏移 量,并提交消息到磁盘保存。 broker 为消费者提供服务,对读取分区的请求做出响应,返 回已经提交到磁盘上的消息。根据特定的硬件及其性能特征,单个 broker能够轻松处理数 千个分区以及每秒百万级的消息量。
Broker能够看做是消息中间件处理节点,一个Kafka节点就是一个broker,一个或者多个Broker能够组成一个Kafka集群。
broker是集群的组成部分。每一个集群都有一个 broker 同时充当了集群控制器的角色(自动 从集群的活跃成员中选举出来)。控制器负责管理工做,包括将分区分配给 broker和监控 broker. 在集群中, 一个分区从属于一个 broker, i亥 broker被称为分区的首领。一个分区 能够分配给多个 broker,这个时候会发生分区复制(见下图)。这种复制机制为分区提供 了消息冗余,若是有一个 broker失效,其余 broker能够接管领导权。不过,相关的消费者 和生产者都要从新链接到新的首领。
保留消息(在必定期限内)是 Kafka的一个重要特性。 Kafka broker默认的消息保留策略 是这样的:要么保留一段时间(好比 7天),要么保留到消息达到必定大小的字节数(比 如 1GB)。当消息数量达到这些上限时,旧消息就会过时井被删除,因此在任什么时候刻, 可 用消息的总量都不会超过配置参数所指定的大小。主题能够配置本身的保留策略,能够将 悄息保留到再也不使用它们为止。例如,用于跟踪用户活动的数据可能须要保留几天,而应 用程序的度量指标可能只须要保留几个小时。能够经过配置把主题看成 紧凑型日志, 只有 最后一个带有特定键的消息会被保留下来。这种状况对于变动日志类型的数据来讲比较适 用,由于人们只关心最后时刻发生的那个变动。
多个生产者
Kafka 能够无缝地支持多个生产者,无论客户端在使用单个 主题仍是多个主题。因此它很 适合用来从多个前端系统收集数据,并以统一的格式对外提供数据。例如, 一个包含了 多 个微服务的网站,能够为页面视图建立一个单独的主题,全部服务都以相同的消息格式向 该主题写入数据。消费者应用程序会得到统一的页面视图,而无需协调来自不一样生产者的 数据流。
多个消费者
除了支持多个生产者外, Kafka也支持多个消费者从一个单独的消息流上读取数据,并且 消费者之间直不影响。这与其余队列系统不一样,其余队列系统的消息一旦被一个客户端读 取,其余客户端就没法再读取它。另外,多个消费者能够组成一个群组,它们共享一个消息流,并保证整个群组对每一个给定的消息只处理一次。
基于磁盘的数据存储
Kafka不只支持多个消费者,还容许消费者非实时地读取消息,这要归功于 Kafka的数据 保留特性。?肖息被提交到磁盘,根据设置的保留规则进行保存。每一个主题能够设置单独的 保留规则,以便知足不一样消费者的需求,各个主题能够保留不一样数量的消息。消费者可能 会由于处理速度慢或突发的流量高峰致使无陆及时读取消息,而持久化数据能够保证数据 不会丢失。?肖费者能够在进行应用程序维护时离线一小段时间,而无需担忧消息丢失或堵 塞在生产者端。 消费者能够被关闭,但消息会继续保留在 Kafka里。消费者能够从上次中 断的地方继续处理消息。
伸缩性
为了可以轻松处理大量数据, Kafka 从一开始就被设计成一个具备灵活伸缩性的系统。用 户在开发阶段能够先使用单个 broker,再扩展到包含 3 个 broker 的小型开发集群,而后随 着数据盐不断增加,部署到生产环境的集群可能包含上百个 broker。对在线集群进行扩展 丝绝不影响总体系统的可用性。也就是说, 一个包含多个 broker的集群,即便个别 broker 失效,仍然能够持续地为客户提供服务。要提升集群的容错能力,须要配置较高的复制系 数。
高性能
上面提到的全部特性,让 Kafka成为了一个高性能的发布与订阅消息系统。经过横向扩展 生产者、消费者和 broker, Kafka能够轻松处理巨大的消息流。在处理大量数据的同时, 它还能保证亚秒级的消息延迟。