OLAP 引擎选型复盘Druid vs ClickHouse vs Doris 的决策过程一、选型背景去年团队做了一个数据产品升级核心需求是给业务方提供一个秒级响应的多维分析平台。业务方要能自己拖拽维度、筛选条件在百万级到十亿级数据量上做聚合查询响应时间要求 P99 在 3 秒以内。当时我们面临三个候选方案Apache Druid老牌实时 OLAP已经在公司内部有其他团队在用ClickHouse列存黑马社区热度极高单表查询性能炸裂Apache Doris百度开源的 MPP 架构号称一键开启实时分析这篇文章就是当时的选型复盘——我们怎么评估的最后选了哪个以及踩了哪些坑。二、核心需求与技术指标先明确我们的场景特点维度具体指标说明数据量日均 50 亿条保留 90 天总数据量约 4500 亿条查询并发峰值 50 QPS业务方同时拖拽看板的并发查询复杂度3-8 个维度5-15 个指标典型的 OLAP 多维聚合场景实时性延迟不超过 10 分钟离线和实时数据可以分开运维人力2 人不能上来就搞分布式调参成本敏感度中等不能无限加机器三、三个引擎的对比评测3.1 Apache DruidDruid 的架构设计非常工业化——它把数据摄取、存储、查询完全解耦每个组件都可以独立扩缩容。优点实时摄取能力很强Kafka 原生集成毫秒级延迟预聚合rollup机制对固定维度的查询非常友好社区成熟生产案例多缺点SQL 支持不完整Druid SQL 和标准 SQL 差距不小JOIN 能力弱架构组件多Coordinator、Overlord、Broker、Historical、MiddleManager...运维复杂对 Ad-hoc 查询即席查询维度组合不固定表现不佳存储成本高不压缩文本segment 文件大-- Druid SQL 的风格限制非常多 -- 只支持特定的聚合函数和简单的 GROUP BY SELECT TIME_FLOOR(__time, PT1H) AS hour, -- 时间维度必须用特殊函数 channel, COUNT(DISTINCT user_id) AS uv, -- COUNT DISTINCT 有近似和精确之分 SUM(page_view) AS pv FROM user_behavior WHERE __time TIMESTAMP 2026-07-01 00:00:00 AND __time TIMESTAMP 2026-07-08 00:00:00 GROUP BY 1, 2 -- 注意Druid 不支持 HAVING 子句的复杂表达式3.2 ClickHouseClickHouse 是近几年 OLAP 领域最火的引擎以单表查询性能著称。优点单表聚合性能真的是变态级别的快十亿级数据 count distinct 秒出结果完整的标准 SQL 支持JOIN、子查询、窗口函数都能用压缩率高默认 LZ4数据体积只有原始数据的 1/5 到 1/3运维简单单机部署一条命令搞定缺点高并发场景是短板默认配置下并发超过 20 就开始吃力实时写入需要依赖物化视图或外部工具Kafka Engine不是原生的流处理JOIN 性能对大表不太友好分布式 JOIN 的内存消耗大删改操作代价高MergeTree 家族的特性决定的-- ClickHouse SQL 和标准 SQL 几乎一致上手成本低 SELECT toStartOfHour(event_time) AS hour, channel, uniqExact(user_id) AS uv, -- uniqExact 精确去重uniq 近似去重 count() AS pv, avg(session_duration) AS avg_duration FROM user_behavior WHERE event_time 2026-07-01 00:00:00 AND event_time 2026-07-08 00:00:00 GROUP BY hour, channel HAVING uv 1000 -- 标准 HAVING毫无障碍 ORDER BY hour, uv DESC LIMIT 100;3.3 Apache DorisDoris 是百度开源的 MPP 架构 OLAP 引擎主打极简运维 MySQL 兼容。优点MySQL 协议兼容直接用 MySQL 客户端连接BI 工具Superset、Tableau无缝接入聚合模型Aggregate Key可以自动做预聚合对固定维度的查询性能极好运维真的很简单——BE 节点挂了自动迁移副本FE 节点用 BDBJE 做高可用支持标准 SQLJOIN 性能比 ClickHouse 好缺点社区规模比 ClickHouse 小遇到深水区问题不好找答案实时写入通过 Stream Load 或 Routine Load延迟在秒级不如 Druid单表极限性能不如 ClickHouse但差距在缩小更新模型Unique Key在大批量更新时性能会下降-- Doris SQL 兼容 MySQL 协议语法差异几乎为零 SELECT DATE_FORMAT(event_time, %Y-%m-%d %H:00:00) AS hour, channel, COUNT(DISTINCT user_id) AS uv, COUNT(*) AS pv, AVG(session_duration) AS avg_duration FROM user_behavior WHERE event_time 2026-07-01 00:00:00 AND event_time 2026-07-08 00:00:00 GROUP BY hour, channel HAVING uv 1000 ORDER BY hour, uv DESC LIMIT 100;3.4 对比总结维度DruidClickHouseDoris单表查询性能★★★☆★★★★★★★★★高并发支持★★★★★★☆★★★★SQL 兼容性★★☆★★★★★★★★★☆JOIN 性能★★★★★★★★实时摄入★★★★★★★★★★★★运维复杂度★★★★★★★★★★★社区活跃度★★★★★★★★★★★★存储成本★★★★★★★★★★3.5 基准测试数据我们用 10 亿条模拟数据做了基准测试以下是一些典型查询的对比import time from dataclasses import dataclass from typing import List dataclass class QueryResult: engine: str query_name: str response_time_ms: int error: str None # 基准测试结果模拟实际测试数据 # 硬件配置3台 32C128G 组成集群 benchmark_results: List[QueryResult] [ # Q1: 单维度聚合1天数据PV/UV QueryResult(Druid, 单维度日聚合, 1200), QueryResult(ClickHouse,单维度日聚合, 180), QueryResult(Doris, 单维度日聚合, 350), # Q2: 三维度交叉7天数据含COUNT DISTINCT QueryResult(Druid, 三维度7天聚合, 4500), QueryResult(ClickHouse,三维度7天聚合, 420), QueryResult(Doris, 三维度7天聚合, 680), # Q3: 多表JOIN 聚合7天数据 QueryResult(Druid, 多表JOIN聚合, 8000), # Druid JOIN极慢 QueryResult(ClickHouse,多表JOIN聚合, 2900), QueryResult(Doris, 多表JOIN聚合, 1500), # Q4: 高并发场景20并发取P99 QueryResult(Druid, 高并发P99, 1800), QueryResult(ClickHouse,高并发P99, 5200), # ClickHouse高并发是短板 QueryResult(Doris, 高并发P99, 2100), ] # 输出对比表 print(f{引擎:12} {查询场景:20} {响应时间:8}) print(- * 45) for r in benchmark_results: print(f{r.engine:12} {r.query_name:20} {r.response_time_ms:6}ms)四、最终决策我们最终选择了Doris。原因有三SQL 兼容性和 BI 工具对接。我们用 Superset 和 Metabase 做可视化Doris 的 MySQL 协议兼容意味着零改造接入这是 Druid 做不到的。运维人力匹配。两个人运维 Druid 那一套组件有点不现实Doris 的极简运维对我们来说是巨大的加分项。高并发支持。ClickHouse 单查虽然快但 50 QPS 的并发直接把它打趴下了。Doris 的 MPP 架构在高并发场景下表现稳定得多。当然没有完美的方案。Doris 在数据更新和深水区问题排查上时不时会遇到一些坑但整体来说是三个方案里最契合我们场景的。五、总结OLAP 选型没有银弹关键是把需求拆清楚再匹配SQL 兼容性是第一优先级。如果你的 BI 工具和数据分析师都需要写 SQL那 Druid 的方言就是致命伤。并发和单查性能要分清。ClickHouse 单查快但高并发差Doris 是全面的良好但单项不是最好。运维成本是最容易被低估的。架构炫不炫不重要出了问题你能不能在半小时内恢复才重要。社区和生态也要纳入考量。用的引擎至少要有 3-5 个公司在类似场景下验证过不然你就是踩坑先锋。最后补充一点不管选哪个引擎建表时的分区策略和排序键设计才是性能的决定性因素选型只是起点。