这段时间圈子里聊得最密的,就是“Kafka已正式接入AI”这句话。以前我们总把Kafka当成日志搬运工,觉得它就是给数据中间加一层缓冲、削削峰顶多削个峰,直到最近我认真捋了一遍AI应用的数据流,才发现Kafka几乎成了AI场景里的“神经中枢”。这篇文章不聊口号,就讲清楚Kafka接入AI到底接的是什么、从零怎么搭一条实时数据管道、生产环境里最常见的消息延迟和重复消费问题怎么排查,顺便把大家平时搜的那些词——Kafka可视化工具、集群安装、生产消费命令、Kafka和RabbitMQ的区别——一次性串起来。如果你正在做 AI 应用开发、数据平台建设,或者准备应付下一场架构面试,这篇值得你花十分钟看完。
1. 先搞清楚:Kafka正式接入AI,到底接的是什么
1.1 从消息队列到AI数据神经中枢
很多人在谈“Kafka接入AI”的时候,第一反应是“用Kafka存AI日志”。这个理解不能说错,但太浅了。AI应用的完整生命周期是:数据采集 -> 清洗 -> 特征工程 -> 训练 -> 推理 -> 反馈 -> 再训练。每一步之间都需要数据流转,而传统的数据流转方式——直接调接口、写文件、连数据库——在实时性和解耦性上都有硬伤。
Kafka真正解决的,是AI系统中的“数据流动”问题。它不是一个简单的消息队列,而是一个分布式事件流平台。AI项目里最值钱的不是模型本身,而是持续产生的数据流。用户行为、传感器数据、业务日志、模型推理请求、推理结果、人工反馈……这些流通常每秒几万条甚至更高,如果没有一个统一的缓冲和分发层,任何一个下游服务的抖动都会像多米诺骨牌一样传导给整个AI链路。
所以“Kafka正式接入AI”这句话,我更愿意解读成:Kafka生态开始原生支持AI场景下的事件流模式,而不是等我们用一堆hack手段硬接。它带来的核心价值有三个:高吞吐缓冲、多消费者订阅、事件回放。尤其是事件回放,这是其他很多中间件做不到的,后面会详细说。
1.2 Kafka接AI,接的是哪几层
我把Kafka和AI结合的位置分成四层,这样看架构会特别清楚:
- 数据接入层:各类数据源(App埋点、DB变更、日志文件、IoT设备)通过Kafka Connect或者SDK写入Kafka,作为AI的训练数据和推理输入的统一入口。
- 实时特征管道层:特征计算任务从Kafka消费原始事件,实时计算特征后写入Redis、Feature Store或者特征Topic,供在线推理模型调用。
- 模型推理层:AI推理服务作为Kafka消费者,接收推理请求消息,执行模型预测后把结果发回结果Topic,或者直接投递到下游业务系统。
- 反馈与回流层:推理结果、用户反馈、标注数据再写回Kafka,形成数据闭环,用于模型监控、在线学习、定期微调。
这四层可以只用一套Kafka集群支撑。每一层通过Topic隔离,通过Consumer Group实现独立伸缩,层与层之间互不阻塞。这就是为什么越来越多人愿意在AI架构里放一个Kafka,而不是像以前那样让各服务之间两两直连。
1.3 为什么偏偏是Kafka
很多人会问:RabbitMQ不行吗?Pulsar不行吗?Redis Streams不行吗?我对比过之后说句实话:不是不能用,而是Kafka和AI场景的匹配度最高。
关键在三点。第一,Kafka的分区模型天然支持并发消费。一个Topic拆成多个分区,每个分区只能被同一个Group内的一个消费者线程消费,但不同分区可以并行处理。AI推理任务经常需要大并发,如果瓶颈在模型算力,只需要给消费者Group加机器;如果瓶颈在模型效果,需要按用户或请求ID保持顺序处理,就按Key路由到同一个分区。这种“既能并发、又能保序”的能力,是AI场景特别需要的。
第二,Kafka的日志语义特别适合训练数据集管理。Kafka里的数据默认保留一段时间或达到一定大小后才删除,期间任何新消费者都可以从任意位置重新消费,相当于自带时间回溯能力。训练集需要更新、模型需要复盘之前的数据,直接把Consumer Group重置到几天前的offset重放一遍就行,不需要跑数据恢复流程。
第三,生态齐全到什么程度——Kafka Streams可以做流式特征计算,ksqlDB可以用SQL处理实时特征,Schema Registry能管理AI特征和推理结果的数据协议,Kafka Connect对接各种存储。AI项目落地的最大成本是数据工程,Kafka把数据工程里最难啃的骨头已经啃掉了一大半。
2. 从零搭建一套Kafka + AI实时管道
2.1 用Docker Compose快速拉起Kafka集群
纸上谈兵没用,我直接把我常用的最小可用搭建方式放出来。现在Kafka已经全面支持KRaft模式,不依赖ZooKeeper,个人开发环境一台机器就能跑。
新建一个docker-compose.yml:
version: "3.8" services: kafka: image: apache/kafka:3.7.0 container_name: kafka ports: - "9092:9092" environment: KAFKA_NODE_ID: 1 KAFKA_PROCESS_ROLES: broker,controller KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093 KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093 KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092 KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1然后执行:
docker compose up -d这里有几个参数我要提醒一下:KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR和KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR在单节点集群里必须设为1,否则Kafka初始化和事务功能会失败,这是新手最容易踩的坑。生产环境至少要三台Broker,这个值要改成3。另外一个容易忽略的是KAFKA_ADVERTISED_LISTENERS,这个地址是写给客户端看的,如果你用的是远程服务器,必须改成服务器的公网或内网IP,否则客户端连不上。
2.2 用Python快速体验Kafka生产与消费
装好集群后,用Python跑一个最简单的生产消费验证。先装依赖:
pip install kafka-python生产者代码:
from kafka import KafkaProducer import json import time producer = KafkaProducer( bootstrap_servers='localhost:9092', value_serializer=lambda v: json.dumps(v).encode('utf-8') ) for i in range(10): message = { "request_id": i, "text": "Kafka接入AI的测试消息", "timestamp": time.time() } producer.send("ai-inference-request", value=message) producer.flush() print("10条消息已发送")消费者代码:
from kafka import KafkaConsumer import json consumer = KafkaConsumer( "ai-inference-request", bootstrap_servers="localhost:9092", group_id="ai-consumer", auto_offset_reset="earliest", enable_auto_commit=True ) for msg in consumer: data = json.loads(msg.value.decode('utf-8')) print(f"收到分区{msg.partition}数据: {data}")注意,这段消费者代码跑起来之后会一直停在那里,不会自动退出。这不是卡死,而是Kafka消费者本来就设计成长轮询模型,它会持续向Broker拉取新消息。如果你只想消费固定条数,要么手动杀掉进程,要么在for循环里加计数器控制。这个话题后面专门讲。
2.3 把Kafka接到模型推理服务
光传字符串没意思,我演示一个真实点的AI场景:从Kafka消费文本消息,做向量化,然后把结果写回另一个Topic。假设你已经有一个embedding模型,这里用sentence-transformers里的小模型举例:
from kafka import KafkaConsumer, KafkaProducer from sentence_transformers import SentenceTransformer import json # 初始化模型 model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2') consumer = KafkaConsumer( "ai-inference-request", bootstrap_servers="localhost:9092", group_id="ai-embedding-worker", auto_offset_reset="latest", enable_auto_commit=False ) producer = KafkaProducer( bootstrap_servers="localhost:9092", value_serializer=lambda v: json.dumps(v).encode('utf-8') ) for msg in consumer: request = json.loads(msg.value.decode('utf-8')) text = request["text"] # 推理:文本向量化 vector = model.encode(text).tolist() result = { "request_id": request["request_id"], "vector": vector, "model_name": "paraphrase-multilingual-MiniLM-L12-v2" } # 结果写入下行Topic producer.send("ai-embedding-result", value=result) producer.flush() # 手动提交offset consumer.commit()这个场景里,我把enable_auto_commit设成了False,每处理完一条消息就手动提交offset。为什么要手动提交?经验之谈:在AI推理这类耗时操作里,如果开自动提交,很可能消息还没处理完,offset就已经被提交了。一旦服务进程崩溃,就会出现“丢了数据”的假象——其实是offset推进得太快。反过来,如果处理完再提交,万一提交失败,下个消费者会再拿一次这条消息,这就造成重复消费。所以AI场景的消费端设计,本质上是在“不丢”和“不重”之间做权衡。
2.4 生产者和消费者的关键参数,凭什么这么配
我经常看到有人直接把API默认参数跑线上,然后出了问题一脸懵。这里把我实际调Kafka参数的经验整理一下。
Producer端:
| 参数 | 默认值 | 我的建议 | 原因 |
|---|---|---|---|
| acks | 1 | all | AI场景不能丢请求,必须等所有ISR副本确认 |
| enable.idempotence | false | true | 开启幂等生产,避免网络重试造成消息重复 |
| linger.ms | 0 | 5-20 | 牺牲几毫秒延迟,显著提升吞吐,适合高并发AI数据接入 |
| batch.size | 16384 | 32768-65536 | 大批次减少网络交互,但太大会增加延迟 |
| retries | 2147483647 | 3-5 | 设置合理重试次数,配合幂等更安全 |
Consumer端:
| 参数 | 默认值 | 我的建议 | 原因 |
|---|---|---|---|
| enable.auto.commit | true | false | 手动提交才能精确控制offset |
| auto.offset.reset | latest | 按需 | AI离线重放选earliest,在线推理选latest |
| max.poll.interval.ms | 300000 | 适当调大 | 推理耗时可能超过默认5分钟,超时会被踢出组 |
| heartbeat.interval.ms | 3000 | 1000-3000 | 调小有助于快速发现消费者宕机 |
| max.poll.records | 500 | 100-500 | 一次拉取太多消息会导致处理窗口拉长 |
有一个特别容易踩的坑:如果推理服务处理一条消息要10秒,而max.poll.interval.ms保持默认5分钟,当积压消息一多,消费者在5分钟内没完成一轮poll,Broker会判定消费者死亡并触发rebalance。结果就是处理进度反复倒退,Lag越来越高,消费组一直在“心跳正常但被踢出”的边缘徘徊。解决办法不是无限调大这个参数,而是要保证“拉取一轮消息的总处理耗时小于该参数”,配合max.poll.records限制单次拉取量。
3. 日常运维绕不开的命令行与可视化工具
3.1 生产消费命令为什么启动一次会一直跑
命令行工具是排查Kafka问题的最低门槛,Kafka自带的脚本在bin目录下。最常用的生产命令:
kafka-console-producer.sh --bootstrap-server localhost:9092 --topic ai-inference-request启动后,在控制台输入一行消息,回车就发送一行。这条命令不是常驻进程,输完就结束,因为生产者本来就不需要持续等待消息。
消费命令就不一样了:
kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic ai-inference-request --from-beginning --group ai-consumer很多人第一次跑这条命令,发现控制台一直停在那里,就以为是卡住了。其实这是Kafka消费者的正常工作方式:它启动后会向Broker发送拉取请求,如果没有新消息,就进入长轮询等待状态,Broker默认阻塞300ms再返回空批次,消费者继续发起下一轮拉取,如此循环。所以一条消费命令启动后会一直运行,直到你按Ctrl+C结束。
这里要额外说一个容易误用的点。加--from-beginning的效果取决于当前消费者Group是否已经存在:
- 如果这个Group是全新的、没有提交过offset,
--from-beginning表示从最早的可用消息开始消费; - 如果Group已经有提交过的offset,这个参数不会生效,继续从上次的offset位置消费。
很多人用命令行排查“为什么消息消费不到”的时候,老纠结这个参数,其实真正的问题是Consumer Group的offset已经推进到最新位置了,旧消息早被跳过。
3.2 可视化工具怎么选
命令行能解决问题,但不直观,尤其是看Lag和分区分布的时候。我试过几个可视化工具,给结论:
- Kafka UI(provectus/kafka-ui):开源免费,支持多集群管理、查看Topic分区、浏览消息内容、查看Consumer Group的Lag,部署也很简单。个人项目我优先推荐。
- Offset Explorer(原Kafka Tool):桌面客户端,老牌工具,浏览消息很方便,适合本地快速查看。
- Kafdrop:轻量级Web UI,主打简单,适合临时用,功能比Kafka UI少。
- Conduktor:功能全面,有商业版,团队协作时可以考虑。
Kafka UI的Docker部署就一行:
docker run -d \ --name kafka-ui \ -p 8080:8080 \ -e KAFKA_CLUSTERS_0_NAME=local \ -e KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=localhost:9092 \ provectuslabs/kafka-ui:latest我建议你在本地把所有工具都装上玩一遍,但线上环境不要随便开浏览Topic消息的权限,高危操作尽量用命令行走审批。这里提一句:可视化工具看的是“现状”,很多问题还是得靠命令行的精确输出才能定位。
3.3 集群监控比对:从JMX到Prometheus
Kafka本身提供了非常丰富的JMX指标,但太底层,不容易用。现在我常用的这套组合:
- kafka_exporter:把Kafka指标暴露成Prometheus格式;
- Prometheus:采集和存储指标;
- Grafana:出监控面板。
重点关注的指标有这么几类:
- Broker存活、分区副本是否处于ISR(同步副本列表);
- 消费者Group的Lag、消费速率、堆积速率;
- 请求处理耗时(Produce和Fetch请求的延迟分位数);
- 磁盘使用率、网络吞吐、GC耗时。
其中kafka_consumergroup_lag这个指标是AI场景下的核心KPI。模型推理的效果可以糙一点,但数据管道Lag一旦持续上涨,说明消费者处理能力跟不上生产速度,最终会表现为线上特征过期、推理结果延迟、训练样本陈旧。
4. 消息延迟高和Lag飙高,完整排查思路
4.1 先把概念对齐:延迟不等于Lag
很多团队在排查Kafka性能问题的时候,把“消息延迟高”和“Lag大”混在一起说,结果排查方向从一开始就错了。
- Latency(延迟):一条消息从生产者发送到消费者处理完之间的端到端耗时。
- Lag(消费积压):某个Topic某个分区的
log-end-offset(最新已生产消息位置)与消费者当前已提交offset之间的差值。
它们有关联,但不是一个东西。延迟高可能是单条消息处理太慢;Lag大则说明消费者的平均处理速度跟不上生产速度,积压是持续累积的结果。我见过一个场景:某AI推理服务单条消息处理耗时2秒,延迟确实高,但Lag一直是0,因为处理完才提交offset,根本谈不上积压。另一个场景:消费者批量处理消息,单条很快,但每次批量处理完统一提交offset,一旦批量处理失败,整个批次在下次重拉时全部重新处理,表面看Lag大,本质是事务控制有问题。
4.2 一次真实排查的完整链路
我在实际项目里排查过不少Lag异常,完整链路是这样的:
第一步:确认问题范围。
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group ai-recommend-group输出会类似:
GROUP TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG CONSUMER-ID ai-recommend ai-user-event 0 1000 1500 500 host-1-1 ai-recommend ai-user-event 1 1200 1800 600 host-2-1 ai-recommend ai-user-event 2 900 1500 600 host-1-2看到Lag上涨后,先不要急着加消费者。先看两个数:CURRENT-OFFSET是否还在增长,如果还在增长说明消费没有完全停,只是追不上;如果完全不动,说明消费端可能已经阻塞或者被踢出消费组。
第二步:看消费者实例状态。
如果某几个分区的CONSUMER-ID为空,说明这个分区没有活跃消费者在拉取,通常是rebalance之后没有成功分配。这种情况优先检查消费者是否频繁超时,特别是前面提到的max.poll.interval.ms配置问题。
第三步:看Broker侧指标。
用Kafka UI或者命令查看Broker的请求耗时,特别是Fetch请求的P99。如果Fetch耗时都很高,问题可能不在消费者,而在磁盘IO或者网络。Kafka的底层存储是顺序写盘,但碰上其他业务共用磁盘,或者Page Cache不足,仍然会出现写入和读取互相拖慢的现象。
第四步:验证下游AI服务的实际处理能力。
这一步很容易被忽略。Kafka消费者拿到消息后要调AI模型,模型的单条推理耗时如果是50ms,理论上一个线程每秒能处理20条;如果同时存在一个外部RPC超时重试,一个线程可能被拖到每秒处理2条。这会导致Lag持续上涨,而Kafka本身一点问题都没有。这时候加消费者实例是有效果的,但更该做的是给下游AI服务加超时熔断。
4.3 常见恢复手段与预防
Lag恢复没有银弹,只能根据瓶颈对症下药:
- 如果是消费者处理能力不足:水平扩容Consumer实例,但要注意实例数不要超过总分区数,多了也白加。
- 如果是单条消息处理过慢:优化推理服务本身,或者把消息切小、异步批处理。
- 如果是频繁rebalance:检查
session.timeout.ms、heartbeat.interval.ms和max.poll.interval.ms是否匹配,最好把rebalance机制理解透再调参。 - 如果是单分区热点:AI场景里如果按用户ID做Key,头部用户很容易把流量打到同一个分区。解决方案是增加分区数并重新设计Key策略,或者在写入前给用户ID加盐。
预防也比较简单:把Lag做成监控告警,当某个Consumer Group的Lag超过5000条持续5分钟就触发PagerDuty或者钉钉机器人消息,别等问题已经影响到线上推理结果再去看面板。
5. 重复消费问题:AI场景下的数据一致性设计
5.1 Kafka为什么会重复消费
Kafka的“至少一次”(at-least-once)语义决定了重复消费是可能发生的,不是bug,是分布式系统容错的必然结果。
常见的重复消费原因有三个:
- 消费者处理完消息,但在提交offset之前发生崩溃或网络异常,重启后重新消费同一批消息。
- 消费者处理时间太长,触发
max.poll.interval.ms,Broker判定其死亡并触发rebalance,消息被分配给其他消费者重新消费。 - 事务消息在生产者重试时,如果没开幂等,网络超时后重发导致Broker写入重复消息。
也就是说,一条消息可能被消费两次甚至多次,这在传统消息系统里问题不大——比如订单通知、日志归档,重复一次最多多发一封邮件。但在AI场景里,影响大了去了。
5.2 对AI推理的影响有多大
重复消费对AI推理的影响分三方面:
第一是算力浪费。模型推理是按GPU/CPU计费的,重复消费几千条消息等于白白烧掉几千次推理资源。如果队列积压严重,重复消费还会让恢复时间成倍增长。
第二是结果污染。如果推理结果被写入特征库或者数据库,重复写入会覆盖或追加错误数据。比如实时推荐服务根据用户行为做CTR预估,同一条行为被消费两次,特征里就多了一次计数,用户画像被污染。
第三是下游副作用。很多AI服务不只产出预测结果,还会触发后续业务动作,比如自动风控拦截、自动客服回复。如果重复消费导致同一条风控事件被处理两次,可能造成重复拦截或者重复发送消息,这个影响就不是技术问题而是业务事故了。
5.3 幂等消费的落地方式
要解决重复消费,不能指望Kafka保证“恰好一次”(exactly-once)就万事大吉,因为Kafka的EOS只能保证它自己系统内的读写一致性,下游数据库和AI服务不一定参与事务。实际工程上我见过并实践过这几套方案:
方案一:业务键去重+数据库唯一约束。这是最朴素也最可靠的方案。给每条Kafka消息带一个全局唯一的业务ID(比如request_id或者用户行为event_id),在AI结果写入数据库的字段上建唯一索引,重复插入被数据库拒绝,应用层捕获冲突后正常提交offset。
方案二:Redis乐观去重。在消费端用Redis的SETNX命令,以消息ID为Key设置一个带过期时间的标记:
import redis r = redis.Redis(host='localhost', port=6379, db=0) # 设置成功说明第一次处理,设置失败说明重复消息 if r.set(f"msg:{request_id}", 1, nx=True, ex=3600): # 执行AI推理 ... else: # 跳过,但继续提交offset这个方案的好处是去重逻辑和业务解耦,坏处是Redis本身可能成为新的瓶颈,并且消息量特别大时Key会占大量内存,需要设置合理的过期时间。
方案三:手动提交offset+幂等算子。在AI服务内部实现“读消息-处理-提交”的原子性,这里的关键是不要先commit再处理,而是处理完业务逻辑后同步提交。如果担心“处理完提交前崩溃导致重复”,那就必须配合方案一或方案二,因为分布式系统里不存在既不重复又不丢失的完美答案。
方案四:开启Kafka事务+读已提交隔离级别。这是Kafka官方的EOS方案,Producer端设置enable.idempotence=true和transactional.id,Consume端设置isolation.level=read_committed,配合流处理框架(比如Kafka Streams或Flink)才能发挥真正价值。如果只是普通的生产消费,不推荐硬上事务,复杂度会成倍增加。
我在实际项目中,最推荐的是“方案一+手动提交offset”的组合。数据库唯一约束是最容易说服团队的方案,因为它的语义最清晰:重复消息来了就是会被挡在持久化层外面。AI推理这种资源密集型操作放在约束校验之后,能过滤掉绝大多数重复计算。
6. 选型对比与延伸思考
6.1 Kafka和RabbitMQ到底怎么选
这个几乎是面试必问,也是团队选型时争论最多的话题。我直接给结论:
| 维度 | Kafka | RabbitMQ |
|---|---|---|
| 核心模型 | 分区日志模型,Topic内按offset顺序存储 | 队列模型,消息被消费后即标记删除 |
| 吞吐量 | 单节点轻松支持数十万条/秒 | 单节点万级左右 |
| 消息回放 | 支持,按offset落盘可重放 | 默认不支持,消费即删除 |
| 消费模式 | 支持广播(多Group订阅)和消费组竞争 | 支持发布订阅和轮询/公平队列 |
| 消息顺序 | 分区内有序,跨分区不保证 | 单队列内有序 |
| 消息确认 | 自动/手动提交offset | ack机制,消息级确认 |
| 数据保留 | 时间/大小策略,可长期保留 | 队列删除即丢 |
| 适用场景 | 大数据管道、AI特征流、日志收集、事件驱动数据湖 | 业务解耦、RPC异步化、任务分发 |
AI项目我几乎总是选Kafka,因为需要海量数据经过统一管道进入训练和推理系统,并且要有重放能力。但如果是几台服务器之间做业务解耦,涉及消息的动态优先级和复杂路由,RabbitMQ确实比Kafka灵活。不要迷信哪个更高级,关键看你要解决的问题是“大量数据持续流动”还是“业务消息精准投递”。
6.2 Kafka接AI之后的几个值得关注的方向
Kafka接入AI这个话题,接下来有几个方向我觉得值得持续关注。
一个是特征平台标准化。实时特征计算的逻辑以后大概率会统一落在Kafka Streams或者Flink里,而不是散落在各个模型服务的内部代码里。Kafka Streams正好解决了“特征计算代码和模型代码耦合”的问题,可以做到特征逻辑单独部署、单独扩缩容。
另一个是AI Agent事件总线。现在的多Agent协作系统里,Agent之间需要传递任务状态、推理结果、上下文信息,很多团队直接通过HTTP调用硬串,调试起来极其痛苦。改成Kafka事件总线后,每个Agent只需要订阅自己关心的事件,发布自己的处理结果,Agent之间的耦合度会大幅降低。我刚看到Spring AI Alibaba这类框架也在做AI服务接入抽象,和Spring Kafka配合用会越来越顺。
还有一个很实在的方向是训练数据的自动回流。在线推理产生的错误案例、用户反馈、标注结果,都通过Kafka统一收集,定期回放给训练任务生成新的训练集。这一步做好之后,数据闭环才真正成立,模型的持续迭代才有依据。
最后补一个我自己的体会:Kafka接入AI这件事,最难的从来不是Kafka本身,而是下游AI服务的吞吐和Kafka的吞吐不匹配。Kafka可以一秒接收几十万条消息,但一个模型服务一秒能处理几百条就算不错了。所以做架构的时候,一定要在中间留好缓冲层、设计好背压机制,否则Kafka越稳定,你的AI服务就越容易被积压消息冲垮。先把这部分想清楚,再谈接入AI,才不会被那句“已正式接入AI”的宣传带偏。