news 2026/5/3 6:50:28

Kafka 基础:从消息队列到事件流平台

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kafka 基础:从消息队列到事件流平台

学习目标

  1. 能说清 Kafka 是什么、适合什么、不适合什么。
  2. 能解释 broker、topic、partition、offset、consumer group 的关系。
  3. 能用命令创建 topic、发送消息、消费消息、查看消费组状态。

Kafka 是什么

Kafka 是一个分布式事件流平台。它表面上像消息队列,但核心模型不是“把消息投递给某个消费者后立刻删除”,而是“把事件追加写入一个可持久化、可分区、可复制的日志中,消费者按 offset 自己读取”。

这带来几个关键差异:

对比项普通队列视角Kafka 事件流视角
数据生命周期消费后通常删除按保留策略保存,可回放
消费进度队列维护投递状态消费者组维护 offset
扩展方式增加队列或消费者增加 partition、broker、consumer
典型能力异步解耦异步解耦 + 数据总线 + 回放 + 流计算

Kafka 适合什么

Kafka 适合高吞吐、可回放、多订阅方、事件流式处理的场景:

  • 订单事件:订单创建后,库存、积分、优惠券、风控系统分别订阅。
  • 用户行为日志:Web/App 埋点进入 Kafka,再进入实时计算、数据湖、画像系统。
  • 数据同步:业务数据库变更通过 CDC 写入 Kafka,再分发到搜索、缓存、数仓。
  • IoT 上报:设备持续上报状态,Kafka 接住洪峰,后端服务按能力处理。
  • 实时指标:实时计算 UV、PV、支付成功率、异常告警。

Kafka 不适合什么

Kafka 不是所有队列场景的默认答案:

不适合场景原因替代思路
极低延迟 RPCKafka 是日志系统,不是请求响应框架HTTP/gRPC
复杂任务调度Kafka 不负责延迟队列、任务状态机、重试编排Quartz、XXL-JOB、Temporal
小团队简单异步运维成本可能高于收益Redis Stream、RabbitMQ、云队列
强事务跨系统一致性Kafka 事务只覆盖 Kafka 内部和部分生产者语义本地事务表、Saga、Outbox

核心组件

Broker

Broker 是 Kafka 服务节点。一个 Kafka 集群由多个 broker 组成。每个 broker 存储若干 partition 的日志数据,处理客户端读写请求,并参与副本复制。

Topic

Topic 是消息分类。比如:

  • order-events:订单事件。
  • payment-events:支付事件。
  • user-behavior:用户行为日志。

Topic 不是一个单文件队列,而是由多个 partition 组成。

Partition

Partition 是 Kafka 扩展吞吐和并行消费的基本单位。每个 partition 内部是有序追加日志;不同 partition 之间不保证全局顺序。

如果 topic 有 6 个 partition,一个消费组最多可以让 6 个消费者实例并行消费。第 7 个消费者会空闲,因为同一个消费组内,一个 partition 同一时刻只能分配给一个消费者。

Offset

Offset 是消息在 partition 内的位置编号。消费者提交 offset 表示“我已经处理到哪里”。Kafka 保存的是日志,消费者保存的是进度。

Consumer Group

Consumer Group 是一组共同消费某个 topic 的消费者。不同消费组之间互不影响,都会读到同一份消息。

例子:

  • inventory-service消费组处理库存。
  • coupon-service消费组处理优惠券。
  • risk-service消费组处理风控。

三者都订阅order-events,但各自维护自己的 offset。

Kafka 架构关系

Producer

Topic: order-events

Partition 0

Partition 1

Partition 2

Broker 1

Broker 2

Broker 3

Consumer A / group inventory

Consumer B / group inventory

Consumer C / group risk

第一组实操:启动 Kafka 并收发消息

进入 CLI demo:

cdkafka-knowledge-system/demos/cli-kafka-labdockercompose up-ddockercomposeps

创建 topic:

dockercomposeexeckafka kafka-topics\--bootstrap-server localhost:9092\--create\--topicorder-events\--partitions3\--replication-factor1

查看 topic:

dockercomposeexeckafka kafka-topics\--bootstrap-server localhost:9092\--describe\--topicorder-events

发送消息:

dockercomposeexec-Tkafka kafka-console-producer\--bootstrap-server localhost:9092\--topicorder-events<<'EOF' {"orderId":"O1001","status":"CREATED","amount":99.8} {"orderId":"O1002","status":"PAID","amount":199.0} EOF

消费消息:

dockercomposeexeckafka kafka-console-consumer\--bootstrap-server localhost:9092\--topicorder-events\--from-beginning\--grouporder-demo-group\--timeout-ms5000

查看消费组:

dockercomposeexeckafka kafka-consumer-groups\--bootstrap-server localhost:9092\--describe\--grouporder-demo-group

验证标准

