ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Apache Doris vs StarRocks:实时数仓选型与架构对比全解析

Apache Doris vs StarRocks:实时数仓选型与架构对比全解析 最近在好几个技术社群里都看到类似的讨论团队准备做实时数仓选型在 Apache Doris 和 StarRocks 之间反复犹豫或者已有 Doris 集群看到 StarRocks 的某些新特性又动了迁移的心思。这类问题放在两三年前其实不难回答但放到今天情况确实变了——两个项目在经历了一段时间的“同源竞争”后技术路线上的分歧越来越大各自的适用边界也越来越清晰。这篇就基于我个人的使用经验和对社区的观察把这两个系统从架构原理到落地实操重新梳理一遍给正在选型或打算迁移的朋友一些参考。先说清楚我自己的集群环境里两个系统都用过一套是 Apache Doris 2.1 做了主查询链路另一套 StarRocks 3.x 跑数据湖分析和部分实时报表。两边的线上问题都处理过不少下面的内容不站队只从技术特点和业务匹配度出发。读之前先搞清楚一个前提这两个项目同源于早期的 Palo 项目但经过这些年的独立演进它们在存储引擎、查询优化器、湖仓能力上的实现路径已经有明显差异今天再做选择本质上不是在选“谁更强”而是在选“哪条技术路线的取舍更适合你的场景”。1. 重新审视两个项目的“血缘”与分岔1.1 同源不同路为什么不能再用老印象看它们Apache Doris 和 StarRocks 的渊源很多老用户都清楚都是源自百度的 Palo 项目早期代码库高度重叠。但 2020 年前后团队分叉StarRocks 从 Doris 拉出独立分支后走了完全不同的发展节奏。这里有个关键认知要更新现在拿“Doris 1.x 时代的问题”去评价 Doris或者拿“StarRocks 早期不成熟”去评价 StarRocks都是刻舟求剑。Doris 进入 Apache 基金会后走的是社区共识驱动的路线版本迭代相对审慎但 2.x 系列完成了一次大换血——引入 Nereids 全新查询优化器、原生向量化执行引擎全面落地、Unique Key 模型的 Merge-on-Write 支持、异步物化视图、多 Catalog 数据湖联邦查询这些都是实打实的大版本更新。StarRocks 则更激进从设计之初就把“极致的查询性能”和“湖仓一体”放在最优先级在向量化执行上走得早也走得深同时把主键模型做成了支持高频实时更新的强力类型3.x 之后更是强化了数据湖分析能力直接对标 Snowflake 的架构理念。所以今天比较这两者先要把“谁继承谁”这种历史包袱放下把它们当成两个独立演化的现代 OLAP 系统来评估。1.2 为什么“今天”值得重新比较三个触发点第一实时数仓的负载形态变了。以前 OLAP 主要是 T1 的离线报表用 Doris 或 StarRocks 跑跑预聚合查询就很够。现在越来越多业务要求实时写入、秒级可见、点查与聚合查询混合这直接考验主键模型和导入链路的实时性。第二数据湖技术爆发式成熟。Hive、Iceberg、Hudi、Delta Lake 在湖仓一体架构中的地位越来越重两个 OLAP 系统都把“直接查数据湖”作为卖点但实现路径和实际性能差异很大。这就引出热词里常被提到的“starrocks hive clickhouse”对比——大家在选型时真正关心的是查询数据湖时能不能达到接近查询本地表的性能能不能直接做联邦查询第三社区和商业支持的格局变了。Doris 背靠 Apache 基金会和多家厂商的共建StarRocks 则选择了商业化开源路线背后的商业公司推动力度很大更新节奏快。这种差异直接影响 Bug 修复速度、新功能落地时序、企业版工具链的完整度对做技术选型的人来说这不能不看。2. 核心架构差异拆解从存储到执行的路线之争2.1 存储引擎列式存储的“同与不同”两边的底子都是列式存储数据以 Segment 文件形式组织按列独立编码和压缩。很多人以为这部分两者差不多但细看有区别。Doris 的存储引擎在 2.x 版本完成了 Segment V2 的全面切换支持 ZSTD 压缩、Bitmap 索引、Bloom Filter 索引以及 Unique Key 模型的 Merge-on-Write写时合并。这里“写时合并”值得多说一句在老版本里Unique Key 模型的更新是读时合并Merge-on-Read查询时要动态合并历史版本数据主键冲突多时性能退化明显。改成写时合并后导入阶段就完成主键去重查询路径不用再做归并点查和聚合查询的稳定性大幅提升。这个改进对实时更新的业务场景是质的飞跃。StarRocks 的存储引擎沿袭了 Doris 早期架构但做了大量底层改造使用全局低基数字典、按列级别做 Zone Map 索引、支持更细粒度的二级索引。在主键模型上StarRocks 从一开始就走 Merge-on-Write 的实现而且做了进一步优化——主键索引支持 Hash Index 和持久化索引大数据量下内存占用控制得比很多同类系统好。实际测试里高频更新场景下 StarRocks 的主键模型表现确实更稳。2.2 执行引擎与查询优化器向量化与代价模型执行引擎方面两个系统现在都实现了向量化执行但落地的深度和成熟度有差异。StarRocks 在向量化上起步早整个执行链路从算子到函数都做了向量化重写SIMD 优化比较彻底。Doris 的向量化引擎在 2.x 也基本完成但部分复杂表达式和 UDF 场景下仍有行式处理回退导致极端情况下性能和 StarRocks 有差距。查询优化器上Doris 的 Nereids 是一个自研的基于代价的优化器CBO从 2.0 开始逐步替代旧优化器实现了多阶段统计信息、动态分区裁剪、Runtime Filter 下推等能力。StarRocks 则采用基于 Cascades 框架的优化器这个框架源自 SQL Server 的优化器设计在复杂多表 Join 的 plan 搜索上更系统对 Join 重排、CTE 优化、分布式执行计划生成的支持更完善。从我的经验看三表以上 Join 的复杂查询StarRocks 更容易产生稳定的执行计划而 Doris 在新版优化器下表现也很不错个别场景需要手动调 Join 顺序。2.3 数据湖分析一条关键分水岭这可能是今天对比中最不能忽略的差异点。Doris 的多 Catalog 方案允许直接映射 Hive Metastore、Iceberg、Hudi、Delta Lake 等外部数据源查询时通过外部表方式访问支持谓词下推。但在实际使用中对 Iceberg/Hudi 这类有事务层的表格式Doris 的下推深度和统计信息利用还有提升空间复杂查询容易把大量数据拉到 Doris 侧处理导致查询延迟偏高。StarRocks 在湖仓一体上投入明显更重。它的 External Catalog 不仅支持多种数据源还对 Parquet/ORC 文件做了本地化缓存和索引加速配合 Pipeline 执行引擎查询数据湖的性能接近查询内表。它甚至支持在数据湖表上创建异步物化视图把湖上的高频查询透明加速。很多人关心的“starrocks hive clickhouse 对比”里StarRocks 的卖点就是“直接取代 Hive 查询引擎 弥补 ClickHouse 多表 Join 的短板”这个定位在湖仓一体架构里确实有吸引力。2.4 负载模型对比速查对比维度Apache DorisStarRocks存储格式Segment V2ZSTD/Bitmap/BloomFilter列式存储 全局字典 Zone Map主键更新Unique Key 支持 Merge-on-Write主键模型原生 Merge-on-Write 持久化索引查询优化器Nereids CBO2.x 后全面启用Cascades 框架 CBO向量化执行2.x 全面落地个别 UDF 场景有回退从头向量化覆盖面更彻底数据湖分析Multi-Catalog 联邦查询下推深度一般External Catalog 缓存加速 湖上物化视图实时写入能力Stream Load 成熟高频导入需调优主键模型实时性更强适合秒级可见场景社区与迭代Apache 基金会治理版本审慎商业驱动版本迭代快3. 实操对比部署、建表与查询调优的真实差异3.1 部署形态与资源规划两个系统在部署架构上极其相似都是无共享的 MPP 架构分为 FEFrontend负责元数据管理和查询规划、BEBackend负责数据存储和计算。这种架构的好处是扩容方便坏处是 FE 高可用和数据一致性都要自己维护好。实操中Doris 和 StarRocks 对 FE 的内存都有要求建议至少 16GB 起步元数据量大时 32GB 以上比较稳妥。BE 节点建议按数据量估算内存列式存储对内存带宽敏感CPU 主频高的机器跑查询更占优势。一个我自己踩过坑的细节虽然两者都推荐 SSD但 StarRocks 在数据湖查询场景下对本地缓存盘的 IOPS 要求更高如果要用它的湖加速能力尽量给 BE 挂高性能 SSD。部署方式上两边都支持 Docker 和裸机部署K8s 部署也都有 Operator 支持。如果是生产环境我更建议裸机或虚拟机部署性能更可控测试环境用 Docker 快速起一套就够了。3.2 建表与模型选择一个例子讲清楚以一个常见的订单明细表为例两边建表语句大体相似但细节有讲究。-- Apache Doris / StarRocks 通用建表示例 CREATE TABLE orders ( order_id BIGINT, user_id BIGINT, product_id BIGINT, category_id INT, amount DECIMAL(12,2), order_status TINYINT, order_time DATETIME ) DUPLICATE KEY(order_id) PARTITION BY RANGE(order_time) () DISTRIBUTED BY HASH(user_id) BUCKETS 32 PROPERTIES ( replication_num 3, storage_medium SSD );上面的表用了 Duplicate Key 模型适合明细查询不更新。如果业务上需要按订单维度更新比如订单状态从“待支付”变成“已支付”就应该用 Unique Key 模型-- 使用主键/Unique 模型实现实时更新 CREATE TABLE orders_unique ( order_id BIGINT, user_id BIGINT, product_id BIGINT, amount DECIMAL(12,2), order_status TINYINT, update_time DATETIME ) PRIMARY KEY(order_id) DISTRIBUTED BY HASH(order_id) BUCKETS 32 PROPERTIES ( replication_num 3 );这里特别提醒一个实操注意点Unique/主键模型在数据量大的时候导入性能受主键数量影响很大。如果导入任务经常出现版本冲突调整分区粒度、增加分桶数往往比调大内存更有效。两边都有这个规律但 StarRocks 的持久化索引让主键规模大时的稳定性更好Doris 则建议控制单表主键数量必要时做冷热分离。分桶数的选择也是经典问题。经验上单个桶的数据量控制在 1GB 到 3GB 之间比较合适分桶字段要选择高基数且查询过滤常用的列。很多人直接按默认建表结果数据倾斜后某些查询慢得离谱这种情况优先检查分桶字段和分桶数。3.3 导入链路的配置要点实时数仓场景里导入链路是最容易出问题的环节。Doris 的 Stream Load 是使用最多的导入方式一条 HTTP 请求就能完成 CSV/JSON 数据导入支持原子生效、部分列更新。StarRocks 的 Stream Load 用法几乎一致兼容性做得很好从 Doris 迁到 StarRocks 时导入接口基本无需改写。但有一个差异值得注意StarRocks 在 3.x 架构中把导入写路径做了更多优化支持了“大批量高频导入下的小文件合并”自动处理。而 Doris 在高频小批量导入场景下如果调度不当容易产生大量小 Segment 文件导致 Compaction 压力大、查询变慢。解决方法也简单尽量攒批导入控制导入频率在每分钟 10 批次以内或者调大“cumulative_compaction”相关参数。我自己维护 Doris 集群时就习惯给实时写入的表设置较短的 Compaction 间隔避免业务高峰期集中做合并。3.4 查询优化实践从执行计划到 Runtime Filter不管用哪个系统遇到慢查询第一步永远是看执行计划。两边都支持 EXPLAIN输出格式有点不同但核心看几点扫描行数估算是否准确、Join 顺序是否合理、是否存在数据倾斜、Runtime Filter 是否生效。Runtime Filter 是这类 MPP 数据库在大表 Join 小表时的重要优化手段。Doris 和 StarRocks 都支持自动生成 Runtime Filter但实际效果受数据分布影响。如果发现 Join 查询没有走 Broadcast 而是走了 Shuffle可以先强制 Join 顺序-- 以 StarRocks 为例利用 hint 控制 join 顺序 SELECT /* ORDERED */ ... FROM big_table JOIN small_table ON big_table.id small_table.id;这种手动干预在两边都通用是调优复杂查询的基本功。另外一个实操技巧是给过滤字段建合适的索引——Doris 的 Bitmap 索引在低基数列上的过滤效果明显StarRocks 则更适合利用 Zone Map 做区间裁剪两种玩法要按数据特征来。4. 常见问题与排查技巧实录4.1 导入延迟与数据可见性变慢现象实时导入任务积压查询看不到最新数据。排查思路先查导入任务的返回状态确认是否报错再看 BE 的 Compaction 队列是否积压。两边都有后台合并机制如果积压严重考虑降低导入频率、调整分桶数、扩大 BE 节点数。一个容易被忽略的问题节点时间不同步会导致数据版本时间戳错乱表现为“刚导入的数据查不到”或“重复数据”。这个问题我踩过不止一次NTP 同步一定要在运维规范里落实。4.2 查询突然变慢或内存溢出两个系统都是内存大户复杂 Join 非常吃内存。遇到 OOM 可以先做三件事检查查询是否存在笛卡尔积这种查询在 OLAP 里几乎必炸查看是否触发了全表扫描但过滤条件没下推尤其是数据湖外部表调大查询内存上限同时控制并发。StarRocks 有 Pipeline 执行引擎查询内存控制机制更精细可以限制单个查询的内存Doris 2.x 之后也有类似的内存控制能力但参数调优的经验值要按版本摸索。4.3 数据湖外部表查询性能差这是热词里最常被问到的一类问题。很多人以为配好 Catalog 就能直接快查 Hive结果第一次查询等了几分钟。原因基本是文件格式不是列式比如大量 textfile、min/max 统计信息缺失、未启用本地缓存。我的建议是数据湖表尽量转成 Parquet/ORC 格式并保证文件大小在 256MB 左右太小文件太多在 Doris 或 StarRocks 侧开启本地结果缓存重复查询能省大量远程读放大过滤条件要能落到分区列上否则全表扫描。如果你拿 ClickHouse 做对比这里也说句公道话ClickHouse 在单表扫描聚合上确实快得惊人但多表 Join、并发查询、数据更新上是硬伤。Doris 和 StarRocks 都是完整的 SQL 引擎Join 能力远强于 ClickHouse这决定了它们在复杂分析场景中更有通用性。4.4 版本升级踩坑记录Apache Doris 从 1.2 升 2.x 时很多老集群要重刷元数据升级前务必做 FE 元数据备份StarRocks 升级则要注意兼容性某些大版本间的 BE 滚动升级需要保持小版本连续。两边都建议先在测试环境完整跑一遍导入、查询、建表删表的回归再动生产集群。5. 场景化选型建议别问哪个好问你的场景适合哪套5.1 适合选 Apache Doris 的情况如果团队更看重 Apache 基金会的治理模式、希望避免绑定单一商业公司的技术栈业务以离线报表、T1 分析为主加上一定的实时导入需求对数据湖联邦查询要求不高主要分析场景集中在数仓内部表——Doris 是非常稳妥的选择。它在国内互联网公司有大量生产案例踩坑经验容易搜到社区活跃度也高。5.2 适合选 StarRocks 的情况如果业务对实时性有极致要求秒级甚至毫秒级更新可见、有大体量数据湖分析需求、希望用一个引擎统一“湖”和“仓”的查询入口StarRocks 的架构优势更明显。它在复杂 Join 上的稳定性和湖查询性能是实打实的商业公司提供的企业版工具链监控、备份、跨集群复制也能减少不少自研成本。缺点就是开源版和商业版的边界要理清楚有些高级特性只有企业版才有。5.3 迁移与共存一个务实路径已经有 Doris 集群又看中 StarRocks 的部分能力不一定只能做迁移。我的建议是先做“共存”验证把 StarRocks 集群搭起来通过 External Catalog 直连 Doris 表或者数据湖用真实查询对比两边的性能和稳定性再决定是否迁移。两边都支持标准 SQL遷移成本主要集中在建表语句转换、导入任务适配和 BI 报表的 JDBC 连接串修改上整体可控。从我个人的体会来说这两个项目的竞争对用户其实是好事——互相追赶让两边都在快速变强。选型没有一劳永逸的答案关键是把业务负载摸清楚把技术路线的取舍想明白用一套可复现的测试方法去验证而不是停留在论坛里的性能跑分口水战上。希望这篇文章能帮你少走些弯路。
返回列表