Apache Kafka 简介

108 阅读18分钟

本章内容包括

  • Apache Kafka 是什么及其使用场景
  • Kafka 在企业生态系统中的定位与作用
  • Kafka 的架构概览
  • Kafka 的运行与使用

现代企业应用通常由彼此独立的组件和服务构成,这些组件通过交换消息进行通信。随着系统在多台服务器、数据中心、云平台和地理区域间扩展,管理消息流变得愈发复杂。对可靠性、容错能力和近实时性能的需求则使问题更为棘手。Apache Kafka 正是为应对这些要求而设计的:它提供了一个高吞吐量、分布式的消息平台,能够高效处理大规模的数据流。

在本章中,我们将了解 Apache Kafka 的定义,深入探讨其基本组件及各自作用,并讨论 Kafka 的适用场景。更重要的是,我们会看看 Kafka 如何融入更广泛的企业生态系统。最后,我们将介绍使用 Kafka 所需的硬件、工具和编程语言方面的基本要求。

1.1 Apache Kafka 是什么?它如何解决我们的问题?

我们的世界以实时运行为常态。下单后我们期待立即得到确认;寄包裹时我们希望能实时跟踪;当信用卡出现可疑使用时,我们要的是立刻知道,而不是等到明天。作为用户,我们已经习惯组织在事情发生的同时就能处理和响应数据。

这种实时期待,加上数据量的爆炸式增长——从物联网(IoT)传感器持续流入的数据,到用户在众多数字触点上的交互——给 IT 团队带来了许多挑战。以往为日终批处理设计的传统批处理架构,很难适应“每一秒都很重要”的新现实。

对于拥有复杂遗留系统的成熟组织来说,将架构转向能处理实时数据流,同时保持系统可靠性,已成为一项关键挑战。随着团队把单体应用拆分为分布式服务,复杂度急剧上升。团队需要独立地演进服务,同时确保组织内的数据流可靠传递。几十个服务需要互相通信时,如何维护系统稳定?如何确保团队在部署变更时不会破坏其他服务?如何在系统间处理这些巨量数据流,而不把点对点集成搞成一张乱七八糟的网?

Kafka 提供了一种架构模式来应对这些挑战:它充当数据的中枢神经系统。并非巧合,根据 Kafka 社区的数据,超过 80% 的财富 100 强公司都依赖 Kafka 来解决这些问题。从支持服务的独立演进、通过异步通信防止系统级故障,到将批处理系统转变为实时流处理,Kafka 已成为现代分布式架构的骨干。

Kafka 是一个健壮的、开源的、分布式流处理平台,彻底改变了组织处理数据流的方式。本质上,Kafka 充当组织所有数据事件的持久化、分布式日志。可以把它想象成一根中央骨干:每一条重要信息——从客户交互到系统状态变化——都能可靠地被存储并实时处理。这种架构方式带来了关键优势:

  • 通过持久化数据流,Kafka 支持实时处理并能可靠地重放数据。当某个消费系统失败时,它可以从上次停下的位置继续处理。开发需要历史数据的新服务时,它可以像处理新事件一样轻松地处理过去的事件。
  • Kafka 的分布式特性意味着它可以水平扩展以应对海量数据,同时保持容错能力。单个 Kafka 集群可以每秒处理数百万个事件,且即使系统部分失败也能保证数据不丢失。

这些能力使得 Kafka 在各行各业中不可或缺。金融机构用它来实时处理数百万笔交易,同时确保从欺诈检测到客户通知的每个系统保持同步。制造业通过 Kafka 将成千上万台 IoT 设备的传感器数据流入系统,从而实现预测性维护和实时监控。零售业使用 Kafka 进行库存管理和订单处理。

Kafka 通过发布-订阅模型(或如 Kafka 社区所说的生产者-消费者模型)实现上述功能。生产者将消息发送到特定主题(topic),消费者按需处理这些消息。但使 Kafka 区别于传统消息系统的是其持久化层——写入 Kafka 的数据可以被多次存取,保存时长可以是数小时、数天,甚至数月。

这种持久化能力,连同 Kafka 的分布式特性及其丰富的生态工具(例如 Kafka Connect、Kafka Streams),把 Kafka 从 LinkedIn 起初的高吞吐量消息系统,发展成更强大的东西:企业数据的中枢神经系统。

