Kafka核心概念:Topic、Partition、Broker、Producer、Consumer、Consumer Group

好,咱们今天来啃Kafka最核心的几个概念。说实话,很多初学者一上来就被这些术语搞懵了。我当年刚接触Kafka时,也花了整整一周才理清楚它们之间的关系。别急,咱们一个一个拆开讲。

Topic:数据的“分类标签”

Topic,说白了就是一个数据流的名字。你想想看,金融系统里每天有成千上万条交易数据,有股票成交、有基金申购、有风控告警……如果全混在一起,谁分得清谁是谁?

Topic就是用来做分类的。比如我定义一个叫trade_orders的Topic,专门放订单数据;再定义一个risk_alerts,专门放风控告警。这样数据就有了归属,消费方也能按需订阅。

重点:Topic只是一个逻辑概念,它不存储数据。真正存数据的是Partition。

Partition:数据分片,Kafka的“并行引擎”

一个Topic可以拆成多个Partition。为什么要拆?为了并行啊!

我在项目中遇到过这样一个场景:某券商的核心交易系统,每秒要处理几万笔订单。如果只有一个Partition,那所有数据都挤在一个队列里,消费者只能串行处理,性能根本扛不住。

把Topic拆成多个Partition后,每个Partition可以独立读写,消费者也能并行消费。嗯,这里要注意:Partition内部是有序的,但Partition之间不保证全局有序。如果你需要严格有序,那就只能用一个Partition——但代价就是性能下降。

Partition数量 优点 缺点
1个 严格有序 吞吐量低,无法并行
多个 高吞吐,可并行 Partition间无序

我的建议:金融场景中,如果对顺序要求不高(比如日志、监控),Partition数可以设大一些,比如12个或24个。如果要求严格有序(比如资金流水),那就只能设1个,或者用业务键做分区。

Broker:Kafka集群的“工人”

Broker就是Kafka服务器。一个Kafka集群由多个Broker组成,每个Broker负责管理一部分Partition。

我习惯把Broker比作工厂里的工人。每个工人手里有几份文件(Partition),工人之间可以互相备份文件(副本机制)。如果某个工人请假了(宕机),其他工人能顶上。

为什么要有多个Broker?说白了就是为了高可用。我曾经见过一个生产环境,3个Broker的集群,其中一个挂了,集群照样正常服务。如果只有一个Broker,那它一挂,整个系统就瘫痪了。

Producer:数据的“生产者”

Producer就是往Kafka发数据的客户端。比如你的交易系统每产生一笔订单,就通过Producer发到trade_orders这个Topic里。

Producer有几个关键参数,我踩过坑,得跟你说说:

  • acks:确认机制。设成all最安全,但性能最差;设成0性能最好,但可能丢数据。金融场景我建议用all,数据不能丢。
  • retries:重试次数。网络抖动时,重试能避免发送失败。我曾经把重试设成3次,结果某次网络故障持续了10秒,重试3次全失败,数据丢了。后来我改成重试5次,配合指数退避,稳多了。
  • batch.size:批量发送大小。设大一点能提高吞吐,但会增加延迟。我一般设16KB到32KB,看业务对延迟的容忍度。
// 一个典型的Producer配置示例
Properties props = new Properties();
props.put("bootstrap.servers", "broker1:9092,broker2:9092");
props.put("acks", "all");
props.put("retries", 5);
props.put("batch.size", 16384);
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

Producer<String, String> producer = new KafkaProducer<>(props);
producer.send(new ProducerRecord<>("trade_orders", "order_id_123", "{\"symbol\":\"AAPL\",\"price\":150.0}"));

Consumer:数据的“消费者”

Consumer从Kafka拉取数据。比如你的风控系统订阅了risk_alerts,一旦有告警,Consumer就拉下来处理。

Consumer有个重要的概念叫offset(偏移量)。它记录了当前消费到了哪个位置。我刚开始做时,以为Consumer消费完数据就完事了,结果有一次Consumer重启后,从最早的数据重新消费了一遍,把下游系统搞崩了。后来我才知道,offset默认是自动提交的,如果没提交成功,重启后就会重复消费。

避坑指南:我曾经遇到过Consumer自动提交offset的时机没调好,导致数据重复处理。后来我改成手动提交,在业务处理成功后再提交offset,虽然代码复杂了点,但数据一致性有保障。

Consumer Group:消费者的“团队协作”

Consumer Group是一组Consumer的集合。它们共同消费一个Topic,每个Partition只能被同一个Group内的一个Consumer消费。

为什么要用Group?举个例子:你的风控系统有3个实例,如果每个实例都消费全部数据,那就重复了。把它们放到同一个Group里,Kafka会自动分配Partition,每个实例只消费一部分数据,既避免了重复,又实现了负载均衡。

我习惯把Group比作一个团队。团队里有3个人(Consumer),有6份工作(Partition),每人分2份。如果有人离职了(Consumer宕机),剩下的两个人会重新分配工作,把离职那人的工作接过来。

这里有个关键点:Group内的Consumer数量不能超过Partition数。如果Partition有6个,Consumer有8个,那就有2个Consumer闲着没事干。我曾经犯过这个错,白白浪费了资源。

一张图看懂Kafka核心架构

说了这么多,咱们用一张SVG图把关系理清楚:

Producer Topic trade_orders Partition 0 Partition 1 Partition 2 Broker 1 Broker 2 Broker 3 Consumer Group risk_group Consumer 1 Consumer 2 Consumer 3 图例: Producer(生产者) Topic(主题) Broker(服务器) Consumer Group(消费组) 流程:Producer → Topic(Partition 0/1/2) → Broker集群 → Consumer Group(Consumer 1/2/3)

这张图把整个流程串起来了。Producer发数据到Topic,Topic拆成多个Partition,Partition分布在多个Broker上,Consumer Group里的每个Consumer负责消费不同的Partition。环环相扣,缺一不可。

小结

这六个概念是Kafka的基石。Topic是分类,Partition是分片,Broker是服务器,Producer是写入端,Consumer是读取端,Consumer Group是消费团队。搞懂了它们,Kafka的架构你就掌握了七成。

我个人习惯在搭建金融流处理系统时,先把Topic和Partition规划好,再考虑Broker的部署和Consumer Group的设计。顺序对了,后面就顺了。

蓝海数据掘金营,专注资料整理