2 分钟

什么是 Kafka,以及它如何在现代系统中使用?

了解 Apache Kafka 是什么,主题和分区如何工作,以及 Kafka 在现代系统中用于实时事件、日志和数据管道的场景。

什么是 Kafka,以及它如何在现代系统中使用?

用通俗的话说的 Kafka

Apache Kafka 是一个分布式事件流平台。简单来说,它是一个共享的、持久的“管道”,允许许多系统发布关于已发生事件的事实,另一些系统可以快速、可扩展并保持顺序地读取这些事实。

团队在需要实现系统间可靠传递数据且不希望强耦合时会使用 Kafka。与一个应用直接调用另一个应用(当对方宕机或变慢时就会失败)不同,生产者将事件写入 Kafka,消费者在准备好时再读取。Kafka 会根据配置保存事件,因此系统可以从故障中恢复,甚至重新处理历史数据。

一些你会看到的术语

  • 事件 / 消息: 记录某件事情发生(例如“OrderPlaced”或“PaymentFailed”)。Kafka 用户常说“消息(message)”,但“事件(event)”更强调它表示现实世界的变化。
  • 流(Stream): 随时间连续产生的事件流。
  • 日志(Log): Kafka 将事件组织成可追加的日志——新事件被添加到末尾,读取方按自己的节奏向前移动。

本指南适合谁(你将学到什么)

本指南面向注重产品的工程师、数据人员和技术负责人,帮助建立对 Kafka 的实用心智模型。

你将学到核心构件(生产者、消费者、主题、broker)、Kafka 如何通过分区扩展、它如何存储与重放事件,以及它在事件驱动架构中的定位。我们还会覆盖常见用例、投递保证、安全基础、运维规划,以及何时 Kafka 是合适(或不合适)的工具。

核心概念:生产者、消费者、主题、Broker

把 Kafka 当作一个共享事件日志来理解最简单:应用将事件写入它,其他应用随后读取这些事件——通常是实时,有时可能是数小时或数天之后。

生产者与消费者

生产者是写入方。生产者可能会发布像“order placed”、“payment confirmed”或“temperature reading”之类的事件。生产者不会把事件直接发给特定应用——而是发给 Kafka。

消费者是读取方。消费者可能驱动仪表盘、触发发货工作流,或将数据载入分析系统。消费者决定如何处理事件,并且可按自己的节奏读取。

主题:组织事件的方式

Kafka 中的事件按主题分组,主题本质上是命名的类别。例如:

  • orders 用于订单相关事件
  • payments 用于支付事件
  • inventory 用于库存变更

某个主题会成为该类型事件的“事实来源”流,这使得多个团队可以重用相同数据,而无需为每个集成单独开发接口。

Broker 与集群

Broker 是存储事件并向消费者提供服务的 Kafka 服务器。在实际生产环境中,Kafka 以集群形式运行(多个 broker 协同工作),以处理更大流量并在单机故障时保持运行。

消费者组:在不重复工作的前提下扩展读取能力

消费者通常在一个消费者组内运行。Kafka 会将读取工作在组内分配,这样可以通过增加消费者实例水平扩展处理能力——而不必让每个实例都做相同的工作。

主题与分区如何让 Kafka 可扩展

Kafka 通过把工作拆成主题(相关事件的流)和对每个主题再拆成分区(流的更小、独立切片)来实现扩展。

分区 = 并行与吞吐量

一个只有一个分区的主题在一个消费者组内一次只能被一个消费者读取。增加分区,就能增加消费者来并行处理事件。这就是 Kafka 支持高吞吐事件流实时数据管道的方式,而无需把每个系统都变成瓶颈。

分区还能把负载分散到不同的 broker 上。不是只一台机器处理某个主题的所有写入和读取,而是多个 broker 可以托管不同的分区并共享流量。

有序性:Kafka 保证什么(不保证什么)

Kafka 保证单个分区内的有序性。如果事件 A、B、C 以该顺序写入同一分区,消费者将按 A → B → C 的顺序读取它们。

跨分区的有序性不受保证。如果你需要对某个实体(例如客户或订单)保持严格顺序,通常会确保该实体的所有事件都落到同一分区。

键决定事件去向

