本文由 Google Gemini 生成,仅供参考。
问题背景
本文是对近期数据仓库建设过程中,Doris 集群在高并发、混合负载下查询性能严重不稳定问题的深度复盘。集群的核心使命是同时承载后台批量的 ETL 任务与前台高并发的即席查询及报表任务。我们观察到,在 ETL 高峰期,查询服务的 Latency 和稳定性急剧下降,严重影响了数据消费端的体验。
核心矛盾的识别
经过层层追溯,我们将问题的根源归结于一个数据仓库架构中的经典“不可能三角”:对于一张巨大的、需要持续进行行级别更新的全量明细事实表(如订单表),我们期望同时满足三个相互冲突的目标:
- 简便的行级更新:ETL 逻辑简单,能轻松处理历史数据的状态变更。
- 基于全量明细的查询加速:能够直接在更新后的明细表上创建物化视图等预计算结构,以加速查询。
- 可接受的 ETL 成本:数据加工和写入过程的资源消耗和时间开销在可控范围内。
我们当前的架构和实践,正是在试图同时达成这三点而不得的过程中,导致了系统性的问题。
对当前架构的反思:三个关键“反模式”
-
为简化 ETL 而“滥用” AGGREGATE KEY 模型
为规避在 ETL 中处理复杂大 JOIN 的难题,我们采用了一种“分批写入、自动合并”的技巧:将 DWS/ADS 层的表设计为 AGGREGATE KEY 模型,并利用其 REPLACE_IF_NOT_NULL 特性,通过多次 INSERT 来模拟对同一行数据的“列式更新”
- 查询限制: AGGREGATE KEY 在聚合和宽表场景下性能优越,其查询限制主要体现在聚合函数固定和无法再建物化视图。
- 写放大: 一次逻辑上的“行更新”,被分解为多次物理上的 INSERT 和后台 Compaction。
-
非对称副本策略导致的“伪隔离”
为隔离负载,我们采用了
etl:2, online:1的副本分布策略。然而,Doris 的 Quorum 写入机制(3副本至少写成功2个)使得所有 ETL 写入操作都必须跨越隔离带,将数据写入到 online 节点。-
隔离失效: online 节点在 ETL 期间成为了“写前线”,I/O 和 CPU 资源被持续抢占,本应被隔离的查询服务受到了严重干扰。
-
可用性风险: 查询服务依赖的 online 节点成为了单点,一旦其故障,查询服务将中断。
-
-
对“可更新事实表”处理的误区
在探讨解决方案时,我们曾考虑过使用 DUPLICATE KEY 模型(以支持物化视图)并采用“分区覆盖”或“整表交换”的方式来处理数据更新。但很快意识到:
- 分区覆盖不可行: 订单等事实表的更新是跨周期的(如1月的订单在10月更新状态),无法通过覆盖当前分区来更新历史数据。
- 整表交换成本过高: 对于我们超大的核心事实表,“每日重算并交换全表”的方案,其计算和存储成本高到完全不具备现实可行性。
这三个反模式的叠加,共同导致了当前集群不稳定的困境。
架构演进方案
既然不存在能同时满足三个核心目标的“银弹”,我们必须做出取舍。以下是我们推演出的两条逻辑自洽且可落地的演进路径。
路径一:Doris 体系内的“分层解耦”方案
此方案的核心是放弃“在一张万能表上解决所有问题”的执念,通过清晰的分层,让不同的表模型各司其职。
-
ODS/DWD 层 (数据明细层)
- 模型: UNIQUE KEY
- 职责: 维持现有模式。当前 CDC 数据已通过 UNIQUE KEY 模型同步至 ODS 层,这部分继续作为实时数据接入层。
-
DWS/ADS 层 (高性能查询层)
- 模型: DUPLICATE KEY
- 职责: 将当前为规避大表 JOIN 而设计的 AGGREGATE KEY 模型,改造为更灵活但 ETL 成本更高的 DUPLICATE KEY 模型。
- ETL 改造: ETL 任务负责从上游的 UNIQUE KEY 明细层抽取数据,在 ETL 过程中处理“合并更新”的逻辑,然后将结果写入 DUPLICATE KEY 表。这取代了之前利用 REPLACE_IF_NOT_NULL 特性的做法。
- 优势: DWS/ADS 层模型纯粹,查询灵活,且完全支持创建物化视图,可以最大化地满足查询性能需求。
-
资源隔离:
- 采用 BE 标签划分物理资源池(如
pool=query,pool=etl)与 Workload Group 进行逻辑资源管控的“两级”模式,实现彻底的资源隔离。
- 采用 BE 标签划分物理资源池(如
- 此路径的取舍: 接受了 ETL 流程的复杂性(需手动处理合并逻辑),以换取查询层的极致性能和灵活性。
路径二:评估 StarRocks 以实现“ELT 范式转型”
此方案旨在通过引入新的技术栈,从根本上破解“更新”与“查询加速”的矛盾。
-
核心技术: StarRocks 的 Primary Key 模型 + 异步物化视图。
- Primary Key 模型提供了比 Doris UNIQUE KEY 更高效的实时更新性能。
- 异步物化视图支持直接创建在 Primary Key 模型之上,并支持嵌套,它将视图的更新与主表的写入解耦。
-
新的 ELT 范式:
- L (Load): 将 CDC 数据流直接加载到 StarRocks 的 Primary Key 明细表中。
- T (Transform): 将 DWS/ADS 层的聚合、关联逻辑,以声明式的方式定义为多层嵌套的异步物化视图。由 StarRocks 内核自动、增量地完成数据转换。
- 此路径的取舍: 接受了物化视图中分钟级的数据延迟,换取了 ETL 逻辑的极大简化和开发维护效率的巨大提升。
结论与战略抉择
本次复盘清晰地表明,当前数据仓库的性能问题源于一系列相互关联的架构设计“反模式”。面向未来,我们面临一个关键的战略抉择:
-
选择路径一,意味着我们选择在现有 Doris 技术栈内进行深度优化和重构。这是一条“存量改进”之路,考验的是团队对数据仓库理论的深刻理解和扎实的 ETL 工程能力。
-
选择路径二,意味着我们考虑引入 StarRocks 进行技术升级。这是一条“技术换代”之路,旨在用更先进的特性从根本上改变开发范式,考验的是团队的学习能力和对技术迁移成本的把控。
两种路径没有绝对的优劣,最终的选择,取决于我们对 ETL 开发成本、数据时效性要求、以及未来数据平台长期演进方向的综合考量。需要对两种路径的核心技术点进行实际验证,以数据支撑最终的架构决策。