Kafka

Kafka 架构与消息模型 Kafka 是持久化的分布式事件流平台,常用于日志汇聚、异步解耦、数据管道和流处理。 Broker:存储分区数据并处理生产、消费请求。 Topic / Partition:Topic 是逻辑消息流,Partition 是存储和并行处理单元。 Producer:按指定分区、

Kafka

架构与消息模型

Kafka 是持久化的分布式事件流平台,常用于日志汇聚、异步解耦、数据管道和流处理。

Kafka 的生产者与消费者

  • Broker:存储分区数据并处理生产、消费请求。
  • Topic / Partition:Topic 是逻辑消息流,Partition 是存储和并行处理单元。
  • Producer:按指定分区、消息 key 或分区器选择目标分区。
  • Consumer Group:同组消费者分担分区,不同组独立消费;传统消费组内,一个分区同时只分配给一个消费者。
  • Controller:维护元数据与分区领导关系。KRaft 使用 Raft 元数据仲裁组;Kafka 4.x 已移除 ZooKeeper 模式。
  • Kafka Connect / Streams:分别负责外部系统连接和应用内流处理,不是 Broker 必须附带的组件。

Topic 与分区

消息包含 key、value、timestamp、headers 等信息。每个分区内的 offset 单调递增,但不保证连续;消息顺序只在单个分区内成立。增加分区数可能改变 key 的分区映射,需评估同 key 顺序要求。

消费者提交的 offset 表示下一条待消费的位置。消息保留由时间、空间或日志压缩策略决定,与是否被消费无关。cleanup.policy=compact 保留每个 key 的最新状态,不能当作普通事件归档策略。

副本数不等于能无条件容忍的故障数。可用性还取决于 ISR、min.insync.replicas、leader 选举策略和 KRaft quorum;不要开启非同步副本选主来换取未评估的数据丢失。

Docker Compose 单节点实验

下面使用固定的 Kafka 3.9.1 KRaft 镜像,Broker 与 Controller 合并运行,适合本机验证。生产应选择经过兼容测试且仍受支持的补丁版本,并部署独立故障域与多个控制节点。

保存为 compose.yaml:

services:
  kafka:
    image: apache/kafka:3.9.1
    hostname: kafka
    ports:
      - "127.0.0.1:9092:9092"
    environment:
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: INTERNAL://:29092,EXTERNAL://:9092,CONTROLLER://:9093
      KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka:29092,EXTERNAL://localhost:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
      KAFKA_LOG_DIRS: /var/lib/kafka/data
    volumes:
      - kafka-data:/var/lib/kafka/data
volumes:
  kafka-data:
docker compose config -q
docker compose up -d
docker compose logs --tail=100 kafka
docker compose exec kafka /opt/kafka/bin/kafka-topics.sh \
  --bootstrap-server kafka:29092 --create \
  --topic quickstart-events --partitions 3 --replication-factor 1
printf 'first event\nsecond event\n' | docker compose exec -T kafka \
  /opt/kafka/bin/kafka-console-producer.sh \
  --bootstrap-server kafka:29092 --topic quickstart-events
docker compose exec kafka /opt/kafka/bin/kafka-console-consumer.sh \
  --bootstrap-server kafka:29092 --topic quickstart-events \
  --group demo --from-beginning --max-messages 2

容器内客户端使用 kafka:29092,宿主机客户端使用 localhost:9092。远程客户端需要同时修改端口绑定、防火墙和 EXTERNAL 通告地址,并配置 TLS/SASL;只修改监听地址不能解决返回元数据后的连接失败。保留数据卷,不要用删除卷来处理普通启动故障。

消费语义与可靠性

  • 生产集群常用 3 副本、min.insync.replicas=2、acks=all,并显式启用生产者幂等;ISR 不足时写入失败是保护行为。
  • 生产者幂等可避免客户端重试在 Kafka 内造成重复,但不替代业务去重;消费者应在业务处理成功后提交 offset。
  • 先提交再处理可能丢消息,先处理再提交可能重复。数据库写入应使用幂等键、唯一约束或可靠事务边界。
  • Kafka 事务结合 isolation.level=read_committed 可覆盖 Kafka 内的读写链路,不能自动保证外部数据库或 HTTP 调用恰好执行一次。
  • 批量、压缩、linger.ms 与 batch.size 影响吞吐和延迟;按真实消息大小、峰值和延迟目标测试。

常用管理与排障

在以下命令中,kafka:29092 是本例容器内地址,生产环境添加认证配置文件参数。

docker compose exec kafka /opt/kafka/bin/kafka-topics.sh \
  --bootstrap-server kafka:29092 --describe --topic quickstart-events
docker compose exec kafka /opt/kafka/bin/kafka-consumer-groups.sh \
  --bootstrap-server kafka:29092 --describe --group demo
docker compose exec kafka /opt/kafka/bin/kafka-metadata-quorum.sh \
  --bootstrap-server kafka:29092 describe --status

重置消费位点前停止组内消费者,先用 --dry-run 查看计划,再明确使用 --execute。重置可能导致重复处理或跳过消息,必须记录原位点和业务补偿方式。

现象 检查方向
bootstrap 地址可连但生产/消费超时 检查每个 Broker 的 advertised.listeners、DNS、证书和网络路由
消费 lag 持续增长 检查处理耗时、分区倾斜、rebalance、批量和下游数据库;超过分区数再加消费者不会增加该组并行度
分区副本不足 检查 Broker 状态、磁盘、网络与 ISR;不要直接降低可靠性参数掩盖故障
消息过期无法消费 检查保留时间、保留容量和消费停机窗口,按业务恢复或重放
经常 rebalance 检查 max.poll.interval.ms、处理批量、心跳、发布频率和成员变动

Prometheus 监控

Kafka exporter 主要提供分区和消费组指标;Broker JVM、请求延迟和控制器指标需另外通过 JMX exporter 等采集。Blackbox exporter 只做探测,不能替代 Kafka 协议和消费组监控。

scrape_configs:
  - job_name: kafka-exporter
    static_configs:
      - targets: ["192.0.2.10:9308"]
常见 exporter 指标 含义
kafka_brokers Broker 数量
kafka_topic_partitions Topic 分区数
kafka_topic_partition_current_offset 分区最新 offset
kafka_topic_partition_oldest_offset 分区最旧 offset
kafka_topic_partition_in_sync_replica ISR 副本数量
kafka_topic_partition_under_replicated_partition 分区是否副本不足
kafka_consumergroup_current_offset 消费组已提交位点
kafka_consumergroup_lag 消费组相对日志末尾的消息条数差

指标名与标签以实际 exporter 版本的 /metrics 为准。Lag 是条数差,不是时间延迟;无提交记录的组和未发现的组也不一定有时序。告警同时覆盖抓取失败、离线分区、ISR 缩减、磁盘水位、控制器 quorum、消费延迟与业务端到端延迟。

安全、升级与备份

生产使用 TLS、SASL 和 Topic/Group ACL,管理凭据与业务凭据分离。跨不可信网络不使用 PLAINTEXT。保留策略、ACL、Topic 配置和集群元数据纳入配置备份;副本不能替代异地恢复或业务归档。

滚动升级按官方版本路径操作,先检查客户端协议兼容、ISR 和 quorum,再逐节点升级。ZooKeeper 到 KRaft 的迁移只在支持迁移的版本和流程内执行,不能直接拿 ZooKeeper 配置启动 Kafka 4.x。

评论