生产者发送事件时,可以包含一个(例如 order_id)。Kafka 使用键来将相关事件一致地路由到同一分区。这样你就能对该键获得可预测的有序性,同时让整个主题在许多分区间扩展。

副本保证数据可用

每个分区可以被复制到其他 broker。如果某个 broker 故障,保存有副本的其他 broker 可以接管。复制是 Kafka 在关键业务场景中被信任的一个重要原因:它提升了可用性并支持容错,而不要求每个应用都实现自己的故障切换逻辑。

存储、保留与重放事件

Apache Kafka 的一个关键理念是:事件不仅仅是“传递中”的,它们被写入磁盘的有序日志,消费者可以现在读取,也可以稍后读取。这使得 Kafka 不仅适合用于传输数据,还适合用于保留可追溯的历史记录。

事件是持久化的,而不仅仅在传输中

当生产者将事件发送到主题时,Kafka 会把它追加写入 broker 的存储。消费者随后按自己的节奏从该存储日志中读取。如果某个消费者宕机一小时,事件依然存在,待其恢复后可以补读。

保留:Kafka 保留数据的时长

Kafka 根据保留策略保留事件:

  • 基于时间的保留:保留事件一段设定的时间(例如 7 天)。
  • 基于大小的保留:日志达到配置的大小后,删除最旧的数据。

保留是按主题配置的,这让你可以对“审计轨迹”类主题与高流量遥测主题采取不同策略。

压缩:按键保留最新值

有些主题更像变更日志而非历史归档,例如“当前客户设置”。日志压缩会至少保留每个键的最新事件,而随时间删除被替代的旧记录。这样你可以在不无限增长的同时,保留最新状态的持久来源。

重放事件:重建状态并修复问题

因为事件会被持久保存,你可以重放它们来重建状态:

  • 从头重建搜索索引或物化视图
  • 在错误部署后通过从较早的位置重新处理来恢复服务
  • 为新消费者提供历史数据以便入门

在实践中,重放由消费者“开始读取”的位置(offset)来控制,这为团队在系统演进时提供了强大的安全网。

可靠性与容错基础

Kafka 的设计目标是即便系统部分组件失败也能保持数据流动。它通过复制、对每个分区“负责人”的明确规则,以及可配置的写入确认实现这一点。

复制:leader 与 follower(高层次)

每个主题分区有一个 leader broker 和一个或多个 follower 副本。生产者和消费者与该分区的 leader 通信。

Follower 不断复制 leader 的数据。如果 leader 宕机,Kafka 可以将一个已同步的 follower 提升为新的 leader,从而保持分区可用。

Broker 故障时会发生什么(简述)

如果某个 broker 故障,它作为 leader 托管的分区会在短时间内不可用。Kafka 的 controller(内部协调器)会检测到故障并触发这些分区的leader 选举

如果至少有一个 follower 副本较为同步,它可以接管为 leader,客户端继续生产/消费。若没有可用的同步副本,Kafka 可能会暂停写入(取决于你的配置),以避免丢失已被确认的数据。

持久性:acks 与复制因子

两个主要配置项影响持久性:

  • 复制因子(replication factor):每个分区的副本数量(例如在 3 台 broker 上有 3 份)。
  • 确认(acks):生产者认为写入成功所等待的确认级别。

概念上:

  • acks=0:生产者不等待确认——速度快,但可能丢消息。
  • acks=1:leader 确认写入——更好,但若 leader 在 follower 完成复制前宕机,最近写入可能丢失。
  • acks=all(或 -1):leader 等待所有“in-sync”副本确认——更安全,但通常稍慢。

为了减少重试时的重复,团队常将更安全的 acks 与幂等生产者和稳健的消费者处理结合使用(后面会详述)。

延迟与安全性的权衡

更高的安全性通常意味着等待更多确认并保持更多副本同步,这会增加延迟并降低峰值吞吐量。

对延迟要求更低的场景(例如遥测或点击流)可以接受偶发丢失,但支付、库存和审计日志通常值得为更高安全性付出代价。

Kafka 在事件驱动架构中的角色

快速搭建 Kafka 演示
通过一次聊天式构建,把你对 Kafka 的设想变成可运行的生产者/消费者应用。