本书面向希望深入理解 Kafka 及其如何与现有 IT 基础设施集成的广泛 IT 人员。无论你是架构师、系统管理员、开发者还是数据工程师,本书都为你提供一个全面的入门点。

你不应期待在此找到大量 Java 示例的开发者手册;相反,我们旨在提供清晰、实用的见解与指导,使你能够在项目中有效地使用 Kafka。我们的目标是赋予你在各种 IT 环境中使用 Kafka 进行数据流与实时处理所需的知识与技能。

1.2 Kafka 在企业生态系统中的作用

我们说 Kafka 可以成为“数据的中枢神经系统”,这是什么意思?其愿景是将每一个事件(见图 1.1)——即在企业内部发生、会产生数据并携带重要信息的重大事项或操作——都存入 Kafka。在企业系统与 Kafka 的语境中,事件通常代表组织不同部分发生的各种活动、变更或交易,例如用户交互、系统更新、金融交易或任何其他相关的业务操作。

在事件驱动架构与 Kafka 的上下文中,事件通常是一段封装了某次具体发生事项细节的数据,给该事项提供结构化的描述。这些事件通常由企业内的各个组件或应用产生并发布到 Kafka 的一个主题(topic)中——主题是组织数据流的结构单元。随后,其他系统或应用可以订阅这些主题来消费与处理这些事件,从而实现企业生态系统不同部分之间的实时数据流与通信。

在许多公司中,传统遗留系统(对现有业务流程和模型至关重要)与采用现代开发实践构建的新系统之间的分离越来越明显。所谓“新世界”指的是使用当代方法论开发创新服务与解决方案的范式。虽然要在新旧系统之间建立接口并不一定非用 Kafka 不可(这类工作常常可以通过适配器或防腐层/anti-corruption patterns 来完成),但 Kafka 在促成这些系统间通信方面扮演着关键角色。Kafka 便于消息的无缝交换,连接了既有的遗留系统与不断演进的现代软件服务。通过这种方式,它能够在不对现有系统做大规模改动的前提下,保证平滑的集成与数据流通。

image.png

遗留系统往往无法满足内部与外部客户的现代需求。这些系统通常依赖批处理,在预设的时间间隔内以大块数据进行处理。然而在当今快节奏的环境中,立即获取信息变得至关重要。例如,在信用卡交易后,没人愿意等上一周或哪怕一天才看到账户余额更新。我们现在期望实时的包裹追踪和瞬时的数据更新。以现代汽车为例,它们会产生大量数据,需要传回总部进行分析,尤其是在为自动驾驶做准备时。Kafka 可以帮助企业从面向批处理的模式过渡到实时数据处理模式。它在旧系统与实时数据处理模型之间充当强有力的桥梁,帮助公司应对对即时信息日益增长的需求,并适应不断变化的客户期望和行业趋势。虽然 Kafka 为实时处理设计,但根据具体用例,当消息处理频率较低(例如每天一次)时,Kafka 仍然可以胜任。

我们编写软件的方式也在改变。与其把越来越多的功能塞进单体服务并通过集成把这些单体互连,我们更倾向于将服务拆分为微服务。在微服务架构风格中,应用由小型、可独立部署的服务组成,这些服务通过定义良好的 API 进行通信。这种方式旨在减少团队之间的依赖、提升可扩展性,并在软件开发与部署上带来更大的灵活性。要享受微服务带来的好处,就必须实现异步的数据交换。即便某个微服务正在维护,其他服务也能继续独立工作。此外,微服务需要通信机制,使得一个服务中的数据格式可以独立演进而不影响其他服务。在这种背景下,Kafka 提供了重要支持:它是一个用于异步通信和数据流的健壮平台,使微服务能够以解耦的方式独立运行并无缝交换信息。

另一个由虚拟化和云架构普及推动的趋势是对专用硬件的需求在下降。与某些其他消息系统不同,Kafka 不需要专用设备。它可以运行在标准的、通用的硬件上,不依赖专门的容灾/故障保护设备。Kafka 的设计能够优雅地处理子系统故障。因此,即便数据中心内部出现问题,消息投递仍能保持可靠。

那么,Kafka 是如何实现这种可靠性与性能的?我们如何将 Kafka 用于具体用例,运行 Kafka 时又需要考虑哪些要点?在本书后续章节中,我们将为你回答这些问题以及更多内容。

1.3 Kafka 的架构概览

