4. 消息队列中间件:Kafka 核心概念与选型实战
大家好,我是老张。今天咱们聊聊大屏监控系统里最关键的「数据管道」——消息队列。说实话,我见过不少团队,数据采集搞定了,存储也搭好了,结果中间的消息队列成了瓶颈。嗯,这节咱们就把它彻底讲透。
4.1 Kafka 核心概念:Topic、Partition、Consumer Group
先说说 Kafka 最基础的三个概念。你想想看,没有它们,Kafka 就是个空壳子。
4.1.1 Topic(主题)
Topic 说白了就是消息的分类标签。比如我们做大屏监控,会有「服务器CPU指标」、「网络流量数据」、「业务订单量」这些不同的数据流。每个数据流就是一个 Topic。
我个人习惯这样命名:monitor_cpu_usage、monitor_network_flow。清晰明了,运维同事一看就懂。
4.1.2 Partition(分区)
Partition 是 Kafka 实现高吞吐的关键。一个 Topic 可以拆成多个 Partition,每个 Partition 是一个有序的、不可变的消息序列。
为什么会这样设计?因为单机处理能力有限。把数据分散到多个 Partition 上,就能并行读写。我做过一个项目,刚开始只设了 3 个 Partition,结果高峰期 CPU 指标堆积了 10 万条。后来改成 12 个 Partition,问题迎刃而解。
- Partition 数量决定了并行度
- 同一个 Partition 内的消息是有序的
- 不同 Partition 之间不保证全局顺序
- Partition 越多,吞吐越高,但管理成本也越大
4.1.3 Consumer Group(消费者组)
Consumer Group 是 Kafka 实现「广播」和「单播」的关键机制。同一个 Group 内的消费者,共同消费一个 Topic 的消息——每条消息只会被其中一个消费者处理。
举个例子:我们大屏监控系统有 3 台服务器做实时计算,它们属于同一个 Consumer Group。那么一条 CPU 指标数据,只会被其中一台服务器处理。这样既实现了负载均衡,又避免了重复计算。
我曾经遇到过一个坑:两个不同的业务模块(比如实时告警和历史存储)用了同一个 Consumer Group ID。结果告警模块处理了本该存储模块处理的数据,导致历史数据丢失。嗯,这个教训挺深刻的。
4.2 Kafka 高可用部署实战
Kafka 的高可用,说白了就是「挂了也不怕」。我建议至少部署 3 个 Broker 节点,配合副本机制来实现。
4.2.1 副本机制(Replication)
每个 Partition 可以设置多个副本。比如 replication.factor=3,意味着每个 Partition 有 3 个副本,分布在不同的 Broker 上。
副本分为 Leader 和 Follower。生产者只往 Leader 写,消费者也只从 Leader 读。Follower 负责同步数据。一旦 Leader 挂了,Controller 会从 Follower 中选举一个新的 Leader。
# 创建 Topic 时指定副本数
bin/kafka-topics.sh --create \
--bootstrap-server broker1:9092,broker2:9092,broker3:9092 \
--replication-factor 3 \
--partitions 12 \
--topic monitor_cpu_usage
4.2.2 ISR 机制(In-Sync Replicas)
ISR 是 Kafka 保证数据一致性的关键。只有跟 Leader 保持同步的 Follower 才会被列入 ISR 列表。如果某个 Follower 落后太多,就会被踢出 ISR。
我记得有一次,某个 Broker 磁盘 IO 飙升,导致 Follower 同步延迟超过 30 秒。Kafka 自动把它踢出了 ISR,然后从其他 Follower 中重新选举了 Leader。整个过程业务无感知,这就是高可用的价值。
4.2.3 生产环境部署建议
| 配置项 | 推荐值 | 说明 |
|---|---|---|
| Broker 数量 | 3 或 5 | 奇数个,方便选举 |
| replication.factor | 3 | 保证数据安全 |
| min.insync.replicas | 2 | 至少 2 个副本同步才算写入成功 |
| acks | all | 生产者等待所有 ISR 确认 |
| unclean.leader.election.enable | false | 不允许非 ISR 的副本成为 Leader |
unclean.leader.election.enable 一定要设为 false。虽然设为 true 能提高可用性,但会丢失数据。在大屏监控场景下,数据准确性比短暂的不可用更重要。
4.3 RabbitMQ 与 Kafka 选型对比
很多同学问我:「老张,到底该用 RabbitMQ 还是 Kafka?」我的回答是:看场景。
4.3.1 核心差异
| 对比维度 | Kafka | RabbitMQ |
|---|---|---|
| 设计定位 | 分布式流处理平台 | 传统消息代理 |
| 吞吐量 | 百万级/秒 | 万级/秒 |
| 消息模型 | 拉模式(Pull) | 推模式(Push) |
| 消息持久化 | 磁盘顺序写,性能高 | 内存+磁盘,性能中等 |
| 消息顺序 | Partition 内有序 | 队列内有序 |
| 路由能力 | 弱(基于 Topic) | 强(Exchange + Routing Key) |
| 延迟 | 毫秒级 | 微秒级 |
4.3.2 选型建议
我个人经验是这样的:
- 大屏监控数据采集 → 选 Kafka:数据量大、吞吐要求高、需要持久化存储。我们每天处理 10 亿条指标数据,Kafka 稳如老狗。
- 业务系统解耦 → 选 RabbitMQ:比如订单系统、支付系统之间的异步通知。需要灵活的路由策略,延迟要求高。
- 日志收集 → 选 Kafka:配合 ELK 或 Flink,Kafka 是标准配置。
- 任务调度 → 选 RabbitMQ:需要确认机制、死信队列等特性。
4.3.3 实战案例
我去年做过一个智慧城市的大屏项目。数据源包括:
- 10 万台 IoT 设备,每秒上报 50 万条传感器数据
- 200 个业务系统,每秒产生 5 万条业务日志
- 实时告警系统,需要毫秒级响应
最终架构是这样的:
- 传感器数据和业务日志 → Kafka(3 个 Broker,12 个 Partition,副本数 3)
- 告警通知和任务调度 → RabbitMQ(集群模式,3 个节点)
运行一年,Kafka 端日均处理 40 亿条消息,RabbitMQ 端日均处理 200 万条消息。各司其职,相安无事。
好了,这节的内容就到这里。下一节咱们聊聊「数据采集 Agent 的设计与实现」,我会分享一个从零搭建采集 Agent 的实战案例,敬请期待。
公众号:蓝海资料掘金营,微信deep3321