验证项命令预期结果
Kafka 正常启动docker compose pskafka状态为 running
Topic 创建成功kafka-topics --describe能看到 3 个 partition
消息写入成功console producer无报错
消息消费成功console consumer能打印 JSON 消息
Offset 已提交kafka-consumer-groups --describeCURRENT-OFFSET大于 0

常见误区

  1. 认为 topic 有序。准确说法是:partition 内有序,topic 级别默认不保证全局有序。
  2. 认为消息消费后删除。准确说法是:Kafka 按保留时间或大小删除,与是否消费无直接关系。
  3. 认为消费者越多越快。准确说法是:同一消费组内并行度上限受 partition 数量限制。
  4. 认为 Kafka 一定不丢消息。准确说法是:可靠性取决于 producer ack、broker 副本、consumer offset 提交策略。

02 Topic、分区、生产者和消费者

本章目标

本章解决 Kafka 日常开发最常见的问题:

  • Topic 应该怎么设计。
  • Partition 数量怎么估算。
  • Producer 如何保证顺序、吞吐和不丢。
  • Consumer 如何控制并发、提交 offset、处理失败。

Topic 设计

Topic 是事件类型边界,不是业务表的简单复制。一个好 topic 应该表达事件语义,而不是表达某个方法调用。

推荐命名:

命名含义说明
order-events订单领域事件包含 CREATED、PAID、CANCELLED
payment-events支付领域事件支付成功、失败、退款
user-behavior-events用户行为事件点击、曝光、搜索
inventory-commands库存命令如果明确是命令而不是事实事件

不推荐命名:

命名问题
test无业务语义,难治理
service-a-to-service-b强耦合两个服务
order-table容易把 Kafka 当数据库同步表
all-eventsSchema 混乱,权限和保留策略难控制

事件建模示例

订单创建事件建议带上事件 ID、业务 ID、事件类型、版本和发生时间:

{"eventId":"EVT-20260502-0001","eventType":"ORDER_CREATED","eventVersion":1,"occurredAt":"2026-05-02T20:30:00+08:00","orderId":"O1001","userId":"U1","amount":99.8,"status":"CREATED"}

字段设计要点:

  • eventId:用于幂等处理和排查。
  • eventType:一个 topic 可以承载同一领域内多个事件类型。
  • eventVersion:用于兼容升级。
  • occurredAt:事件真实发生时间,不等于 Kafka 写入时间。
  • orderId:适合作为消息 key,保证同一订单进入同一 partition。

Partition 设计

Partition 决定并行度、吞吐、顺序边界和未来扩展成本。

Partition 数量估算

简单公式:

partition_count = max(目标写入吞吐 / 单分区写入吞吐, 目标消费吞吐 / 单消费者吞吐)

例子:

  • 峰值写入:60 MB/s。
  • 单 partition 稳定写入:10 MB/s。
  • 单消费者处理:5 MB/s。
  • 目标消费者并行度:12。

则 topic 至少需要:

max(60 / 10, 60 / 5) = max(6, 12) = 12 个 partition

实际生产中还要给未来增长留空间,例如设置为 18 或 24。

Partition 过多的问题

Partition 不是越多越好:

  • 文件句柄和日志段数量增加。
  • leader election 更慢。
  • Controller 元数据压力更大。
  • Consumer rebalance 时间变长。
  • 小流量 topic partition 过多会浪费资源。

消息 Key 与顺序

Kafka 只保证同一个 partition 内有序。生产者发送消息时,如果指定 key,默认分区器会根据 key 哈希选择 partition。

如果要保证同一订单的状态事件顺序:

key = orderId topic = order-events

这样O1001CREATED -> PAID -> SHIPPED会进入同一个 partition。

注意:如果后期增加 partition,同一个 key 的哈希结果可能变化,只能保证变更后新消息进入新规则下的 partition,不能保证跨变更的全局顺序连续。

Producer 核心配置

配置推荐值作用
acksall等待 leader 和 ISR 副本确认,提高可靠性
enable.idempotencetrue开启幂等生产,避免重试导致重复写入
retries较大值可恢复错误自动重试
delivery.timeout.ms业务可接受范围发送总超时时间
linger.ms5-50等待更多消息组成批次,提高吞吐
batch.size32KB-128KB 起调批次大小
compression.typelz4zstd降低网络和磁盘压力

可靠生产者配置示例:

spring.kafka.producer.acks=all spring.kafka.producer.retries=10 spring.kafka.producer.properties.enable.idempotence=true spring.kafka.producer.properties.delivery.timeout.ms=120000 spring.kafka.producer.properties.linger.ms=10 spring.kafka.producer.properties.batch.size=65536 spring.kafka.producer.properties.compression.type=lz4

Consumer 核心配置