Kafka 的架构不仅仅是一个基础框架;它是一个经过深思熟虑的系统,使数据的平滑传输、存储与处理成为可能。让我们仔细看看图 1.2 中展示的 Kafka 架构,了解构成其作为分布式流处理应用核心的关键组件。

无论你是寻求全面理解的开发者,还是只是好奇其工作原理的读者,下面这些组件的探讨将阐明 Kafka 架构的组织方式及其在塑造数据流处理未来中的关键作用。

image.png

  1. 消息构成有效载荷,也称为记录(record)。它们以字节数组的形式发送,通常在底层会在发送前被分成批次处理。
  2. 生产者将消息发送到分区的 leader,并借助分区器(partitioner)自行选择要写入的分区。
  3. 主题(topic)用于将属于同一业务范畴的消息聚合在一起,可类比为数据库中的表。
  4. 分区(partition)是 Kafka 性能的支柱。主题会被划分为多个分区,以实现并行化和扩展。为了保证容错性与高可用性,分区会在不同的 broker 之间进行复制。
  5. 消费者(consumer)从 Kafka 接收并处理消息,可以从多个分区以及多个主题进行读取。
  6. 消费者组(consumer group)通过在消费者间分配分区和消息来实现并行处理与可扩展的消息消费。如果某个消费者失败,组内的其他消费者会接管其任务,从而保证容错。
  7. Broker 是 Kafka 的服务器。它们在 broker 之间均匀分配副本和任务,从而提升性能。如果某个 broker 故障,其他 broker 可接管,提高可靠性。
  8. Leader 是负责某个分区读写操作的 broker。Leader 会尽可能均匀地分布在所有 broker 之间。
  9. Follower 是从 leader 那里复制分区数据以提升系统弹性的 broker。
  10. 协调集群(Kafka Raft,简称 KRaft;此前为 ZooKeeper 集群)用于 Kafka 自身的协调。

下面通过一个示例来说明 Kafka 的各组件如何协同工作。设想一个银行处理资金转账的场景:把银行转账应用视为生产者。其职责是为每笔转账事件生成消息。这些消息就像信息包,包含来源账户、目标账户、金额和时间戳等详细信息。

这些消息并不会直接发送到最终目的地,而是被发布到名为 bank-transfers 的 Kafka 主题。可以把主题看作对相关消息的分类集合。该主题下有多个分区,每个分区处理消息子集,从而支持并行处理。在我们的例子里,不同分区可能负责不同类型或不同组别的转账。

Kafka 集群由多个 broker 组成,是该流程的骨干。broker 是存储和管理数据的服务器,它们协同工作以形成一个具有弹性和可扩展性的 Kafka 集群。每个 broker 负责一个或多个主题的分区,保证数据高效分配。

在传统的 Kafka 部署中,ZooKeeper 用于协调 broker 并管理元数据,在保证 Kafka 分布式特性方面发挥了关键作用。但在较新的版本中,Kafka 已逐步弃用 ZooKeeper,转而使用上文提到的 KRaft 协议进行内部协调。这一变化使 Kafka 能够在无需外部协调系统的情况下自行管理协调功能。

注意:ZooKeeper 向 KRaft 的迁移细节将在后续章节中更深入地讨论。当前只需了解 Kafka 已向 KRaft 过渡,以提升可扩展性与简化性。

现在说说消费者(consumers)。它们是负责从 Kafka 主题读取消息的应用或服务。为高效处理读取操作,消费者被组织成消费者组。每个消费者组可以包含多个消费者,且在同一组内每个分区只会被一个消费者消费。这样并行处理可以保证消息被快速处理。

每个分区都有一个 leader broker 和多个 follower。leader 负责处理读写操作,follower 则复制数据以实现容错。如果 leader 故障,某个 follower 会接替以保持数据流的平稳。

综合来看,当资金转账消息在 Kafka 中流转时,消费者组能够高效地处理这些消息,确保账户及时且准确地更新。Kafka 集群凭借其分布式架构与容错机制,构成了这种可靠且可扩展数据流的骨干。无论是管理 leader 与 follower、对消息进行分区,还是在 broker 间进行协调,Kafka 都能无缝地编排这场数据交响。

1.4 运行与使用 Kafka

