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,Topic拆成多个Partition,Partition分布在多个Broker上,Consumer Group里的每个Consumer负责消费不同的Partition。环环相扣,缺一不可。
小结
这六个概念是Kafka的基石。Topic是分类,Partition是分片,Broker是服务器,Producer是写入端,Consumer是读取端,Consumer Group是消费团队。搞懂了它们,Kafka的架构你就掌握了七成。
我个人习惯在搭建金融流处理系统时,先把Topic和Partition规划好,再考虑Broker的部署和Consumer Group的设计。顺序对了,后面就顺了。