2. Kafka基础入门
在银行交易事件平台中,Kafka 承担的是“交易事件总线”的角色:账户转账、支付清算、风控决策、积分变动等事件,都会先被写入 Kafka,再由下游的对账、反欺诈、客户画像、实时报表等系统按需消费。要设计好这样的平台,第一步不是写代码,而是把 Kafka 的核心概念在脑子里建立成一张清晰的结构图。本节围绕消息队列、发布订阅、Topic、Partition、Offset、Broker 六个关键词展开,帮助大家从“会用 API”进阶到“能设计平台”。
一、从消息队列到发布订阅:Kafka 的定位
传统消息队列(如早期的 JMS 实现)通常有两种模型:点对点队列和发布订阅。点对点模型中,一条消息只会被一个消费者取走,适合任务分发;发布订阅模型中,一条消息会被多个订阅者各自收到一份,适合事件广播。Kafka 在语义上更接近发布订阅,但它的实现方式与经典 MQ 有本质区别。
Kafka 采用“日志式”存储:消息被追加写入磁盘上的分区日志,消费者通过维护自己的读取位置来消费,而不是由 Broker 删除已读消息。这意味着同一份数据可以被多个消费组重复读取,也可以被回放。对银行场景而言,这一点非常关键——风控系统需要实时消费,而审计系统可能需要在事后重新读取历史事件进行核查,两者互不干扰。
二、Topic、Partition 与 Offset:数据如何组织
Topic 是逻辑上的消息分类,例如 bank.transfer.events、bank.payment.events。每个 Topic 可以划分为多个 Partition,Partition 是物理上的有序日志文件。消息被追加到某个 Partition 的末尾,并分配一个单调递增的编号,这个编号就是 Offset。
Partition 是 Kafka 实现水平扩展和并行消费的基本单位。一个 Topic 有 N 个 Partition,就可以被同一个消费组内的最多 N 个消费者并行消费。Offset 则决定了消费者的读取位置:消费者提交 Offset 表示“我已经处理到这里”,Kafka 据此支持断点续读和重复消费。
| 概念 | 层级 | 作用 | 银行场景示例 |
|---|---|---|---|
| Broker | 物理节点 | 存储 Partition、处理读写请求 | 3 台 Broker 组成集群,跨机房部署 |
| Topic | 逻辑分类 | 按业务域隔离消息 | 转账事件、支付事件、风控事件 |
| Partition | 物理日志 | 并行读写、水平扩展 | 转账 Topic 设 12 个 Partition |
| Offset | 消息编号 | 标识消费进度、支持回放 | 风控消费组提交 Offset 到 1024 |
| Consumer Group | 消费单元 | 组内分区分配、组间广播 | 对账组与风控组各自独立消费 |
三、Broker 与集群:消息落在哪里
Broker 是 Kafka 的服务器进程,多个 Broker 组成集群。每个 Partition 会有一个 Leader 和若干 Follower,Leader 负责读写,Follower 负责同步复制。当 Leader 所在 Broker 故障时,Kafka 会从 ISR(同步副本集合)中选举新的 Leader,从而保证可用性。
在银行交易平台中,通常至少部署 3 个 Broker,并设置 replication.factor=3、min.insync.replicas=2。这样即使一台 Broker 宕机,数据仍然不丢,写入也不会中断。生产者的 acks=all 配合上述配置,可以实现“至少写入两个副本才确认”的强可靠语义。
# 创建一个银行转账事件 Topic
kafka-topics.sh --create \
--bootstrap-server kafka-bank:9092 \
--topic bank.transfer.events \
--partitions 12 \
--replication-factor 3 \
--config min.insync.replicas=2
# 查看 Topic 详情
kafka-topics.sh --describe \
--bootstrap-server kafka-bank:9092 \
--topic bank.transfer.events
四、案例与误区:转账事件平台的一次复盘
某银行在建设转账事件平台时,最初将转账 Topic 设置为 1 个 Partition,认为“消息量不大,够用”。上线后发现,下游风控系统需要实时计算,但单 Partition 只能被一个消费者线程消费,吞吐上不去,延迟逐渐升高。后来将 Partition 扩展到 12 个,消费并行度提升,延迟恢复到毫秒级。
另一个常见误区是混淆“消费组”和“消费者”。同一个消费组内,一个 Partition 只会分配给一个消费者;不同消费组之间互不影响。如果风控和对账使用了同一个消费组,就会互相抢分区,导致两边都收不全消息。正确做法是为每个业务系统建立独立消费组。
bank.transfer.events;关键交易 Topic 设置 cleanup.policy=delete 并保留 7~30 天;需要长期审计的事件可另建归档 Topic 或写入对象存储。
把这张结构图记在脑子里,后续设计银行交易事件平台时,无论是选分区数、定副本策略,还是排查消费延迟,都能快速定位到对应的概念层级。Kafka 并不复杂,复杂的是把每个概念放到正确的位置上。