要有效运行 Kafka,需要若干组件与先决条件。首先,需要一组可靠且配置良好的服务器来托管 Kafka 集群。集群中的每台服务器都作为一个 broker 协作,管理数据流的分布式处理。此外,需要具备低延迟、高带宽的网络基础设施,以便 Kafka broker 之间能够顺畅通信。用户必须清晰理解其数据需求,并在 Kafka 中设计合适的主题与分区来对数据进行有效组织与分发。同样重要的是,必须构建良好设计的生产者与消费者应用,以便进行实时数据的写入与处理。最后,全面的监控与管理策略对追踪 Kafka 性能并及时排查问题至关重要。成功运行 Kafka 需要配置良好的基础设施、强健的网络能力以及对 Kafka 架构与相关组件的深入理解。

自行管理 Kafka 是可行的,但不应低估其复杂性。如果想在云环境中使用 Kafka,多家云厂商提供托管型 Kafka 服务。例如 AWS 的 Amazon Managed Streaming for Apache Kafka(Amazon MSK)和 Azure HDInsight 都提供相应解决方案。此外还有专门的 Kafka 厂商,如 Confluent 和 Aiven。除这些传统 Kafka 厂商外,市场上还有一些兼容 Kafka 的替代方案,例如 Redpanda 和 WarpStream,声称能带来更好的性能、降低成本或提供额外功能。尽管这些产品看起来各有优势,但我们对它们的实践经验尚不足以给出强力推荐。需要强调的是,维护 Kafka 基础设施只是构建成功流式架构的一部分;即便使用托管服务,你的团队也仍需具备相应专业能力,才能充分发挥其价值。

提示:我们推荐 Confluent 和 Aiven,因为我们与二者都有良好经验。

除了前述基础设施组件外,运行 Kafka 还涉及特定的编程语言与工具。Kafka 本身以 Scala 与 Java 实现,因此托管 Kafka broker 的服务器需要安装 Java 运行环境(JRE)。在与 Kafka 交互、开发生产者和消费者应用时,用户通常使用 Java、Scala、Python 或其他由 Kafka 客户端支持的语言。Kafka 为多种编程语言提供官方客户端库,便于开发者将 Kafka 无缝集成到其应用中。

1.5 我们的学习路径

在接下来的章节中,我们将踏上一条全面理解 Kafka 的学习之旅,从基础概念平滑过渡到对内部复杂机制的深入剖析。书中的学习体验配以大量图示,用以直观展示 Kafka 的关键原理、架构与处理流程,帮助你更清晰地把握底层概念。无论是探索 Kafka 的分布式架构,还是深入主题、分区与 broker 的细节,本书的可视化资料都将助你加深理解。

学习方式以实践为导向,采用简洁而有效的示例,让你能够立刻上手并开始使用 Kafka。通过实际场景与循序渐进的操作说明,我们将展示如何将所学运用于构建与运行 Kafka 应用。从生产与消费消息到搭建和管理 Kafka 集群,这些示例设计得易于理解,鼓励你进行实验并通过真实操作巩固技能。借助清晰的图示与实用示例,我们将以既启发性又可直接应用于工作实践的方式,引导你攻克 Kafka 的复杂性。

总结

  • Kafka 是一个基于发布-订阅模型的强大分布式流处理平台,实现了生产者与消费者之间的无缝数据流转。
  • Kafka 在实时分析、事件溯源、日志聚合与流处理方面被广泛采用,帮助组织基于最新的数据做出决策。
  • Kafka 的架构强调容错、可扩展性与持久性,即使在系统故障情况下也能保证数据可靠传输与存储。
  • 从金融到零售、再到电信,Kafka 可用于实时欺诈检测、交易处理、库存管理、订单处理、网络监控与大规模数据流处理等场景。
  • 除核心消息系统外,Kafka 还拥有丰富生态,如 Kafka Connect 与 Kafka Streams,这些工具提供对外部系统的连接器并便于构建流处理应用,增强了 Kafka 的整体实用性。
  • Kafka 可作为多样化系统集成的中心枢纽。
  • 生产者将消息发送到 Kafka 以进行分发。
  • 消费者从 Kafka 接收并处理消息。
  • 主题用于将消息组织为通道或类别。
  • 分区用于划分主题,以实现并行与扩展。
  • Broker 是管理存储、分发与检索的 Kafka 服务器。
  • KRaft/ZooKeeper 用于协调与管理 Kafka 集群中的任务。
  • Kafka 通过复制机制保证数据弹性。
  • 通过增加 broker,Kafka 可以横向扩展。
  • Kafka 可运行在通用硬件上。
  • Kafka 使用 Java 与 Scala 实现,但也提供对其它编程语言(例如 Python)的客户端支持。