想象你经营一家网店,大促瞬间几千个订单同时涌入,如果每单都让客服立刻回电、仓库立刻发货、财务立刻对账,系统当场就会瘫痪。聪明的做法是建一个「订单中转站」:所有请求先扔进去,后端各部门按自己的节奏取走处理。这个中转站,就是消息队列。市面有三款主流中转站,风格迥异:Kafka 像一条超长自动传送带,包裹按到达顺序摊开在带上,极速追加、极速读取,但布局固定不易调整;Pulsar 像一座现代化物流园区,分拣台只管收发,货物统一存入共享总仓,分拣台坏了随时换新,多家公司还能共园而治;RocketMQ 则像同城保价急送,讲究严格先来后到,还支持「货到付款」式的两阶段确认。这篇文章,我们沿着这条物流线,把三者的架构、语义与适用场景一次讲透,帮你选出最匹配的那一款。
选错消息队列如同选错仓库:扩容时翻车、数据错乱时束手无策。搞清 Kafka、Pulsar、RocketMQ 的架构差异,是流式数据工程师做出可靠选型的第一课。
可视化演示
展示三大消息队列架构差异(Kafka一体/Pulsar分离/RocketMQ事务)、消息投递语义(≤1/≥1/=1)与吞吐/延迟/事务/扩容/生态五维对比,帮助理解MQ选型决策。
本节配有交互动效(进入视口后自动加载,约 3KB)。
'+captions.arch+'
消息队列基础
想象你开了一家网店。大促瞬间涌入几千个订单,如果每一单都让客服立刻打电话、仓库立刻发货、财务立刻对账,系统瞬间就会卡死。聪明的做法是设一个「订单中转站」:下单请求先扔进去,后端各个部门按自己的节奏取走处理。这个中转站,就是消息队列的核心思想——它从不在“谁送”和“谁收”之间强加同步,而是让两边各自为政、异步协作。
对应到技术世界,角色非常清晰:寄件人叫 Producer(生产者),收件人叫 Consumer(消费者),一条专线叫 Topic,中转站里的分拣中心叫 Broker。Producer 只管往 Topic 丢消息,Consumer 按需拉取,二者互不相识。这带来两个杀手级能力:异步解耦——上游不再关心下游是否在线、处理多慢;削峰填谷——流量洪峰先灌进队列,下游按最大处理能力慢慢消化,系统再也不会被瞬时流量冲垮。
但中转站不是无限的,它本质是一个排队系统。排队论里有一条著名定律——利特尔定律(Little's Law):中转站里积压的订单数,等于每秒到达的订单数乘以每个订单平均停留的时间。这条公式,是后面理解三个产品吞吐差异的底层工具。
现在你理解了中转站的价值。但同样是中转站,Kafka、Pulsar、RocketMQ 三家公司的建造方案截然不同:一家铺超长传送带,一家建现代化物流园区,一家做同城保价急送。接下来,我们逐一参观。
- L(积压队列长度)中转站里同时滞留的包裹数量,即待处理订单数。
- λ(到达速率)平均每秒涌入中转站的订单数,大促时 λ 会瞬间飙高。
- W(平均等待时长)每个包裹从进站到被取走的平均时间,下游处理越慢 W 越大。
Kafka架构剖析
先参观 Kafka。它的仓库是一条超长的自动传送带:所有包裹一到,就按到达顺序一个接一个平铺在传送带上,只能往后追加,绝不允许插队或修改。任何想看包裹的人,只能沿着传送带从头走到尾,按编号(offset)找到自己想要的货。这就是 Kafka 的存储模型——分布式提交日志(distributed commit log)。
传送带太长,一条不够用怎么办?Kafka 把一个 Topic 专线切成多个 Partition(分区),相当于并排铺开多条子传送带。为了防丢失,每条分区的数据会复制 N 份到不同节点(副本)。多分区带来并行度,副本带来可靠性,这是 Kafka 吞吐与容错的两大支柱。
那 Kafka 为什么快?两个秘密:顺序写盘和页缓存。机械硬盘顺序写可达每秒几百 MB,随机写却慢两三个数量级;Kafka 只追加不修改,恰好把磁盘最擅长的顺序写发挥到极致。同时,消息先写操作系统页缓存(page cache),由内核异步刷盘,免去每写一条都等待落盘的延迟。为了保证“副本跟上主节点”,Kafka 维护一个 ISR(In-Sync Replicas)同步副本集合,只有集合内的副本才参与“已确认”判定。
Kafka 把“快”做到了极致,但也有代价:想给传送带换布局很难——加机器要搬数据;想让多个公司共用一条传送带,也缺乏隔离机制。速度之王的短板,正好是下一家 Pulsar 的强项。
- QPS(每秒查询数)传送带系统每秒能处理的请求数,衡量吞吐的核心指标。
- B(批大小)Kafka 把多条消息凑成一批再写盘,一次搬运越多效率越高。
- N(分区数)并行子传送带的数量,分区越多并行度越高。
- t(单次耗时)一次批量写入的耗时,顺序写让 t 远小于随机写。
Pulsar架构剖析
Pulsar 建的是一座现代化物流园区,它与 Kafka 最大的不同可以浓缩成一句话:计算与存储分离。园区里有两类角色:分拣台 Broker 只负责收发包裹、维护会话状态,本身不存任何货;包裹真正存放的地点是共享总仓 BookKeeper,由一批 Bookie 存储节点组成。分拣台坏了,换一台新的立刻上岗,因为货都在总仓里——这就是“Broker 无状态”。
总仓怎么存?Pulsar 把数据切成一个个小段(Segment)分散存到多个 Bookie 上,每段有若干副本。这带来两个好处:分层存储——老数据可以自动滚动到廉价存储,想存多久存多久;扩容像呼吸一样自然——加 Broker 不用搬任何数据,加 Bookie 只是给总仓多几排货架。对比 Kafka 扩容时要把百万级分区搬来搬去,Pulsar 的体验堪称丝滑。
园区由物业统一管理,不同公司可以同时入驻而互不干扰:Pulsar 用 namespace(命名空间)做多租户隔离,每个租户有自己的配额、权限和流量策略。一个租户流量暴涨,最多挤占其所在资源,不会拖垮整座园区。对云厂商和 SaaS 平台来说,这是 Kafka 很难给出的承诺。
园区模式让 Pulsar 在弹性、多租户、长时存储上完胜,但每件货要“分拣台→总仓”两跳,多一次网络往返,裸延迟和吞吐未必比 Kafka 那条直通传送带强。接下来这家,专治“怕乱、怕丢”的场景。
- N_段(分段数量)总仓里数据被切成多少个小段,决定存储的分散程度。
- D_总量(数据总量)需要存储的全部数据大小,例如 10 TB 的日志。
- S_段(每段大小)每个存储段的大小,例如 64 MB。
RocketMQ架构剖析
RocketMQ 像同城保价急送专线,不追求传送带极速,但把两件事做到极致:严格先来后到,和“货到付款”式的事务保障。为什么需要严格先来后到?银行的转账、电商的下单,消息顺序错了,业务就乱了。RocketMQ 把消息放进有序队列,提供全局顺序和分区顺序两种模式,在金融交易圈口碑极佳。
再看“货到付款”,这是 RocketMQ 的招牌——事务消息。想象你在同城急送下了一单:骑手先取走一个“半包裹”(half message),此时这笔交易处于待定状态,消费者不可见;你确认付款后,系统才把半包裹升级为正式包裹发出。如果中途取消(本地事务回滚),半包裹直接作废。RocketMQ 通过这个两阶段机制,把“发消息”和“本地数据库操作”绑定成同一个事务,杜绝了“订单已付但物流没收到”的惨案。
其他细节同样扎实:主从同步保证高可用;消息带 Tag 支持在 Broker 端过滤,减少无效网络传输;消费失败可按时延不断重投,多次失败最终进入死信队列等人处理。架构上比 Kafka 多了轻量的 NameServer 做路由,运维组件更简单。
保价急送服务周全,但车队规模和速度终究有限:RocketMQ 的吞吐和水平扩展能力不如 Kafka,多租户隔离不如 Pulsar。三家风格已清晰,下一节我们把它们的“承诺”摆到桌面上对比。
- P_成功(整体成功率)一笔事务消息最终被确认提交并送达的概率。
- P_预提交(半消息成功率)半包裹成功进入 Broker 的概率,这一步失败则交易直接作废。
- P_确认(确认提交率)本地业务事务执行成功并确认提交的概率。
- ×(乘法关系)两步是“且”的关系,任何一步失败,整体就失败——这就是两阶段的本质。
消息语义对比
快递公司给用户的承诺分等级:Kafka 和 Pulsar 默认是“尽全力投递,可能多送一次”;RocketMQ 事务消息则基本做到“要么确认,要么退货”。这些承诺在消息领域有个名字:投递语义(delivery semantics),分为最多一次、至少一次、恰好一次。传统 MQ 多为“至少一次(at-least-once)”:消息可能重复投递,但绝不丢失,消费者必须自己做到幂等——同一消息处理多次,结果与处理一次相同。
顺序保证是第二个对比维度。Kafka 只在分区内有序,全局分散到多个分区就是乱序;RocketMQ 通过单一队列可做到全局有序,代价是牺牲并行度;Pulsar 的策略与 Kafka 类似,分区内有序。第三个维度是事务能力:RocketMQ 原生事务消息解决“跨系统原子性”;Kafka 的事务(Exactly-once)面向流处理中的原子写,两者不是一回事;Pulsar 的事务支持仍在追赶。
最后是失败处理:三者都会自动重试,多次失败后进入死信队列(DLQ),由人工或旁路任务补偿。别小看语义差异——金融场景里一条消息重复扣款是事故,日志场景里重复一条日志则无伤大雅。这正是选型最容易被忽视、却最影响业务正确性的维度。
承诺等级决定了业务要不要做幂等、要不要写补偿。选快递之前先想清楚:你的业务是丢不起,还是重不得?这个答案,直接指向不同的产品。
- E[N](期望投递次数)一条消息最终被投递给消费者的平均次数。
- p(单次失败概率)每次投递失败的几率,网络抖动或节点宕机都会让 p 变大。
- 等比级数求和第 1 次成功,或失败后重试第 2 次成功、第 3 次成功……累加得到 1/(1−p)。
- q(成功概率)令 q = 1 − p,q 越小,期望投递次数越大,重复也越严重。
性能生态对比
参观完三家仓库,我们再比比车队规模和增值服务。先说吞吐与延迟的体感:单机裸吞吐上,Kafka 凭借顺序写和页缓存通常是第一梯队,尤其适合“写多读少”的日志洪流;RocketMQ 延迟控制出色,适合在线交易链路;Pulsar 因为多了一次存储写入,吞吐下限取决于存储集群,但胜在稳定可预期。
扩容是另一个分水岭。Kafka 加 Broker 时,要把既有分区的数据搬过去(重平衡),数据越多搬得越久,期间消费时延可能抖动;Pulsar 加 Broker 只需告诉园区“新分拣台来了”,数据分毫不动,扩容按秒计算;RocketMQ 的扩容同样需要迁移,但整体设计更轻量,运维门槛低。
多协议与生态方面:Pulsar 原生支持 Kafka 协议、MQTT、AMQP,客户端几乎零改造迁移;Kafka 的杀手锏是生态——Kafka Connect 做数据集成、Schema Registry 管格式、KSQL 做流式查询,加上 Flink/Spark 全家桶的深度适配,流式处理事实标准的地位难以撼动;RocketMQ 生态在国内阿里系技术栈中非常成熟,配套监控告警完善,社区中文资料丰富。
没有一辆车能同时做到最快、最稳、服务最全。性能与生态的取舍,最终要落到业务需求上打分——这就是最后一节要做的事。
- T_重平衡(重平衡耗时)新增节点后,数据重新分布所花费的时间。
- D_数据(迁移数据量)需要搬到新节点的数据总量,与集群既有数据规模成正比。
- V_迁移(迁移速度)单位时间能搬多少数据,受带宽和磁盘读写限制。
选型决策指南
选快递公司,先看你的货是什么。货是海量日志、埋点、指标?Kafka 当仁不让——日志就是纯追加的流,天生匹配 Kafka 的顺序写和重放能力,加上 Flink 生态的深度绑定,实时数据管道的不二之选。这也是 Kafka 吞吐之王的用武之地。
货是订单、转账、库存这类强一致交易?RocketMQ 的事务消息和顺序消息直击痛点,“先半消息、确认后提交”帮你免去手工补偿的深渊。货是“我要给几十个客户开隔离的消息空间”?比如 SaaS 平台、云厂商,Pulsar 的多租户与计算存储分离,让你不必为每个客户单独搭集群,运维成本断崖式下降。
最后还有两个现实因素:成本和团队。小集群、业务简单、团队只熟 Kafka,强行上 Pulsar 的分布式存储反而增加运维负担;反之,规模巨大且多团队共用时,Kafka 的“一人一集群”模式会变成资源黑洞。理性的做法,是把吞吐、事务、多租户、生态、运维五个维度列成评分表,按场景加权求和,让数据替你做决定。
大到国家级快递网络,小到同城跑腿,各有各的适用半径。选型没有最好,只有最匹配——带上这张评分表,你就能从容回答“到底该用哪一个”。
- S_i(候选队列总分)第 i 个候选消息队列的最终评分。
- w_j(维度权重)第 j 个维度的权重,体现业务对吞吐、事务、多租户的重视程度。
- x_ij(维度得分)候选 i 在维度 j 上的能力评分,可以来自压测或社区基准。
- Σ(加权求和)把所有维度得分汇总,总分最高者胜出。
AI 应用场景
场景1:电商大促日志的实时管道(Kafka)
阶段:数据接入与预处理(Data Ingestion)
解决的问题:大促时 Nginx 日志、用户行为埋点每秒产生上亿条记录,直接写数据库会打爆存储;Kafka 像传送带一样把日志按序追加到分布式日志中,Flink 从任意 offset 重放消费,既保证吞吐又支持回溯分析。
具体案例:某电商平台用 90 台 Kafka 支撑双十一峰值每秒 2000 万条日志。数据先入 Kafka,Flink 实时计算 GMV、UV 等指标;离线数仓另起一套消费者,从同一份日志回放训练数据,一套管道两处复用。
场景2:订单与钱包的跨系统事务(RocketMQ)
阶段:事务一致性与状态同步
解决的问题:下单(订单库)与扣款(钱包库)跨两个系统,若先发消息给钱包再写订单,宕机时会出现“单已下、钱没扣”。传统分布式事务框架太重,RocketMQ 事务消息用两阶段,把本地事务和发消息绑定为原子操作。
具体案例:某支付系统在用户付款时,先向 RocketMQ 发送“半消息”,本地扣款事务成功后再确认提交;若本地事务回滚则消息作废,彻底避免重复扣款与漏扣。
场景3:多租户 SaaS 消息平台(Pulsar)
阶段:资源隔离与弹性扩容
解决的问题:SaaS 平台为几十个企业客户提供消息服务,各客户数据量与峰值差异巨大。用 Kafka 要么“一人一集群”成本爆炸,要么共用集群互相干扰;Pulsar 的 namespace 多租户 + 无状态 Broker,让同一个集群内各客户配额隔离、互不感知。
具体案例:某物联网 SaaS 厂商把 30 个客户的设备消息接入同一个 Pulsar 集群,按租户设置配额。某客户设备大规模上报时,只影响其自身 topic,其余 29 个租户零感知;扩容仅需新增 Broker,几分钟完成。
Python 演示
# -*- coding: utf-8 -*-"""Queue semantics simulator: replay Kafka/Pulsar/RocketMQ delivery behaviors"""import random class Queue: def __init__(self, name, dup_rate, ordered, tx_mode=False): self.name = name self.dup_rate = dup_rate self.ordered = ordered self.tx_mode = tx_mode self.sent_list = [] self.received_list = [] self.rollback_count = 0 def send(self, msg_id): # RocketMQ: a prepared (half) message may be rolled back if self.tx_mode and random.random() < 0.02: self.rollback_count += 1 return self.sent_list.append(msg_id) def consume(self): # Kafka/Pulsar keep order inside a partition but lose global order seq = list(range(len(self.sent_list))) if not self.ordered: random.shuffle(seq) for idx in seq: msg_id = self.sent_list[idx] # at-least-once: the same message may be delivered twice if random.random() < self.dup_rate: self.received_list.append((msg_id, 2)) self.received_list.append((msg_id, 1)) def run(self, n): for i in range(n): self.send(i) self.consume() seen = set(m for m, _ in self.received_list) dup = len(self.received_list) - len(seen) lost = n - len(seen) got = [m for m, _ in self.received_list] ok_order = got == sorted(got) print("[%s] delivered=%d dup=%d lost=%d ordered=%s" % (self.name, len(self.received_list), dup, lost, ok_order)) def main(): random.seed(42) n = 1000 queues = [ Queue("Kafka", 0.03, False), Queue("Pulsar", 0.03, False), Queue("RocketMQ", 0.03, True, True), ] for q in queues: q.run(n) print("RocketMQ half-message rollbacks:", queues[2].rollback_count) if __name__ == "__main__": main()
class Queue:用参数化类抽象队列语义:重复率、是否全局有序、是否启用事务两阶段。if self.tx_mode and random.random() < 0.02:模拟 RocketMQ 半消息被回滚:确认之前断了,这笔交易就作废。seq = list(range(len(self.sent_list)))构造消费顺序索引,模拟 Broker 决定消息的分发顺序。if not self.ordered:Kafka/Pulsar 多分区并发消费导致全局乱序,RocketMQ 单队列保持严格先来后到。self.received_list.append((msg_id, 2))at-least-once 语义下,同一条消息可能被重复投递,副本标记为 2。seen = set(m for m, _ in self.received_list)幂等去重:消费者拿到重复消息后也只处理一次。ok_order = got == sorted(got)校验消费顺序是否被打破,输出 True 或 False。random.seed(42)固定随机种子,让多次运行的对比结果可复现。
常见误区
误区Kafka 和 RocketMQ 一样都是消息队列,把消息发给它,消费者取走不就完了?它跟普通队列没有本质区别。
正解Kafka 本质是「分布式提交日志」:数据只追加、按 offset 读取、可重复消费。就像档案流水线,包裹被取走并不会消失,消费者自己管理读到哪了(offset)。RocketMQ/Pulsar 更接近传统 MQ 的收发语义。理解这一点,才能解释为什么 Kafka 能高吞吐重放,也才能明白它为什么在“队列消费完即删除”的场景里显得别扭。
为何常见:大家都叫“消息队列”,教程和面试也这么称呼,很少有人去深究“日志存储”与“队列”在数据模型上的根本差异。
误区性能不够就加分区,反正分区越多并行度越高,吞吐一定线性往上涨。
正解分区增加会带来文件句柄、内存占用和 Rebalance 耗时的成本;而且 Kafka 的吞吐之本恰恰是“单分区顺序写”,无限增加分区反而会把顺序写变成随机写,拖垮性能。正确做法是根据目标吞吐和客户端并行度估算分区数,例如单分区约 10 MB/s,目标 100 MB/s 就规划 10 个左右的分区,而不是盲目堆。
为何常见:加分区在早期确实能明显提速,“线性直觉”让人误以为可以一直加下去,直到集群被句柄和重平衡压垮。
误区Pulsar 是最新的架构,计算存储分离听起来就高级,吞吐肯定碾压 Kafka。
正解计算存储分离带来的核心价值是弹性、多租户和运维友好,而不是绝对吞吐。Pulsar 写入要走“分拣台→总仓”两跳,多一次网络往返;在小集群、低延迟场景下未必比 Kafka 快。Kafka 的顺序写盘把裸吞吐做到了极致,日志场景仍是王者。选型要看场景匹配,而不是架构新旧。
为何常见:“新架构 = 更快”是厂商宣传最爱的叙事,容易让人忽略架构背后的权衡与代价。
误区下单和发消息不一致?我可以用 Seata 之类的分布式事务框架,消息队列自己的事务能力无所谓。
正解分布式事务框架解决的是跨库原子性,而“本地事务成功后再发消息”这个时序问题,恰恰是消息队列事务消息的专长。RocketMQ 事务消息用半消息 + 本地事务回查,保证“本地操作和发消息要么都成、要么都败”;Kafka 的 Exactly-once 事务则面向流处理中的原子写,语义和应用场景都不同。概念同名但指向不同,选错就要在业务层写大量补偿代码。
为何常见:都叫“事务”却分属不同层次,初学者把流处理事务、分布式事务、事务消息混为一谈,是面试里最常见的翻车点。
面试题
Q1. Kafka 能实现高吞吐的核心机制是什么?
- A.顺序写磁盘加页缓存← 正确答案
- B.内存消息队列缓存
- C.多级索引加速查询
- D.压缩算法实时编码
答案:A。Kafka 的传送带只能往后追加,顺序写盘比随机写快两三个数量级,页缓存又免去频繁刷盘等待,两者共同铸就高吞吐。内存缓存是所有队列的基本功,索引与压缩只是辅助手段,不是核心秘密。
Q2. Pulsar 与 Kafka 最本质的架构差异是什么?
- A.Pulsar 消息默认持久化
- B.Pulsar 支持多语言客户端
- C.Pulsar 将计算与存储分离← 正确答案
- D.Pulsar 使用共享存储介质
答案:C。分拣台只管收发、总仓负责存储,计算与存储分离是 Pulsar 一切特性(无状态 Broker、秒级扩容、多租户)的根基。多语言客户端和消息持久化 Kafka 同样具备,不算本质差异。
Q3. 下列哪种业务场景最适合选择 Kafka?
- A.多租户云平台消息隔离
- B.金融转账事务强一致
- C.全局强顺序业务指令
- D.海量日志采集与分析← 正确答案
答案:D。日志是纯追加流,恰好命中 Kafka 顺序写与重放能力,加上 Flink 生态深度适配,成为实时数据管道标配。金融强一致和全局强顺序是 RocketMQ 的主场,多租户隔离则是 Pulsar 的主场。
Q4. RocketMQ 事务消息中的「半消息」状态表示什么?
- A.已确认但等待消费者
- B.已入队且准备投递消费
- C.已消费但等待回调确认
- D.已发送但尚未确认执行← 正确答案
答案:D。半消息就像“货到付款”里的预付单,状态待定、消费者暂时不可见;本地事务成功后确认提交,半消息才升级为正式消息。A 描述的是提交后的状态,B 是普通入队状态,C 与半消息无关。
Q5. 关于 at-least-once 投递语义,以下说法正确的是?
- A.消息至少被投递一次← 正确答案
- B.消息可能完全不被投递
- C.消息最多被投递一次
- D.消息恰好被投递一次
答案:A。至少一次语义下消息不丢但可能重复,消费者必须做幂等处理。B 是“零次投递”,C 是“至多一次”,D 是“恰好一次”,都不符合 at-least-once 的定义。
Q6. Pulsar 中承担数据持久化存储的组件是哪个?
- A.各分区本地磁盘缓存
- B.独立的 Zookeeper 集群
- C.BookKeeper 存储集群← 正确答案
- D.无状态 Broker 节点
答案:C。Pulsar 的 Broker 无状态,数据统一存放在 BookKeeper 的 Bookie 节点上,相当于物流园区的共享总仓。Zookeeper 只做元数据协调,本地磁盘缓存的说法不成立。
Q7. 关于 ISR(In-Sync Replicas)机制的作用,正确的是?
- A.压缩消息以降低存储开销
- B.维护与主副本同步的副本集合← 正确答案
- C.将消息均匀分配到各分区
- D.保证所有副本数据强一致
答案:B。ISR 是“跟得上进度的副本清单”,只有清单内的副本才参与 acks 判定,落后太多会被踢出、追上了再拉回来。它保证的是“大多数副本已同步”,并非所有副本强一致,也从不负责压缩和分区分配。
Q8. Pulsar 相比 Kafka 的典型优势有哪些?
- A.Broker 无状态弹性扩容← 正确答案
- B.存储计算分离分层架构← 正确答案
- C.支持多租户命名空间隔离← 正确答案
- D.单分区顺序读写最优性能
答案:ABC。无状态 Broker 让扩容秒级完成,计算存储分离是架构基石,namespace 多租户解决共用集群的隔离问题,三者都是 Pulsar 的招牌。单分区顺序读写最优性能其实是 Kafka 的强项,Pulsar 多一跳存储未必更快。
Q9. 以下属于 RocketMQ 特色能力的有哪些?
- A.事务消息两阶段确认← 正确答案
- B.全局与分区顺序消息← 正确答案
- C.消息标签过滤机制← 正确答案
- D.计算存储分离架构
答案:ABC。事务消息两阶段确认、全局与分区顺序消息、Tag 标签过滤,都是 RocketMQ 的差异化能力。计算存储分离是 Pulsar 的架构特征,不属于 RocketMQ。
Q10. 以下属于 Kafka 生态组件的有哪些?
- A.Kafka Connect 数据集成← 正确答案
- B.Schema Registry 管理← 正确答案
- C.KSQL 流式查询引擎← 正确答案
- D.天然支持多租户强隔离
答案:ABC。Kafka Connect 做数据管道集成,Schema Registry 统一消息格式,KSQL 提供流式 SQL 查询,共同构成 Kafka 的生态护城河。多租户强隔离恰是 Kafka 的短板,并非其生态组件。