事件驱动架构(EDA)是一种构建系统的方式:业务发生的事件(订单下达、支付确认、包裹发货等)以事件的形式表示,系统的其他部分可以对这些事件作出反应。

发布事件,消费者响应

Kafka 常位于 EDA 的中心,作为共享的“事件流”。服务 A 不再直接调用服务 B,而是将事件(例如 OrderCreated发布到 Kafka 主题。任意数量的其他服务可以消费该事件并采取行动——发送邮件、预留库存、启动风控——而服务 A 无需知道这些消费者的存在。

松耦合(更少的直接依赖)

服务通过事件通信后,就不需要为每次交互都协调请求/响应 API。这降低了团队间的强依赖,也便于新增功能:你可以为已有事件增加一个新消费者,而无需修改生产者代码。

异步工作流与抗突发能力

EDA 本质上是异步的:生产者快速写入事件,消费者按自己的节奏处理。在流量峰值期间,Kafka 可以充当缓冲,防止下游系统瞬间崩溃。消费者可以扩展以赶上积压,如果某个消费者暂时宕机,恢复后可以从中断处继续处理。

一个实用的心智模型

把 Kafka 想象成系统的“活动订阅流”。生产者发布事实;消费者订阅它们关心的事实。该模式支持实时数据管道和事件驱动工作流,同时让服务更简洁、独立。

现代系统中常见的 Kafka 使用场景

当团队需要在系统间快速、可靠地传递大量小事件,且希望多个消费者复用同一数据时,Kafka 常常出现。

活动追踪与审计日志

应用常需要一个追加写入的历史:用户登录、权限变更、记录更新或管理员操作。Kafka 适合做这些事件的中央流,安全工具、报表和合规导出可以读取同一来源,而不会增加生产数据库负载。由于事件被保留,你也可以在发生 bug 或模式变更后重放它们来重建审计视图。

微服务通过事件通信

服务可以发布“order created”或“payment received”这类事件,其他服务订阅并在各自时间点作出反应。这降低了耦合,有助于在部分故障时保持系统工作,并让新增能力(例如风控)更容易通过消费现有流来接入。

到分析与仓库的数据管道

Kafka 是将数据从运营系统流向分析平台的常见骨干。团队可以实时地把应用数据库的变更流式传输并交付到仓库或数据湖,同时将生产应用与繁重的分析查询隔离开来。

面对突发流量的 IoT 与遥测

传感器、设备和应用遥测数据常常出现突发流量。Kafka 可以吸收突发、对其进行缓冲,并让下游处理系统逐步追赶——适用于监控、告警和长期分析场景。

Kafka 生态:Connect、Streams 与工具链

Kafka 不只是 broker 与主题。大多数团队依赖配套工具来使 Kafka 在日常数据移动、流处理和运维中可用。

Kafka Connect:无需自写代码也能搬运数据

Kafka Connect 是 Kafka 的集成框架,用来把数据导入Kafka(source)或从 Kafka 导出(sink)。你不必为每个连接写维护成本高的一次性管道,只需运行 Connect 并配置连接器。

常见示例包括从数据库拉取变更、摄取 SaaS 事件,或将 Kafka 数据交付到数据仓库或对象存储。Connect 还规范化了重试、offset 管理和并行度等运维关注点。

Kafka Streams:在你的应用内做实时计算

如果 Connect 用于集成,Kafka Streams 则用于计算。它是一个库,你将其加入应用中以实时转换流——过滤事件、富化、流间连接、构建聚合(例如“每分钟订单数”)。

Streams 应用从主题读取并写回主题,天然适配事件驱动系统,并且可以通过增加实例来扩展。

模式管理:保持事件一致性

当多个团队发布事件时,一致性很重要。通过模式管理(通常使用 schema registry)定义事件应该包含哪些字段以及如何演进,能防止生产者重命名字段而破坏消费者的情形。

工具链:监控关键指标

Kafka 对运维敏感,因此基本监控是必需的:

  • 消费者滞后(consumer lag):消费者是否落后?
  • 吞吐量:每秒流过多少事件?
  • 错误:拉取失败、生产错误、连接器任务失败

大多数团队还会使用管理型 UI 与自动化来做部署、主题配置和访问控制策略(参见 /blog/kafka-security-governance)。

投递保证与处理模式

搭建生产者与消费者骨架
让 Koder.ai 围绕你的 Kafka 主题搭建服务骨架,然后迭代细节。

常说 Kafka 是“持久化日志 + 消费者”,但团队更关心的问题通常是:我能否对每个事件只处理一次,出现故障时会怎样?Kafka 提供构建模块,由你在这些模块上权衡取舍。

投递保证(高层次)

至多一次(at-most-once) 意味着你可能会丢失事件,但不会处理重复。这可能发生在消费者先提交位置然后在完成工作前崩溃的情形。

至少一次(at-least-once) 意味着不会丢失事件,但可能产生重复(例如消费者处理了事件后崩溃,重启后会再次处理)。这是最常见的默认模式。

正好一次(exactly-once) 旨在端到端避免丢失和重复。在 Kafka 中,这通常涉及事务性生产者和兼容的处理(通常通过 Kafka Streams)。这很强大,但更有约束,需要谨慎设置。

幂等与去重

实际上,许多系统接受至少一次语义并添加保护措施:

  • 幂等写入:使“应用事件”步骤可重复(例如 upsert、有条件更新、唯一键)。
  • 去重:存储事件 id(或业务键),在窗口内忽略重复。

消费者 offset:你的“书签”

消费者 offset 是分区中最后处理记录的位置。当你提交 offset,就表示“我已处理到这里”。

提交太早会有丢失风险;提交太晚会在故障后造成重复处理。

重试与毒性消息

重试应有限且可见。常见模式是:

  1. 对瞬时错误进行退避重试,
  2. 若仍失败则把出错记录发送到**死信主题(dead-letter topic)**以便检查与重放。

这样可以防止单条“毒性消息”阻塞整个消费者组,同时保留数据以供修复。

安全与治理考虑

Kafka 常承载业务关键事件(订单、支付、用户行为),因此安全与治理必须从设计阶段就考虑,而不是事后补救。

认证与授权

认证回答“你是谁?”,授权回答“你可以做什么?”。在 Kafka 中,认证常用 SASL(例如 SCRAM 或 Kerberos),授权通过 ACL(访问控制列表)在主题、消费者组和集群级别强制执行。

一个实用做法是最小权限:生产者仅能写入其拥有的主题,消费者仅能读其所需主题。这样可以减少意外数据泄露并限制凭证泄露时的影响范围。

传输加密(TLS)

TLS 对应用、broker 与工具之间传输的数据进行加密。没有 TLS,事件在内部网络中也可能被拦截,而不仅仅是在公网上。TLS 同时通过验证 broker 身份来防止中间人攻击。

多租户 Kafka 与命名规范

当多个团队共享集群时,需要设置护栏。清晰的主题命名规范(例如 <team>.<domain>.<event>.<version>)能让归属更明显,并帮助工具一致地施加策略。

将命名与配额和 ACL 模板配合使用,防止某个高噪工作负载挤占资源,并为新服务提供安全默认值。

数据治理:PII、保留与合规

只有在打算把 Kafka 当作事件历史的记录系统时才这样做。如果事件包含 PII,应采取数据最小化(发送 ID 而不是完整档案)、考虑字段级加密,并记录哪些主题含敏感数据。

保留设置应符合法律和业务要求。如果策略要求“30 天后删除”,就不要“以防万一”保留 6 个月的事件。定期审查与审计可使配置随系统演进保持一致。

运行 Kafka:团队需要规划的事项

添加 DLQ 工作流
创建小型应用处理毒性消息并审查失败,而不阻塞消费者。

运行 Apache Kafka 不是“装上就忘”。它更像一项共享公用设施:许多团队依赖它,且小失误可能波及下游应用。

容量规划基础

Kafka 的容量本质上是一个需要定期复盘的数学问题。最大杠杆在于分区数(并行度)、吞吐量(进/出 MB/s)和存储增长(保留时长)。

如果流量翻倍,你可能需要更多分区来将负载分散到更多 broker、更大的磁盘来保持保留、以及更多网络带宽来支持复制。一个实用习惯是预测峰值写入率并乘以保留期来估算磁盘增长,然后为复制和“意外成功”留出缓冲。

日常运维任务

除了保证服务器在线外,还应预期例行工作:

  • 升级: 规划滚动升级,测试客户端兼容性,并在流量最低时安排变更。
  • 重均衡: 消费者组重均衡可能会引起短暂暂停;需要安全的部署模式和明确的归属。
  • 事故响应: 为 broker 故障、磁盘满、以及配置错误导致的生产者大量写入等情况准备运行手册。

成本驱动因素与部署选择

成本由磁盘网络出口流量以及 broker 的数量/规格驱动。托管 Kafka 可以降低运维人员开销并简化升级,而自托管在有经验的运维团队时在规模化下可能更便宜。权衡点在于恢复时间和值班负担。

该测量什么(避免猜测)

团队通常会监控:

  • 端到端延迟(从生产到消费)
  • 消费者滞后(消费者落后多少)
  • Broker 健康(磁盘使用、未复制分区、请求错误率)

良好的看板和告警能把 Kafka 从“黑盒”变成可理解的服务。

何时使用 Kafka(以及何时不该用)

当你需要可靠传输大量事件、保留一段时间,并允许多个系统以自己的节奏对同一数据流作出反应时,Kafka 非常适合。它在需要重放(回补、审计或为新服务重建状态)且预期会增加生产者/消费者的场景中特别有用。

适合选择 Kafka 的场景

Kafka 在以下场景通常表现优秀:

  • 高吞吐的事件流(点击、订单、传感器数据)
  • 许多消费者需要相同事件(分析、监控、风控、通知)
  • 需要重放与长期历史作为特性,而不仅仅是“投递一次后忘记”
  • 需要解耦团队和服务的集成工作

Kafka 可能过重的情况

如果需求简单,Kafka 可能显得大材小用:

  • 两个服务之间的单一低流量队列
  • 短期任务(后台作业),重放价值不大
  • 团队没有时间去运维和监控分布式系统

在这些情况下,集群尺寸、升级、监控和值班的运维开销可能超过其带来的收益。

备选与互补方案

  • RabbitMQ: 适合传统的工作队列与路由模式。
  • NATS: 轻量级消息系统,延迟低。
  • 云端 pub/sub: 想要托管基础设施和更简单运维时的好选择。

Kafka 也通常与而非替代 数据库(事实系统)、缓存(快速读取)与 批量 ETL 工具(大规模周期性转换)一起使用。

快速决策清单

问自己:

  1. 我们是否需要多个消费者并且需要重放?
  2. 吞吐量会明显增长吗?
  3. 我们是否将事件历史/保留作为一项功能?
  4. 我们能否承担运维责任(或使用托管 Kafka)?
  5. 我们是在流式传输事件,而不仅仅是在发送命令/任务?

若对以上多数问题回答“是”,Kafka 通常是个合适的选择。

入门:简单的采用路径

当你需要一个共享的“事实来源”用于实时事件流时,Kafka 最合适:许多系统产生事实(订单创建、支付授权、库存变更),许多系统消费这些事实以驱动管道、分析和响应特性。

第 1 步:选一个明确的具体用例

从一个窄而有价值的流程开始——例如发布“OrderPlaced”事件供下游服务(邮件、风控、履单)使用。避免在第一天就把 Kafka 当成万能队列。

第 2 步:定义你的事件与主题

写下:

  • 事件:发生了什么,用业务术语描述
  • 主题:事件存放在哪里(通常按事件类型或领域划分)
  • 消费者:哪些团队/服务需要这些事件,以及为什么

保持初期 schema 简单且一致(时间戳、ID、清晰的事件名)。决定是立即强制执行 schema 还是在演进中小心演化。

第 3 步:确立归属与基本运维规则

Kafka 成功的关键在于有人负责:

  • 主题创建与命名规范
  • 保留与访问策略
  • 值班职责与运行手册

立即添加监控(消费者滞后、broker 健康、吞吐、错误率)。如果没有专门的平台团队,建议先使用托管服务并设定清晰的限制。

第 4 步:构建“瘦”管道的第一个版本

从一个系统生产事件,在一个地方消费它,验证端到端闭环工作。然后再扩展到更多消费者、更多分区与更多集成。

如果你想快速把想法做成可运行的事件驱动服务,像 Koder.ai 这样的工具可以帮助你快速原型周边应用(React 前端、Go 后端、PostgreSQL),并通过聊天驱动的工作流逐步为应用增加 Kafka 生产者/消费者。它在构建内部仪表盘和轻量级消费主题服务时尤其有用,带有规划模式、源码导出、部署/托管以及快照回滚等功能。

如果你要把它映射到事件驱动方法论,请参见 /blog/event-driven-architecture。若要规划成本与环境,请查看 /pricing。

常见问题

用通俗的话说,什么是 Apache Kafka?

Kafka 是一个分布式事件流平台,它将事件以持久的、追加写入的日志形式保存。

生产者将事件写入主题,消费者独立读取(通常是实时,也可以稍后),因为 Kafka 会根据配置保留数据一段时间。

什么时候团队应选择 Kafka 而不是直接的服务间调用?

当多个系统需要同一事件流、希望降低耦合,或需要能重放历史时,使用 Kafka。

它尤其适合:

  • 事件驱动的微服务(发布事实,异步响应)
  • 实时数据管道到分析/仓库
  • 活动跟踪、审计日志、以及面对突发流量的遥测数据
主题和分区有什么区别?

主题是事件的命名类别(如 orderspayments)。

分区是主题的切片,用来实现:

  • 更高的吞吐量(写/读分散到不同 broker)
  • 并行消费(消费者组内的多个实例)

Kafka 只保证单个分区内的有序性。

键如何影响排序和扩展?

Kafka 使用记录键(例如 order_id)将相关事件稳定路由到同一分区。

实用规则:如果你需要按实体的严格顺序(例如某个订单/客户的所有事件按顺序),就为该实体选择一个键,确保这些事件落到同一分区。

什么是消费者组?为什么重要?

消费者组是一组共享某个主题消费工作的消费者实例。

在一个组内:

  • 每个分区在同一时间最多由一个实例处理
  • 增加实例可以提高并行度,但上限受分区数限制

如果两个不同的应用都需要接收同一事件的全部副本,它们应使用不同的消费者组。

Kafka 会保存多长时间的数据?保留(retention)用于什么?

Kafka 根据主题策略将事件在磁盘上保留一段时间,让消费者能在停机后追赶或重处理历史数据。

常见保留方式:

  • 基于时间(保留 N 天)
  • 基于大小(日志达到 N GB 后删除最旧数据)

保留是按主题配置的,因此可以对审计类流和高吞吐量遥测流设不同策略。

什么是日志压缩?什么时候比普通保留更好?

日志压缩(log compaction)会保留每个键的至少最新记录,逐步删除被更替的旧记录。

当你关心的是“当前状态”的最新值(例如设置或配置项),而不是每次变更的历史时,压缩比普通按时间/大小的保留更合适——它在保证最新状态持久性的同时避免无限增长。

Kafka 能否实现事件的“正好一次”投递?

Kafka 最常见的端到端模式是至少一次(at-least-once):不会丢失事件,但可能产生重复。

为安全处理:

  • 让消费者幂等(重复应用事件不会产生错误)
  • 使用唯一事件 ID 或业务键在需要时去重
  • 在完成工作后再提交 offset,以降低丢失风险
什么是消费者 offset?重试和死信主题如何搭配使用?

Offset 是消费者在分区中的“书签”。

如果提前提交 offset,发生崩溃时可能丢失未完成的工作;提交太晚则会在恢复后重复处理,产生重复记录。

常见实践是有限次重试并退避,然后将失败记录发送到死信主题(dead-letter topic),避免单条“毒性消息”阻塞整个消费者组。

什么是 Kafka Connect 和 Kafka Streams?应该分别在什么时候使用?

Kafka Connect 用连接器(source、sink)在 Kafka 与其他系统之间搬运数据,减少自写管道代码的需求。

Kafka Streams 是一个库,用于在应用内部实时处理流(过滤、连接、聚合、富化),读取主题并将结果写回主题。

一般来说:Connect 用于集成,Streams 用于计算。

Related posts