配置推荐值作用
enable.auto.commitfalse手动提交,避免处理失败但 offset 已提交
auto.offset.resetearliestlatest无 offset 时从哪里开始读
max.poll.records业务处理能力内单次拉取数量
max.poll.interval.ms大于单批最大处理时间防止处理慢被踢出消费组
session.timeout.ms10-30s心跳会话超时
partition.assignment.strategycooperative sticky降低再均衡影响

手动提交的基本原则:

拉取消息 -> 执行业务处理 -> 业务处理成功 -> 提交 offset

如果顺序反了:

拉取消息 -> 提交 offset -> 执行业务处理

业务处理失败时,Kafka 会认为消息已经处理完,造成业务丢失。

消费失败处理策略

策略适用场景风险
立即重试网络抖动、临时数据库失败可能阻塞 partition
有限次重试大多数业务异常需要记录失败原因
死信队列 DLT无法处理的脏数据需要补偿流程
跳过并告警非核心日志类消息可能丢业务语义
暂停消费下游故障、避免雪崩堆积增长,需要容量预案

Spring Kafka 中常用DefaultErrorHandler配合DeadLetterPublishingRecoverer。本包项目 demo 已实现失败重试和 DLT。

再均衡 Rebalance

Rebalance 是消费组内 partition 分配关系发生变化的过程。触发场景:

  • 消费者实例新增或退出。
  • 消费者心跳超时。
  • topic partition 数量变化。
  • 订阅 topic 变化。

Rebalance 期间,部分 partition 会暂停消费。生产环境要降低频繁 rebalance:

  • 处理逻辑不要阻塞太久。
  • 合理设置max.poll.interval.ms
  • 使用静态成员 ID:group.instance.id
  • 使用 cooperative sticky 分配策略。
  • 优雅停机,让消费者主动退出。

实操:观察消费组和分区分配

创建 3 分区 topic:

dockercomposeexeckafka kafka-topics\--bootstrap-server localhost:9092\--create\--if-not-exists\--topicpartition-lab\--partitions3\--replication-factor1

启动第一个消费者:

dockercomposeexeckafka kafka-console-consumer\--bootstrap-server localhost:9092\--topicpartition-lab\--grouppartition-group\--propertyprint.partition=true\--propertyprint.offset=true

再打开第二个终端启动第二个消费者,观察两个消费者分配 partition 的变化:

dockercomposeexeckafka kafka-console-consumer\--bootstrap-server localhost:9092\--topicpartition-lab\--grouppartition-group\--propertyprint.partition=true\--propertyprint.offset=true

发送带 key 的消息:

dockercomposeexeckafka kafka-console-producer\--bootstrap-server localhost:9092\--topicpartition-lab\--propertyparse.key=true\--propertykey.separator=:

输入:

O1001:created O1001:paid O2001:created O2001:paid

验证点:相同 key 通常进入同一个 partition,同一个 partition 内 offset 递增。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/3 6:32:16

AI代码生成质量守卫:eslint-plugin-ai-guard实战指南

1. 项目概述&#xff1a;当AI代码生成遇上ESLint 最近在团队里做Code Review&#xff0c;发现一个挺有意思的现象&#xff1a;随着各种AI编程助手&#xff08;比如GitHub Copilot、Cursor、Codeium&#xff09;的普及&#xff0c;提交的代码里开始出现一些“风格统一但逻辑诡异…

作者头像 李华
网站建设 2026/5/3 6:11:34

手把手教你用Gazebo+ROS搭建Livox Mid360仿真平台,解决FAST-LIO2测试难题

从零构建Livox Mid360仿真平台&#xff1a;GazeboROS实战指南 当硬件成为算法开发的瓶颈时&#xff0c;仿真技术往往能打开另一扇窗。Livox Mid360作为一款高性能激光雷达&#xff0c;在SLAM和机器人感知领域备受青睐&#xff0c;但其高昂的价格和供货不稳定让许多开发者望而却…

作者头像 李华
网站建设 2026/5/3 6:07:15

RDPWrap完全指南:免费解锁Windows多用户远程桌面终极教程

RDPWrap完全指南&#xff1a;免费解锁Windows多用户远程桌面终极教程 【免费下载链接】rdpwrap RDP Wrapper Library 项目地址: https://gitcode.com/gh_mirrors/rd/rdpwrap 你是否曾经因为Windows家庭版或专业版的远程桌面限制而感到困扰&#xff1f;想象一下这样的场景…

作者头像 李华
网站建设 2026/5/3 6:06:46

AI智能体如何利用向量化技术构建Markdown文档知识库

1. 项目概述&#xff1a;当AI智能体遇上Markdown文档最近在折腾AI智能体&#xff08;Agent&#xff09;相关的项目&#xff0c;发现一个挺有意思的现象&#xff1a;很多开发者习惯用Markdown来写项目文档、技术笔记&#xff0c;甚至是任务规划。但Markdown文档一旦多了&#xf…

作者头像 李华