
这个选型问题我这两年至少被问了五十次。每次群里一聊起 Doris、StarRocks、ClickHouse必然有人贴一张“XX vs XX vs XX”的对比图然后一群人围绕“谁更快”吵到几百楼。吵到最后也没结论因为脱离业务场景谈快慢本身就是伪命题。我这些年给不少团队做过 OLAP 引擎的选型评估和线上问题排查自己也亲手维护过这三套集群。Doris 和 StarRocks 同源不同路ClickHouse 走的是另一条极致路线三者在架构、查询模型、更新能力、运维成本上的差异远比跑分数字更能决定你上线之后是否睡得着觉。这篇文章我打算用一张核心对比表打底然后把每个引擎适合什么场景、不适合什么场景讲透最后把我反复踩过的坑和排查经验一并放出来。适合正在做技术选型的数据开发、架构师以及已经装好集群但用起来不顺、天天在想“是不是选错了”的同学。1. 选型之前先想清楚三个问题1.1 三个引擎其实是三种设计哲学先泼一盆冷水Doris、StarRocks、ClickHouse 虽然都被叫“OLAP 引擎”但它们的出发点完全不同就像 SUV、跑车和皮卡都叫“车”上了不同路段表现天差地别。ClickHouse 的核心哲学是“单表分析做到极致”。它用列式存储加稀疏索引把单机扫描速度推到近乎变态的水平尤其在聚合大宽表、时间范围过滤这种查询上单机性能确实能压过很多分布式系统。但极致的代价也很明显高并发小查询不是它的强项数据更新UPDATE/DELETE是重操作分布式写入需要自己维护 Distributed 表集群层面的副本一致性、负载均衡能力也比较原始。Doris 的哲学是“融合”。它从一开始就面向实时数仓设计走的是 MPP 架构FE 负责元数据和查询规划BE 负责存储和计算。它支持明细模型、聚合模型、唯一模型和主键模型既能实时写入又能高效点查导入方式丰富语法兼容 MySQL 协议和 BI 工具、Java 生态的衔接天然顺畅。简单说Doris 想把“实时数仓 高并发报表 即席查询”这件事一把梭。StarRocks 和 Doris 系出同门早期代码同源随后走向独立演进。StarRocks 走了更激进的性能路线在 CBO 优化器、多表 Join、数据湖查询加速这些方向发力很猛物化视图和主键模型的实现也做了不少重构。它的定位更偏向“复杂分析和大规模查询都能打”同时在湖仓一体场景里能直接加速 Hudi、Iceberg、Paimon 等数据湖上的查询。这三种哲学决定了同一个 SQL在不同引擎上执行计划可以完全不同最终耗时差出十倍的情况都正常。所以选型第一步不是比参数而是想清楚你自己的业务到底属于哪种模式。1.2 先回答这三个问题再看对比表我建议你在看下面那张对比表之前先拿笔回答三个问题问题一你的核心查询长什么样是几十个并发、每个查询只带一个 ID 的高并发点查还是两三个并发、每条 SQL 都要扫几亿行做大聚合的分析如果是前者ClickHouse 大概率不是最优解如果是后者ClickHouse 又可能是最省钱的方案。问题二数据需要实时更新吗你的业务里有没有“对账修正”、“状态变更”、“频繁 UPDATE”这类需求ClickHouse 的 Mutation 机制会有后台异步重写数据频率一高频就非常吃力Doris 和 StarRocks 的主键模型则把更新设计成了一等公民。问题三团队有多少运维余量三套引擎都要运维但复杂度不是一个量级。ClickHouse 单机部署极其简单集群化之后副本同步、分布式表的坑不少Doris 和 StarRocks 的 FE/BE 架构天然就是分布式但组件多、监控项多、升级有讲究。团队如果没有专职数仓运维角色选型时就要格外看重“开箱即用”程度。不把这三个问题想清楚直接跳到下一节看跑分对比大概率会选错。2. 一张表看清Doris、StarRocks、ClickHouse 核心差异2.1 关键参数对照表我把三者的核心差异整理成了一张表刻意避开了具体版本号这种“看一眼就过时”的信息尽量写“设计层面不会短期内变化”的差异。这张表不是我拍脑袋写的是结合官方文档和我在多套集群上的实测得出的。对比维度Apache DorisStarRocksClickHouse定位实时数仓、高并发报表、统一分析高性能分析、数据湖加速、复杂查询单表超高扫描速度、日志与指标分析基本架构FE BEMPPFE BEMPP单机多核并行 Distributed 表开源协议Apache 2.0Apache 2.0核心Apache 2.0存储模型明细/聚合/唯一/主键明细/聚合/唯一/主键MergeTree 家族高频点查支持强前缀索引 倒排索引 布隆过滤器强前缀索引 布隆 Bitmap中等稀疏索引更适合范围扫描数据更新能力强主键模型实时更新强主键模型 Merge-on-Write弱Mutation 重、后台异步高并发能力强FE 规划 BE 多副本强弱并发一高 CPU/IO 容易毛刺复杂 Join 优化不错强CBO 优化器成熟度较高弱大 Join 需小心内存数据湖查询支持Hudi/Iceberg/Paimon强Data Cache 元数据缓存支持相对较弱导入方式Stream/Broker/Routine Load 等Stream/Broker/Routine Load 等INSERT Kafka 表引擎分布式写入需额外处理SQL 兼容性MySQL 协议友好MySQL 协议友好自有 SQL 方言部署复杂度中高多组件中高多组件单机低集群中高运维监控自带 FE/BE 监控体系自带监控体系和云厂商集成多依赖第三方监控较多这张表里最容易被忽略的不是“查询快不快”而是“更新能力”和“高并发能力”这两行。很多团队选型时只会压测大查询完全没考虑真实业务里动不动就要改状态、要支持几十个报表页面同时点查询结果上线后被这些“低频但致命”的场景击穿。2.2 表格里容易被误解的三件事第一件事ClickHouse 查询快不等于它就别用 Old?不对应该是“ClickHouse 查询快不等于它适合所有查询”。它的快建立在稀疏索引和列存扫描之上局部性极强的过滤比如WHERE id abc它也能做但并发一高CPU 和 IO 都要被多个查询瓜分延迟曲线会变得很难看。我见过有团队拿 ClickHouse 做面向用户的高并发接口查询结果就是每隔几分钟一个慢查询拖垮整个节点。第二件事Doris 和 StarRocks 用了同一套架构不等于可以直接互相替代。两者 FE/BE 的核心框架非常像但内部实现和运维参数差异已经很大。StarRocks 在 3.x 版本里对主键模型做了大量改造写入链路和合并机制和 Doris 的主键模型实现并不相同Doris 在 2.x 之后加入了 VARIANT 类型、倒排索引等功能两边 SQL 语法虽然大体兼容但一旦用了某个引擎特有的优化特性迁移时就要返工。第三件事开源协议的“Apache 2.0”不代表所有功能都免费无限制。三者核心都是 Apache 2.0 协议但商业版都额外提供了一些企业级功能、技术支持和企业级运维工具。选择的时候要看清楚哪些能力在社区版里就有哪些能力是商业版专属免得做完 PoC 之后采购流程卡壳。3. 真实场景选型指南我是怎么给业务拍板的3.1 场景一实时报表 用户画像 高并发查询选 Doris如果你的核心链路是“业务库 Binlog 实时入仓 → 宽表构建 → 面向运营和用户的高并发查询”那 Doris 几乎是这批产品里最顺手的。理由是它的主键模型天然适合拉链表、状态表这类高频更新场景。Flink CDC 直接写 Doris 主键模型秒级可见不需要像 ClickHouse 那样拿 ReplacingMergeTree 做语义兜底。Doris 的高并发点查能力也经过了大规模业务验证利用前缀索引和建表时精心设计的 Key 顺序单表上亿行也能在毫秒级返回单条查询。我实操中的建议是Doris 建表时一定要琢磨前缀索引。前缀索引最多 36 个字节把查询频率最高的等值条件字段放在最前面收益立竿见影。如果业务里还得支持 JSON 半结构化数据Doris 2.1 的 VARIANT 类型可以直接建列省掉提前拍平 JSON 的麻烦。Java 侧接入的时候要注意驱动版本太老的 JDBC 驱动对 VARIANT 类型的映射会有问题取出来的字段会被当成普通字符串需要业务自己解析。3.2 场景二复杂分析 数据湖加速 还想保留高并发选 StarRocks我和 StarRocks 的团队聊得比较多他们的重点一直在“复杂查询”和“湖仓一体”上。如果业务里有一堆多表 Join 的大查询或者数据分散在数据湖上需要加速StarRocks 值得重点测试。StarRocks 的 CBO 优化器在多表 Join 的 Join 重排、谓词下推、Runtime Filter 上做得比较扎实。我自己测过同样一套 TPC-DS 的查询集StarRocks 在 30 条长查询上的整体耗时明显优于我优化过的 ClickHouse也优于同配置下的早期 Doris。StarRocks 的 Data Cache 功能能把数据湖上的热数据缓存到本地用 Paimon/Hudi 做湖仓一体时查询性能提升非常可观。需要注意StarRocks 对内存的敬畏心不如 ClickHouse 那么强大查询没控制好内存上限会拖垮 BE。线上务必配好query_mem_limit并且把资源组或队列的并发上限卡住。否则一个失控的SELECT就能让同节点上的其他查询集体超时。3.3 场景三超大规模日志 单表聚合 低并发选 ClickHouse如果你做的其实是“日志分析”或者“指标监控”这类场景查询特征就是低并发、大扫描、大聚合ClickHouse 仍然是性价比之王。流程日志动辄一天几十亿条ClickHouse 的列存压缩比能把磁盘占用压到很低的水平。它单机多核并行扫描的能力极其强悍配合分布式表横向扩展后PB 级日志的聚合查询也能跑得动。另一个优势是部署简单单机一个二进制就能跑起来不像 FE/BE 那套动辄要规划角色、配集群。但用 ClickHouse 要有觉悟高并发短查询不是它的主战场UPDATE 和 DELETE 要慎用数据一致性和事务能力都比较弱适合“写进去基本不改”的数据。如果业务里有两张上亿大表频繁 Join我建议你先做一番压力测试再决定不要被单表查询的优秀表现迷惑。3.4 场景四团队运维能力和生态协同才是真正的隐形变量除了业务查询特征团队运维能力真的是选型里最容易被低估的变量。ClickHouse 单机部署门槛最低但集群化运维一点都不轻松。副本配置、分布式表 DDL 同步、跨节点查询路由、ZK/CLickHouse Keeper 的维护都是暗坑。Doris 和 StarRocks 虽然组件多但 FE 可以多活、BE 可以滚动升级官方文档对扩缩容、副本均衡、监控告警的描述也比 ClickHouse 更贴近“数仓产品”的运维习惯。团队如果已经上了 Kubernetes 且习惯用 Operator 管理有状态服务Doris/StarRocks 的 Operator 都更成熟一些。另一个考虑是生态。如果团队已经是 Flink Kafka Hive 的技术栈Doris 和 StarRocks 都有完善的 Connector能直接对接数据湖和 CDC 链路ClickHouse 在这些场景里也能用但中间需要自己写不少胶水代码。4. 实操踩坑实录从安装到线上最常见的几个深坑4.1 安装部署期踩的坑很多新手在安装阶段就被劝退了日常被搜得最多的就是“doris安装部署”、“clickhouse 最新版下载”、“ubuntu 26 安装clickhouse”这类词。我统一说下我的经验。ClickHouse 在 Ubuntu 新版本上安装最容易遇到的问题是和系统 glibc 版本不兼容。比如 ubuntu 26 这类新系统用官方 apt 仓库装老版本 ClickHouse 经常会报依赖错误或直接启动失败。我的做法是直接下载官方最新的tgz包解压运行或者用官方 Docker 镜像。切忌随便找第三方维护的 RPM/DEB 包版本太旧很容易踩到内核和 libc 的坑。另外ClickHouse 新版对 CPU 指令集有要求装完先clickhouse-local --version验证一下能否正常拉起。StarRocks 的 Docker 部署也经常有人卡住比如unable to find image starrocks/allin1-ubuntu:3.3.2 locally这个报错多半是镜像 tag 拼写不对或镜像源里没有这个版本。去 Docker Hub 官方仓库确认准确的 tag 列表或者直接用docker pull starrocks/allin1-ubuntu:latest。国内网络环境下记得给 Docker 配好 registry mirror不然拉镜像也会断断续续。Doris 的安装其实最省心官网的二进制包和 Docker Compose 方案都比较成熟。唯一要注意的是机器内存不能太小官方建议至少 8GB 起步。我见过有人在 4GB 的机器上硬跑 DorisBE 进程反复 OOM查了半天才发现是资源不够。4.2 运行期经典报错与排查思路运行期的问题我先分享三个被搜索频率最高的也是我亲手排查过的。“starrocks transmit chunk rpc failed”这个报错是 StarRocks BE 节点之间在执行查询计划时传输数据块Chunk的 RPC 失败。我排查过几次原因集中在三类一是网络抖动或防火墙拦截了 BE 之间的通信端口二是 BE 的 brpc 内存配额打满导致无法分配新的传输块三是某个 BE 节点负载过高RPC 响应超时。排查思路是从日志入手。先看 BE 日志里的 WARNING 和 ERROR确认报错发生在哪个 BE 和哪个查询再用netstat或ss检查 BE 之间的通信端口是否正常同时打开 StarRocks 的监控面板看各 BE 的内存使用率。如果内存长期高位就调大mem_limit或降低并发如果网络有丢包先解决网络再做参数调整。“doris慢查询优化”Doris 慢查询的常见原因我按出现频率排个序没命中分区裁剪。查询条件里没带分区字段或者分区字段被函数包裹导致全分区扫描。前缀索引设计不合理。Prefix Index 长度有限等值过滤字段没放在 Key 的前面导致退化成全表扫描。分桶数设置不理想。分桶太多会导致 tablet 数量过大、查询调度开销高分桶太少则单 tablet 扫描压力大。大表 Join 发生了严重的数据 Shuffle网络传输成为瓶颈。优化手段也很直接先用EXPLAIN查看执行计划确认是否命中了分区裁剪和分桶裁剪再把高频过滤字段挪到 Key 前列必要时加布隆过滤器或倒排索引对高频大查询建立物化视图或 Rollup 表来覆盖。Doris 的 Profile 功能set enable_profile true能看到每一步的耗时分布这是定位慢查询最有效的工具。“clickhouse的part命名”ClickHouse 的 MergeTree 表在磁盘上会拆成很多 part目录命名类似20240101_0_9_1。这个命名里的四段分别是分区值、最小 block 编号、最大 block 编号、合并层级。part 数量一旦膨胀查询时要扫描的 part 变多后台 merge 线程也会持续繁忙最终导致写入和查询都变慢。处理手段是通过system.parts表查看 part 数量和大小分布如果 part 过多合理收窄分区粒度或者用OPTIMIZE TABLE ... FINAL手动触发合并。写入端也要控制插入批次避免高频小批量插入造成大量小 part 堆积。还有一个经验是给表设置parts_to_throw_insert阈值防止 part 无限膨胀拖垮写入。4.3 数据模型设计上容易被忽略的细节数据模型选择直接决定后期查询体验但这块恰恰是很多团队跳过不看的。Doris 和 StarRocks 的四种数据模型里主键模型PRIMARY KEY适合实时更新场景聚合模型AGGREGATE KEY适合预聚合场景唯一模型UNIQUE KEY适合去重场景明细模型DUPLICATE KEY适合日志类场景。很多人建表时图省事全用明细模型后期做实时更新时才发现要重构表结构代价很大。ClickHouse 的 MergeTree 家族也是类似道理。ReplacingMergeTree 适合需要去重的场景SummingMergeTree 适合数值累加场景AggregatingMergeTree 适合预聚合场景。如果选错引擎要么数据重复要么聚合失效排查起来非常痛苦。Doris 2.1 的 VARIANT 类型也是一把双刃剑。它能直接存储 JSON方便是很方便但如果查询里频繁提取 JSON 字段且数据量极大性能还是不如提前建好普通列。我的经验是能用普通列建模的字段就建普通列VARIANT 只用来兜底那些真正多变、没法提前建模的半结构化字段。5. 迁移与混合部署的一些经验5.1 从 ClickHouse 迁移到 Doris 的体验我操盘过几次从 ClickHouse 迁移到 Doris 的项目过程比想象中顺利但有几个语法坑得先说清楚。ClickHouse 的arrayJoin表和 Doris 的explode函数语义接近但写法不同迁移时需要改写 SQL。ClickHouse 的物化视图是“插入时触发聚合”Doris 的物化视图是“查询时透明改写”两者机制完全不同迁移时不能一一对应要重新设计。ClickHouse 的 Distributed 表写入需要手动指定Doris 直接写表即可简化了很多。数据导入层面ClickHouse 的高频小批量插入在 Doris 上要改成攒批导入否则 BE 小文件太多会拖慢 Compaction。整体来看如果原业务以实时报表 点查为主迁移到 Doris 后的查询延迟和运维体验会明显好转。5.2 多引擎并存是否可取多引擎并存听上去很“专业”实际是给运维团队上强度。但某些场景下确实有必要日志分析继续留在 ClickHouse实时数仓和 BI 报表走 Doris 或 StarRocks数据湖查询用 StarRocks 做加速。这套组合的优势是每个引擎都干自己最擅长的事劣势是数据链路易碎同样的表要在多套系统里各存一份同步链路的延迟和故障点都会增加。我的建议是除非团队有明确的数仓平台组能扛住多引擎的监控、告警、数据同步否则尽量收敛到一到两个引擎。多数业务团队其实一台 Doris 或 StarRocks 就能覆盖实时数仓和报表需求真没必要把组件数量堆起来。6. 最后再分享一点个人心得选型这件事回头看真正起决定作用的往往不是某个跑分而是你后来半年里每天要面对的那些细节查询并发毛刺、更新延迟、物化视图刷新的效率、扩容时是否要停写、凌晨 merge 有没有拖慢导入。愿意把这些细节提前摆到桌面上讨论的团队选哪个引擎都不会太差只盯着“谁最火、谁最快”做决定的用一段时间大概率还要回炉重选。我个人的实操体会是先拿自己最难受的三条查询去压测再模拟真实并发和更新频率跑一跑最后让未来负责运维的人参与 PoC 打分。Doris、StarRocks、ClickHouse 各有各的位置没有绝对的好只有适合不适合你。希望这篇文章能让你少走一点我走过的弯路。