Kafka 最初是 LinkedIn 的一个内部基础组件,用于处理持续的数据流,之后开源成为 Apache 项目。
Kafka 初衷是构建一个流平台,在平台上发布和订阅数据流,保存和处理数据。
Kafka 不同于一般的消息系统。作为现代分布式系统,Kafka 以集群方式运行,可以自由伸缩;Kafka 可以按要求存储数据,通过复制、持久化提供数据传递保证;Kafka 拥有流式处理能力,可动态处理派生流和数据集。
发布与订阅消息系统
在正式介绍 Kafka 之前,先介绍一下发布与订阅消息系统的概念及重要性。
在发布与订阅消息系统中,发送方不直接将消息发送到接收方,而是先以某种方式对消息进行分类,然后发送到消息中心;接收者订阅特定类型的消息,从而通过消息中心接收特定类型的消息。
如果不使用消息系统,应用 A 直接将消息发送给应用 B,在简单场景下没有问题。而如果应用 C 也需要接收此类消息,应用 A 就需要将消息同时发送给 B 和 C。当发送方和接收方逐渐增多,情况会越来越糟。
Kafka 中的基础概念
Kafka 是一款基于发布与订阅的消息系统,消息按一定的顺序持久化保存,可按需读取,具备故障保护和性能伸缩能力。
消息与批次
消息是 Kafka 的数据单元,类似数据库中一个数据行。消息由字节数组组成,同时有一个可选的元数据——键。键也是一个字节数组,用于将消息以可控方式写入到不同分区。
批次为属于同一个主题和分区的一组消息,消息分批写入 Kafka 可以减小网络开销,提升效率。注意,批次越大,单次传输时间越长。压缩批次数据可以通过计算处理提升传输和存储能力。
模式
模式(schema)即消息内容的结构,由于 Kafka 的消息内容为晦涩难懂的字符数组,额外的结构可以使消息容易理解,如 JSON 或 XML。
Kafka 的许多开发者使用 Apache Avro 序列化框架。Avro 提供一种紧凑的序列化格式,模式与消息体分开,模式发生变化时不需要重新生成代码,既向前兼容又向后兼容。
主题和分区
Kafka 中的消息通过主题进行分类,相当于数据库中的表。主题可以分为若干个分区,消息以追加的方式写入其中一个分区,按先入先出的顺序读取。
一个主题通常包含多个分区,无法在主题范围内保证消息顺序,但可以保证单个分区内的顺序。
分区可以分布在不同的服务器上,主题横跨多个服务器,能够提供比单个服务器更强的性能。
生产者和消费者
Kafka 的客户端有生产者和消费者两种基本类型。
生产者创建特定主题的消息,默认情况把消息均衡地写入到主题的所有分区上,也可以通过键或直接指定写入的分区。
消费者订阅一个或多个主题,按消息生成顺序来读取消息。消费者通过检查消息的偏移量来区分是否已经读取过某条消息。
偏移量是一种元数据(不断递增的整数值),创建消息时会将偏移量添加到消息中,分区内消息的偏移量唯一。消费者将每个分区最后读取消息的偏移量记录在 ZooKeeper 或 Kafka 中,消费者关闭或重启读取状态不会丢失。
Kafka 中有消费者群组的概念,消费者是消费者群组的一部分,一个或多个消费者共同读取一个主题。群组保证每个分区只能被一个消费者使用,群组中的消费者和分区之间的映射称为消费者对分区的所有权关系。当一个消费者失效,群组内的其他消费者可以接管失效消费者的工作。
broker 和集群
一个独立的 Kafka 服务器被称为 broker。broker 接收来自生产者的消息,为消息设置偏移量并保存。broker 为消费者提供服务,接收读取分区的请求并返回消息。单个 broker 可以轻松处理数千个分区及每秒百万级的消息量。
多个 broker 组成集群,每个集群中都有一个 broker 同时充当了集群控制器的角色,负责将分区分配给 broker 和监控等工作。每个分区从属于一个 broker,该 broker 称为分区的首领。分区分配给多个 broker 时会发生分区复制,提供消息冗余,在首领 broker 失效时接管领导权。
随 Kafka 部署数量增加,可以使用多个集群,多个集群间实现消息复制需要使用一个叫 MirrorMaker 的工具。
为什么选择 Kafka
基于发布与订阅的消息系统很多,而 Kafka 有以下优点:
多个生产者
Kafka 天然支持多个生产者,并以统一的格式对外提供数据,消费者无需协调来自不同生产者的数据流。
多个消费者
Kafka 支持多个消费者从一个消息流上读取数据,消费者之间互不影响。多个消费者也可以组成一个群组,共享一个消息流,保证整个群组对每条消息只处理一次。
基于磁盘的数据存储
Kafka 中消息被提交到磁盘,根据设置的保留规则进行保存,每个主题可以设置单独的保留规则,所以允许消费者非实时地读取消息,无需担心消息丢失。
伸缩性
Kafka 是一个具有灵活伸缩性的系统,可以先使用单个 broker,再扩展到包含 3 个 broker 的小型开发集群。对在线集群进行扩展不会影响整体的可用性。
高性能
通过横向扩展生产者、消费者和 broker,Kafka 可以轻松处理巨大的信息流,同时保证亚秒级的消息延迟。