标签 OLAP 下的文章

导读:面对万亿级广告数据存量、日均 3 亿行增量及数千个复杂查询模板的挑战,快手广告数据平台如何突破性能瓶颈、实现架构统一与体验跃升?本文系统介绍了快手广告团队从 ClickHouse on ES 混合架构,全面迁移至 Apache Doris 的统一分析实践,最终实现查询性能提升 20~90%,写入吞吐提升 3 倍,存储效率提升 60%。

本文整理自快手高级计算引擎研发工程师 周思闽 在 Doris Summit 2025 中的演讲内容,并以演讲者第一视角进行叙述。

快手是国内日活过亿的短视频平台,其广告投放平台是商业化外部广告主与快手电商商家进行广告投放的主要阵地,支持客户在平台上进行广告物料搭建、物料管理、策略变更、数据查看等操作,这对底层数据系统的存储、计算与查询性能提出了极高要求。

要支撑如此大规模的广告投放与实时分析,底层数据架构面临巨大挑战。当前,快手的广告数据包括:由投放系统产生的物料数据以及用于数据分析的效果数据,这些数据呈现出三个显著特征:

  • 数据存量巨大:广告物料累计已达千亿级别,且随业务发展正向万亿规模迈进,存储体量位居公司前列,对架构扩展性提出极高要求。
  • 数据增长迅猛:仅 2025 年第一季度,日均新增广告物料数据同比激增 3.5 倍,要求底层引擎具备强大的实时写入与弹性扩展能力。
  • 数据模型复杂:整个数据体系涵盖约 700 个核心字段,涉及物料、投放、用户、效果等多个维度;同时,为应对多样化分析场景,沉淀的查询模板已超 4000 个,对查询引擎的兼容性与性能均是严峻考验。

架构演进:从分散存储到统一分析

01 早期架构及挑战

早期存储架构中,物料数据由 MySQL、Elasticsearch 协同存储;效果数据主要存储与 Clickhouse 中。

数据分析时,将分散在 MySQL、Elasticsearch 中的物料数据与 ClickHouse 中的效果数据进行高效关联查询,从而为广告主提供完整、及时的投放效果洞察。

01 早期架构及挑战.PNG

在如上所说的 ClickHouse on ES 架构中,用户提交的查询通常包含 Elasticsearch 外表(a)与 ClickHouse 内表(b)。ClickHouse 会解析查询中外表部分,将其转换为 Elasticsearch 查询语句,通过 HTTP 请求获取数据并封装为 Block,最后在引擎内部完成与内表的关联计算。

01 早期架构及挑战-1.PNG

然而,随着 Elasticsearch 中数据量持续增长,该架构逐渐暴露诸多问题:

  • 查询性能恶化:慢查询率上升至 35%,平均查询耗时达到 1.4 秒;
  • 存储瓶颈:Elasticsearch 单分片难以支撑 10 亿级以上数据量,扩容与数据重分布成本高;
  • 运维复杂度高:数据链路依赖组件多,运维与监控成本显著上升;
  • 问题定位困难:缺少 ClickHouse 与 Elasticsearch 之间的全链路可观测手段,出现查询延迟、数据不一致等问题时,需跨系统排查,耗时较长。

02 选型目标及调研

基于上述问题及挑战,我们为新架构设定了明确目标:

  • 慢查询率低于 5%;
  • 运维排查耗时降低至分钟级;
  • 支持单表万亿级别数据存储;
  • 保障数据实时性,延迟低于 5 分钟。

基于以上目标,我们对 Apache Doris、ClickHouse、Elasticsearch 等主流 OLAP 引擎进行了全面的调研与性能压测。测试涵盖了写入吞吐、查询延迟、存储压缩率、全文检索性能等关键维度。

02 选型目标及调研.png

在这过程中,ClickHouse 首先被排除,因其不支持唯一键模型,而广告物料数据存在大量更新场景,要求引擎具备主键更新能力。因此,重点在 Elasticsearch 与 Apache Doris 之间进行对比。

综合测试结果,Apache Doris 在写入性能、查询效率、存储成本及运维复杂度等方面均表现优异,不仅能够满足既定架构目标,还在多个场景下显著优于 Elasticsearch。因此,我们最终选定 Apache Doris 作为下一代广告数据分析引擎

03 基于 Apache Doris 的统一分析引擎

在实际应用中,我们引入 Apache Doris(计算引擎) 替换了原先架构中的 Elasticsearch、ClickHouse,设计了统一分析引擎 Bleem。通过在外部表模块中引入数据缓存层与元数据服务层,有效提升了跨源查询效率,使数据湖外表的查询性能接近内表水平,实现了关键的性能突破。

03 基于 Apache Doris 的统一分析引擎.png

具体来看,Bleem 架构自下而上分为 5 层

  • 存储层:数据湖中的 Hive/Hudi 数据存储于 HDFS;存算分离模式下的内表数据存放于对象存储 BlobStore;存算一体模式下的内表数据则存储于本地磁盘。
  • 缓存层:将 Hive/Hudi 外部表数据缓存至 Alluxio,保障 I/O 稳定性,提升数据读取效率。
  • 计算层:Apache Doris 为核心引擎。不同项目组对应不同的 Doris 集群,以实现计算资源物理隔离,用户可按需申请计算资源。依托于 Doris 湖仓查询能力,可直接对 Doris 内表与外部 Hive/Hudi 数据查询。同时,Doris 也支持存算一体与存算分离两种部署方式,可根据实际需求灵活选择。
  • 服务层:元数据缓存服务实时监听 Hive 元数据变更,并同步至缓存中,以提升湖仓外部表的查询效率。
  • 接入层:将 OneSQL 作为统一查询接入网关,提供集群路由、查询改写、物化改写、查询鉴权、限流与阻断等功能。

依托 Doris 强大的 OLAP 计算与湖仓一体能力,将此前分散的数据湖分析、实时 OLAP 查询、在线报表及全文检索等多种场景,统一整合至同一套引擎架构中,实现了技术栈的收敛与提效。该架构在实际落地中已带来显著收益:

  • 性能大幅提升:慢查询率低于 5%,整体查询性能提升了 20%~90%
  • 存储扩展高效:支持万亿级别数据存储,水平扩容效率较 Elasticsearch 提升 10 倍以上;
  • 运维大幅简化:一套引擎覆盖全部查询场景,系统依赖组件少,运维复杂度显著降低;
  • 可观测性全面加强:Doris 支持全链路追踪与全面监控,平均问题排查时间降低 80%

迁移实践及调优经验

整个迁移过程分为三个阶段,稳步推进以确保业务平稳过渡:

  • 第一阶段(试点验证):选取关键词推广场景进行试点,跑通全量与增量数据导入流程,搭建双链路并行验证数据一致性与查询正确性。
  • 第二阶段(主体迁移):迁移原 ClickHouse on ES 查询链路,将 Elasticsearch 中全量物料数据导入 Doris,完成业务切换后下线 Elasticsearch 集群。
  • 第三阶段(收尾统一):迁移剩余纯 ClickHouse 场景,将无需关联 Elasticsearch 的查询任务及其数据全部迁移至 Doris,完成整体架构统一。

在架构升级及迁移过程中,我们收获了许多实践及优化经验,在此逐一分享

01 解决极端场景下数据一致性问题

在数据导入层面,我们基于 SeaTunnel 实现流式数据同步,该方式支持批处理场景下的 Overwrite 语义,所有导入均采用两阶段提交机制,以确保数据同步的最终一致性。

而在基于 SeaTunnel 和 Spark 的数据同步过程中,我们遇到了极端场景下的数据重复问题。主要有两种情况:

  • Spark 推测执行时,两个 Task 同时写入同一份数据并均完成 Doris 两阶段提交,尽管 Driver 只认定一个 Task 成功,但数据已重复。
  • Spark Task 完成 Doris 提交后,在向 Driver 汇报前因抢占或异常退出,Driver 重启 Task 并重新写入数据。

为解决该问题,我们在 Doris 的两阶段事务提交环节引入了 ZooKeeper 分布式锁机制,通过记录并校验事务状态来保证批同步的一致性。具体流程如下:

  • 准备提交阶段,先获取 ZooKeeper 临时锁,确保同一时间只有一个事务进入提交流程;
  • 获取锁后,将 Prepare 状态写入 ZooKeeper 临时节点,并记录当前事务 ID;
  • 查询上一个事务的状态:

    • 若不存在,直接提交当前事务;
    • 若上一事务处于 Prepare 状态,则先回滚上一事务,再提交当前事务;
    • 若上一事务已 Commit,则直接回滚当前事务;
  • 最终将 Commit 状态写入 ZooKeeper 持久节点,完成本次提交。

01 解决极端场景下数据一致性问题.png

02 Stream Load 机制优化

为应对高并发数据导入,我们对 Apache Doris 的 Stream Load 机制进行了调优。通过合理配置任务优先级与合并(Compaction)参数,显著提升了写入吞吐与稳定性。Doris 内部通过 Load Channel 进行任务调度,以区分高优与普通优先级通道。

02 Stream Load 机制优化.png

调优的核心在于合理配置相关参数,例如当 Stream Load 任务指定的 timeout 时间小于 300 秒时,系统会将其判定为高优任务并分配至高优通道。参数优化如下

load_task_high_priority_threshold_second=300
compaction_task_num_per_fast_disk=16
max_base_compaction_threads=8
max_cumu_compaction_threads=8

03 差异化的建表策略

OLAP 引擎的查询性能很大程度上取决于表结构设计。因此,我们针对不同业务场景制定了差异化的建表策略:

物料表(高频更新与大规模检索):该表数据量极大且需支持实时更新。业务查询主要基于 account_id 进行过滤,而非原 MySQL 的自增 ID。为充分发挥 Doris 前缀索引与排序键的优势,在保证业务逻辑等价的前提下,我们将 account_idid 组合为联合主键,并将account_id 设为首个排序键及分桶字段,大幅提升查询过滤效率。同时配置倒排索引以支持多维检索,并选用 ZSTD 压缩算法平衡存储与 IO 性能。

-- 建表语句参考
CREATE TABLE ad_core_winfo
(account_id BIGINT NOT NULL,
id BIGINT NOT NULL, 
word STRING,
INDEX idx_word (`word`) USING INVERTED...) 
UNIQUE KEY(account_id,id) 
DISTRIBUTED BY HASH(account_id) BUCKETS 1000;

效果表(多维聚合分析): 相较于物料表,效果表侧重于数仓指标的累加与聚合。因此,我们直接采用聚合模型,并按照“天”或“小时”粒度设置分区。

-- 建表语句参考
CREATE TABLE ad_dsp_report
(__time DATETIME, 
account_id BIGINT, ...
`ad_dsp_cost` BIGINT SUM,
...) 
AGG KEY(__time,account_id,...) 
AUTO PARTITION BY RANGE(date_trunc(`__time`,'hour'))()
DISTRIBUTED BY HASH(account_id) BUCKETS 2;

04 大账户数据倾斜治理

在数据压测中,我们发现不同 Account ID 对应的数据量差异极大,小至个位数、大至百万级别,导致 BE 节点 CPU 负载严重不均。通过 SHOW DATA SKEW 命令进一步确认,Tablet 存储分布明显倾斜:大 Tablet 占用空间达 3–4 GB,小 Tablet 仅 100-200 MB,且大账户查询延迟较高。为此,我们实施了以下两点优化:

A:按账户范围进行分区

经分析,Account ID 为 5–8 位数字,且未来不会超过 10 位。因此使用 FROM_UNIXTIME 函数将 Account ID 转换为 Datetime 类型,按月对历史数据进行分区,共划分出 33 个历史分区。每个分区可容纳 2,592,000 个 Account ID,后续每新增约 200 多万个 Account ID 才会新增一个月份分区。同时,针对历史分区,根据数据存量进行手动分桶,新分区则默认设置为 256 个分桶。

该方案通过分区裁剪有效过滤了大量无关数据,同时为未来数据膨胀预留了扩展空间(物料表日均增量约 3 亿),显著降低分区增长对查询性能的影响。

B:对 Account ID 进行二次哈希

为缓解单个 Account ID 数据量差异过大导致的分布不均,我们选取与 Account ID 无关的 ID 字段,通过 ID MOD 7 计算得到一个取值在 0~6 之间的 mod 字段。将原本仅基于 account_id 的哈希分桶键调整为 (account_id, mod) 联合键,从而将同一 Account ID 的数据分散到 7 个 BE 节点上。

04 大账户数据倾斜治理.png

优化后,各 Tablet 大小基本均衡稳定在 1GB 左右,数据存储与查询负载得以在多个 BE 间均匀分布,有效解决了 此前 CPU 负载不均的问题。

05 万级分区下的查询优化

当分区数量达到万级别时,简单点查 SQL 的耗时达到 250 毫秒,远超 100 毫秒的预期。通过分析,耗时主要集中在 Plan 阶段,原因是 Doris(2.1 版本)在分区裁剪时,会遍历所有分区进行匹配,万级分区的顺序遍历开销巨大。

为此,我们将顺序遍历改为二分查找:对万级分区先进行排序,再利用二分查找快速定位目标分区,将时间复杂度从 O(n) 降至 O(log n)。优化后,该查询耗时从 250 毫秒降至 12 毫秒,性能提升超过 20 倍。目前,二分查找已在 Doris 3.1 版本中实现。

06 并发调优

在查询优化过程中,我们发现:多数查询经过条件过滤后,实际命中的数据量并不大,即便在大账户场景下,命中数据量也仅在百万级别。然而,Profile 显示这类查询的 Total Instance 数高达 800 个,其默认并发数为 32,存在明显的过度并发

为此,我们调整以下参数降低并发开销:

set global parallel_exchange_instance_num=5;
set global parallel_pipeline_task_num=2;

调整后,同一查询的 Total Instance 数量降至 17 个,查询耗时也显著缩短。这说明在小数据量点查场景下,适当降低并发可有效减少 RPC 开销,从而降低延迟(220ms 降至 147ms)。同时,这一优化也提升了系统的整体 QPS 承载能力。

收益及规划

经过上述架构迁移与深度优化,我们在三个核心维度取得了显著收益:

  • 查询性能大幅提升:关键词推广页平均查询延迟下降 64%,创意推广页延迟下降超过 90%,整体查询体验实现跨越式提升。
  • 写入能力显著增强:单节点写入承载能力提升 3 倍以上,单表实时导入峰值突破 300 万行/秒
  • 存储效率优化明显:通过分区策略与 ZSTD 压缩算法,存储效率较 Elasticsearch 提升约 60%,并可轻松支撑万亿级数据存储。

未来,我们将深度探索 Apache Doris ,重点围绕两方面展开:

  • 增强全文检索与分词能力:引入社区在 Doris 4.0 版本中推出的 BM25 打分功能,以及 IK 分词器等更多分词组件,实现按业务场景灵活选用最优分词方案。
  • 增强向量索引:基于 Doris 4.0 版本,在内表和数据湖外表场景下对向量检索的性能和边界能力做验证与优化。

本文完。您还可以阅读来自快手另一篇实践案以及中通快递、小米集团、顺丰科技用户故事来了解湖仓分析。

作者:朱奥 /淘天集团高级数据工程师

导读:双 11 等大促场景会在短时间内集中爆发:运营与业务 BI 在开卖后的窗口期密集访问数据产品,瞬时请求量陡增,对查询引擎的稳定性、成本与治理体系提出极高要求。与此同时,业务对近实时数据产品的诉求持续增强,传统“多存储、多链路、依赖回刷”的模式在研发效率、回刷成本与响应速度上逐步暴露瓶颈。

本文围绕 Paimon 与 StarRocks 的组合实践,梳理淘天在大规模 OLAP 查询场景下的架构演进与双 11 保障体系:通过实时与离线统一入湖,消除数据同步链路与多份存储成本;基于稳定中间层叠加在线现算与维表实时关联,将高消耗回刷转化为秒级查询,核心场景回刷效率提升约 80%,年化节省成本接近 1000 万;同时结合 StarRocks + RoaringBitmap 低成本解决跨天交叉实时 UV 计算难题,满足大促近实时决策需求。

1 淘天集团营销活动 OLAP 查询的探索背景与核心策略

1.1 当前数据架构

首先,简要介绍当前的数据架构与数据流转方式。

从 DWD 层开始,我们的数据分为实时与离线两条主链路:

  • 实时数据主要存储在 TT中,在业界可类比为 Kafka 一类的消息队列;
  • 离线数据主要存储在 ODPS 中。

在数据加工与写入层面,我们会启动 Flink 流批一体任务:

  • 实时侧持续消费 TT 中的数据;
  • 离线侧消费 ODPS 中的数据;
  • 在计算过程中,任务会关联多类 ODPS 维表,例如类目维表、商家分层等维度信息。
  • 计算完成后,结果统一写入 ADS 层的Holo 表中,并在数据服务层对外透出。

在纯离线场景下,我们会通过 ODPS 任务读取 ODPS 数据,同时写入 ADS 层对应的 ODPS 表。这里既包含历史天级数据,也包含历史小时级数据。当存在查询加速需求时,我们还会将 ODPS 数据进一步导入到 Holo 中。

在数据服务层,我们主要通过 Holo 或 MC 对外提供数据服务。我们会根据查询时延要求选择不同的服务路径:当业务对响应速度要求更高、需要达到毫秒级时,通常通过 Holo 提供查询服务;当时延要求相对宽松,例如百毫秒级或秒级,则更多通过 MC 来承载查询请求。

1.2 业务诉求与核心痛点

随着业务发展,我们当前面临的诉求主要来自两个方向:一是业务侧希望获得更多实时数据产品;二是业务 BI 的实时分析需求持续增长。这对数据研发提出了新的挑战:进一步提升研发效率。

回到现有架构,其核心痛点主要体现在两方面:

  • 流批存储不统一:实时数据存储在 TT 中,离线数据存储在 ODPS 中;当存在查询加速需求时,部分数据还需要进一步落到 Holo 表中。
  • 整体开发架构较为复杂,数据需要在多个存储介质之间流转,导致端到端链路拉长。

在查询特性上,Holo 在点查场景具备更突出的性能优势,且整体稳定性较强,在淘天历年大促期间的表现也相对稳定。

但在更常见的 Shuffle 场景下,整体查询性能相对一般。尤其当 OLAP 查询负载更重、需要进行更复杂的计算,或需要关联规模较大的维表时,Shuffle 相关的执行效率会成为瓶颈,导致查询耗时明显拉长。

数据更新与维护上也存在较高成本。以 ODPS 中的维表为例(如类目维表、商家分层维表等),当维表发生业务变更时,往往需要触发 ADS 层任务的回刷,从而带来额外的回刷开销。

业务对“近实时”的诉求在部分场景下出现了被动降级。例如在跨天实时 UV 等场景中,由于 state 规模较大、成本较高等原因,方案不得不从实时级别降级到小时级别。从业务视角看,近实时能力仍然是明确存在的需求。

1.3 核心策略

1)架构简化提效

  • 架构上实现 存储介质的统一:将实时与离线数据统一沉淀到 Paimon 的湖存储中。在此基础上, StarRocks 可以直接面向湖存储进行高性能分析查询,从而能够消除数据同步链路以及多份存储带来的成本。
  • 降低使用门槛,让数据更容易被上层分析与 BI 使用。以实时链路为例,原本实时数据存储在 TT 中,而 TT 的数据形态具有明显特征:每行数据是一个字符串、缺少 schema。在这种形态下,数据虽然可以被消费,但如果要面向 BI 分析使用,往往还需要额外进行反序列化与解析,这会带来不可忽视的工程与使用成本。

在统一存储之后,Paimon 将实时与离线数据沉淀在同一张表中,并提供明确的 schema。这意味着,上层使用方可以直接面向结构化数据开展分析:即使分析师的数据开发能力不强,也可以基于 Paimon 的近实时中间层,通过 StarRocks 自助完成对近实时数据的分析。

在这种模式下,过去一些相对简单的取数与分析需求,可以由 BI 或分析师通过自助方式直接完成,不再必须提交给数据研发排期处理,从而在一定程度上减少数据开发侧的需求量与交付压力。

2) 业务难点攻坚

通过稳定的中间层 Paimon,以及“OLAP 实时关联易变维度”的模式,将原本高消耗的 ADS 回刷任务转化为秒级查询来完成。在后续内容中,我会进一步展开这一改造如何将高消耗回刷去掉,并带来显著的成本收益——每年可节省近千万元级别的回刷成本。

同时,我们通过 StarRocks + RoaringBitmap 的方案,高性能解决了跨天交叉实时 UV 的计算难题,以更低成本的方式满足大促期间对近实时能力的诉求。

1.4 新数据架构

在秒级数据链路上,我们通过实时 Flink 任务消费 DWD 层的 Fluss(秒级实时数据),并将结果写入 ADS 层的 Fluss。

Fluss 提供“湖流一体”的同步开关。开启后,Fluss 中的数据会按配置周期自动同步到 Paimon 表中,默认周期可以是每 3 分钟,且该时间间隔支持用户自定义配置。同步完成后,Paimon 表中会形成当天分钟级数据(t 当天)以及 t−n 的历史数据。

在此基础上,我们会启动 Flink 流批一体任务,同时消费 DWD 层 Paimon 的 t 当天数据与 t−n 历史数据,并将加工结果写入 Paimon 表的 ADS 层与 DWD 层,分别沉淀 t 当天与历史数据。

此外,基于 Paimon 的 partial-update能力,我们也可以构建离线大宽表,用于承载同一业务对象的多状态聚合。以订单为例,订单存在支付、确收、退款等多种状态,可以构建一张以 order\_id 为主键的 Paimon 大宽表,将这些状态写入同一行记录。这样在使用侧只需读取对应 order\_id 的一条记录,即可获取该订单的多种状态信息,使用成本与分析便利性都会更高。

在 ADS 层,我们沉淀的计算结果主要面向“叶子粒度”的维度:例如类目侧以叶子类目为主;若涉及商家分层维表,则对应叶子商家分层。在数据服务层,我们通过 StarRocks 对外提供数据服务。具体而言,在 StarRocks 层既可以直接读取 ADS 层数据进行点查,也可以直接读取 DWD 层的中间层数据进行在线计算。后一种方式的查询负载通常更重、数据量更大,但在当前实践中,StarRocks 仍然能够将查询时延控制在秒级范围内,在查询量较大的情况下保持较快响应。在查询过程中,我们也可以进一步关联 Paimon 维表,最终将查询结果在数据产品端进行展示与交付。

在我们 的业务场景中,一般来说,DWD 层的中间层事实数据相对稳定;真正“易变”的往往是维度侧的数据,例如 Paimon 维表(类目维表、商家分层维表等)。当业务规则或口径发生调整时,通常只需要更新维表即可。相较于回刷大规模中间层数据,维表更新的成本更低、执行也更快。

更关键的是,我们在查询侧采用现算方式:维表更新后,查询会在读取中间层数据的基础上实时关联最新维表,因此中间层数据无需随业务变更反复回刷。由于中间层计算量较重,如果依赖回刷来响应业务调整,整体周期往往较长——快则一到两天,慢则可能需要一周。通过“更新维表 + 查询现算”的方式,业务变更后可以更快在数据产品侧看到最新结果。

在数据服务层,我们进一步利用 StarRocks 的 Warehouse 机制,对读集群进行隔离与分级保障,避免不同业务互相影响。我们按照业务重要性划分为三类:

  • 默认 Warehouse:保障级别相对一般;
  • 重保 Warehouse:承载最核心业务,保障级别最高;
  • 业务 BI 专用 Warehouse:面向业务 BI 或其他业务的专用资源池,保障级别相对一般。

2 Paimon+StarRocks 在双11大规模 OLAP 查询场景下的实践与优化

2.1 业务背景

在日常情况下,运营和业务 BI 往往在不同时间访问数据产品,因此 StarRocks的瞬时请求量(RPS)整体较低,压力相对平稳。

但在大促期间情况会明显不同。以开卖时段为例,运营和业务 BI 通常会在接下来的一小时内集中访问数据产品,导致 StarRocks 的瞬时请求 RPS 急剧升高,对 StarRocks 集群带来显著挑战。

因此,本部分的实践与优化工作主要围绕“大促场景稳定运行”这一目标展开。

2.2 集群侧保障

1)在应用层面推广数据集缓存策略:目前配置 180 秒的查询缓存窗口。也就是说,同一条查询在 180 秒内被多次触发时,实际下发到 StarRocks 执行的仅为首次请求;后续请求直接复用首次查询结果。通过该策略,可以有效降低大促高峰期 StarRocks 集群的瞬时压力。

2)集群层面的保护机制:集群侧设置了 30 秒的全局超时:如果一条 SQL 在 30 秒内仍未执行完成,会被自动终止。该机制属于 StarRocks 的集群保护能力,当查询执行时间超过 30 秒,即可判定该 SQL 需要进一步优化,不适合直接上线,需要回退并完成优化后再进入生产环境。对于少量确有必要、且在 30 秒内无法完成的特殊 SQL,也支持为单条 SQL 配置更长的超时时间。但此类 SQL 数量通常极少,上线评估也会更加严格,以确保不会对整体集群稳定性产生影响。整体目标是避免单条慢 SQL 拖垮集群。

3)架构层隔离:按业务重要性划分只读实例。基于业务重要性对只读查询资源进行分层,将不同业务的读请求隔离到不同的只读实例上,避免相互干扰。

4)集群初始化配置

在新的 StarRocks 集群初始化时,比较推荐先设置一套基础参数,如下:

  • set global cbo\_cte\_reuse_rate=0;

当 CTE 被多处引用时,可能触发同一数据源的重复读取。例如,一个表在 select 中读取三次,那么 StarRocks会对同一张 Paimont 表执行三次读取,读 I/O 开销相当于被放大为 3 倍。将该参数设置为 0 后,可使同一张表在同一条查询中只读取一次。

•set global query_timeout=30;

设置 30 秒的集群全局查询超时 避免单条慢 SQL 拖垮集群。

•set global new\_planner\_optimize_timeout=10000;

适当调大执行图优化器的超时时间。如果该参数设置过小,SQL 在调度过程中更容易直接失败;适当增大后,可降低 SQL 失败的频率。

•set global pipeline_dop=8;

调整 pipeline 的 DOP,用于控制每台机器上拉起的 driver 数量。压测结果显示,在大促场景中 SQL 请求高度集中,若 DOP 设置过大(例如 64),单条 SQL 在每台机器上会拉起大量 driver,带来调度开销飙升,甚至可能打满 driver 阻塞队列,导致 CPU 利用率反而上不去,集群进入不可用状态。

在我们StarRocks集群的双 11 压测中,DOP 调整到 8 时整体查询表现最优,因此给出 DOP=8 作为建议值。需要强调的是,该值是经验建议,最终仍应以各自集群的压测结果为准进行配置。

•set global scan\_paimon\_partition\_num\_limit=100; --限制scan paimon外表的最大分区,杜绝扫描全表的情况

限制 scan paimon外表的最大分区,用于杜绝因条件缺失或下推失败导致的全表/超大范围扫描。

2.3 核心指标监控

通过观察 StarRocks 核心指标的水位变化,可以持续评估实例健康状况。常用的核心指标如图。

2.4 报警规则

建立 StarRocks 实例的异常报警机制非常关键,它能够帮助及时发现实例异常并快速介入处理。报警项的设置通常围绕“资源水位、节点可用性、调度拥塞、查询失败与时延”几类核心信号展开,其中有一部分阈值来自大促压测与实战探索,具有较强参考价值:

  • BE/CN 的 CPU 与内存使用率设置阈值,例如当使用率持续高于 70% 时触发告警;
  • FE 的 CPU 与内存使用率同样设置 70% 的告警阈值;
  • 在可用性方面,可以监控 BE/CN 或 FE 的可用率是否低于 100%,一旦出现低于 100% 的情况,通常意味着有节点不可用或发生故障。
  • 当 BE 阻塞队列数超过 2000 时,StarRocks 集群的查询时延可能出现陡增;
  • 在查询侧,可以增加查询失败次数与查询时延分位数的告警,例如“查询失败次数大于 n”“查询延迟 TP99 大于 n”。其中 n 的取值需要结合业务特性与可接受的服务水平目标进行配置。

2.5 元数据监控

为更有效地治理 StarRocks的各类查询请求,可以实时获取审计日志,并基于审计日志构建元数据监控大盘,为后续的慢查询 SQL 治理提供数据支撑与定位依据。

select * from _starrocks_audit_db_.starrocks_audit_tbl;

审计日志相关数据落在 StarRocks 的内表中,对应信息可实时查询。也就是说,某条 SQL 执行完成后,可以立即在该内表中查到这条 SQL 的执行耗时等关键字段。基于这一基础能力,如果需要进一步做更细的源数据与查询行为监控,也可以围绕审计日志中记录的 SQL 信息进行扩展。

在监控大盘的组织方式上,支持按 Warehouse 维度拆分(例如划分为多个 Warehouse),同时也可以按数据集进行过滤。在筛选完成后,重点关注的数据字段通常包括:数据集名称、总 CPU 消耗、总查询大小、查询次数、查询行数、失败率与失败次数、单次查询的 CU 消耗、查询时间以及查询发起人等。这些指标支持排序与聚合,便于在优化过程中选取特定时间窗口,对总 CPU 消耗、总查询大小、总查询行数等维度进行 Top SQL 排查与治理。通过优先治理这些“高消耗/高影响”的 SQL,往往能够显著改善集群整体健康状况,因为在许多情况下,集群不稳定的根因来自少量高风险的“坏 SQL”。

2.6 大促保障

大促保障的目标,是把不确定性尽量前置消化,确保开卖高峰期间查询链路稳定可控。

  • 在资源侧,会结合历史数据与业务预测,在大促开始前对 StarRocks 集群进行主动扩容,并在大促结束后主动缩容。
  • 在需求侧,提前与业务负责人对齐本次大促的核心变更点,重点关注改造或新增页面,并将核心页面的 QPS 进行量化,为全链路压测与容量评估做准备。
  • 针对重保页面,我们还会建立一套智能应急机制,分为实例级与查询级两层。实例级故障切换方面,当 StarRocks 主实例不可用时,可通过自动化预案工具(FBI)将重保页面的查询请求批量切换到备库 Warehouse,完成实例级容灾;查询级自动容错方面,当重保页面出现单次查询失败或超时,系统会将该查询自动路由到备库 Warehouse 重试,尽量做到用户无感,为关键 SQL 增加一次“二次机会”,提升整体稳定性。

2.7 大促压测

大促压测通常分为两层: 核心页面单压与全链路压测。

在核心页面单压阶段,会先梳理大促期间的核心页面及新增页面,并对这些页面进行单独压测。这样做的目的,是尽可能在活动前置暴露并解决单点问题导致的性能瓶颈,为后续上线留出精细化优化空间。

在全链路压测阶段,会模拟“所有页面同时达到流量峰值”的极限场景,用以验证 StarRocks 集群在峰值冲击下的整体资源水位与关键性能指标是否符合预期。重点关注的资源水位通常包括 CPU、内存与 I/O,同时结合查询时延等指标,评估集群在极端并发与高负载下的稳定性与承载边界。

2.8 压测发现的问题和优化方案

1)分区裁剪失效或缺少分区过滤,导致扫全表

压测中发现,部分 SQL 因分区裁剪失效或未配置分区过滤条件,出现扫描范围过大甚至扫全表的风险。针对该类问题,治理原则是必须启用分区过滤并确保分区裁剪生效,不允许存在扫全表 SQL 在线运行。

分区裁剪生效的常见写法包括:对分区字段进行日期传参,直接基于分区字段触发裁剪;或使用日期函数触发裁剪,例如 date\_format、date\_add 等函数也可以触发分区裁剪。

分区裁剪失效的典型场景是分区字段与子查询结果进行比较,例如将分区字段与子查询返回的最小活动时间进行对比时,分区裁剪会失效。原因在于分区裁剪发生在 FE 阶段,而子查询需要到 BE 执行,FE 在规划阶段无法获得子查询结果,从而无法生成有效的分区裁剪信息。

2)读取 Paimon 生表时小文件过多,导致读取数据块数过大

压测还发现,读取 Paimon 表时存在小文件过多的问题。

定位方法:在 StarRocks 执行 SQL 时可开启 profile(通过 hint:/+ SET\_VAR(enable\_profile = true) /)生成 profile 文件;在 profile 中搜索 “metadata”,其中 nativeReaderReadNum 表示读取的数据块数,nativeReaderReadBytes 表示读取的字节数。实践中,当单个分区的 nativeReaderReadNum 大于 200 时,通常建议考虑对表进行排序治理。

优化方案:在构建流批排序Paimon表时,建议采用分支表模式:离线分支将 bucket 设为 -1,实时分支按需设置 bucket。离线分支表通过 clustering columns 指定排序字段,可支持指定多个字段(如 f1、f2),一般选择 OLAP 查询中最常用的过滤字段,以提升过滤命中与读取效率。该能力仅支持 Flink 批写入,不支持 ODPS 写入;写入表时需要使用 hint: /*+ OPTIONS('sink.parallelism' = '64') */。对于 ODPS 写入的 Paimon 表,则需要在任务下挂一个单独的 compact 排序任务。

为何有效:在双 11 场景下,活动周期往往持续数十天。当天数据属于实时增量,而从活动开始到昨天的历史数据占比更大;因此对离线数据进行表排序收益显著。压测实测显示,排序后读取的数据块数约为排序前的 1/1000。 离线分支完成排序后,活动开始到昨天(占比最大的历史数据)基本都处于“已排序、数据块读取量很小”的状态;实时分支由于无法排序,读取的数据块会相对多一些,但实时数据通常只存在于当天,整体占比小,因此对整条 SQL 的查询时延影响相对有限。

3)检查是否命中 MapJoin:小维表建议显式 broadcast

当 SQL 需要 join 小表(例如小于 10MB 的维表)时,建议在维表前显式加 broadcast,以触发类似离线 MapJoin 的执行策略。实测显示,引入 broadcast 后查询时延可显著下降,典型场景下可从十几秒优化到约 3 秒,整体查询时延约为原先的 1/3。

SELECT xxx FROM table_a t0 LEFT JOIN [broadcast] dim_table_b t1 ON t0.cate_id = t1.slr_main_cate_id AND t1.ds = 'xxx'

4)检查跨地域访问:计算与存储尽量同地域部署

还需要确认 StarRocks 实例与所读取的 Paimon 表是否处于同一地域。若不在同一地域,查询时延会明显增加。建议将 StarRocks 的部署地域与 Paimon 表存储地域保持一致。

5)主键表建议开启 deletion vectors:减少无效数据读取

对于 Paimon 主键表,建议开启 'deletion-vectors.enabled' = 'true'参数。该能力会在写入阶段记录哪些主键数据已被删除;读取时可跳过已删除数据,减少无效扫描,从而提升查询性能。非主键表不需要开启该参数。

3 阶段成果与未来规划

3.1 阶段成果

整体来看,该方案带来了四方面阶段性成果。

  • 数据链路得到简化:通过统一存储与统一查询面,消除了数据同步链路,并降低了多份存储带来的成本与复杂度。
  • 数据使用门槛显著降低:基于 Paimon 的实时/离线中间层,不仅数据开发人员可以使用,业务分析师也可以通过 StarRocks 自助消费近实时数据,从而减少部分简单需求对数据研发排期的依赖。
  • 回刷开销得到明显削减核心场景的回刷效率提升约 80%,年化节省成本接近 1000 万。其关键在于查询可以直接读取 Paimon 公共层并关联 Paimon 维表,业务变更时只需刷新维表,无需回刷与该维表相关的整条数据链路。
  • 在高性能实时分析方面,低成本解决了跨天交叉维度实时 UV 的计算难题,满足大促期间近实时决策需求。具体做法是将可累加指标(如订单数、订单支付金额等)与不可累加指标(如 user\_id)分开处理:可累加指标在查询侧直接聚合;不可累加指标则将 user\_id 做 RB 化后存入中间层,StarRocks 读取 Paimon 表时通过 RB 相关函数计算 UV。

3.2 未来规划

面向下一阶段,规划主要集中在四个方向。

第一, 希望 StarRocks 具备更强的自动物化能力:针对用户高频查询的 SQL 自动生成物化结果,并在后续查询中自动完成改写,直接命中物化表。由于物化表往往已经完成聚合,其数据量相较直接查询中间层可以小很多个量级,从而显著降低扫描与计算开销,进一步提升查询速度与稳定性。

第二,计划进一步 丰富 StarRocks 的元数据能力

第三, 优化 StarRocks 的调度策略,重点是调度层面的 CPU 负载均衡能力。

第四,希望 StarRocks 具备直接读取 Fluss 的能力,从而支持秒级查询场景。目前 Paimon 仍以分钟级链路为主,如果能够在读取侧进一步下探到 Fluss,将更好覆盖对秒级实时性有明确诉求的业务场景。

作者:ba0tiao
编者按:
在AI浪潮席卷全球的今天,有人认为传统关系型数据库已走向黄昏,MySQL 的生命力正在被边缘化。但事实真的如此吗?AliSQL,作为 MySQL 的重要分支,自2010年诞生以来,始终默默支撑着阿里巴巴集团核心业务的高并发、高可用需求。它从未消失,只是沉寂太久。
2026年,AliSQL社区的一帮开发者们,开始为AliSQL注入创新的血液!这是他们的第一篇,系统阐述了MySQL深度融合DuckDB的重大技术实践。这不仅是对“MySQL 只擅长 TP”这一行业共识的突破性回应,更是一次兼具工程魄力与架构远见的创新——在保持 MySQL 协议、语法、运维体系完全兼容的前提下,以轻量、高效、零侵入的方式,为MySQL 注入了 OLAP 能力。
国内首场《2026 AliSQL Innovate 用户大会暨 AliSQL DuckDB 开源发布会》将于2月3日在杭州开启!
席位有限,快来报名吧https://page.aliyun.com/form/act1162737496/index.htm

MySQL的插件式存储引擎架构

MySQL的核心创新之一就是其插件式存储引擎架构(Pluggable Storage Engine Architecture),这种架构使得MySQL可以通过多种不同的存储引擎来扩展自己的能力,从而支持更多的业务场景。MySQL的插件式架构如下图所示:
图片
MySQL的插件式存储引擎架构可以划分为四个主要的部分:

  • 运行层(Runtime Layer):负责MySQL运行相关的任务,比如通讯、访问控制、系统配置、监控等信息。
  • Binlog层(Binlog Layer): 负责Binlog的生成、复制和应用。
  • SQL层(SQL Layer):复制SQL的解析、优化和SQL的执行。
  • 存储引擎层(Storage Engine Layer):负责数据的存储和访问。
    MySQL在SQL计算和数据存储之间设计了一套标准的数据访问控制接口(Plugable Engine Interface),SQL层通过这个标准的接口进行数据的更新、查询和管理,存储引擎得以作为独立组件实现“热插拔”式集成。
    目前MySQL中常用的存储引擎包括:
  • MyISAM:MySQL最早使用的引擎,因为不支持事务已经被InnoDB取代。但是一直到MySQL-5.7还是系统表的存储引擎。
  • InnoDB:MySQL的默认引擎。因期对事务的支持以及优秀的性能表现,逐步替代MyISAM成为MySQL最广泛使用的引擎。
  • CSV: CSV文件引擎,MySQL慢日志和General Log的存储引擎。
  • Memory:内存表存储引擎,也可作为SQL执行时内部临时表的存储引擎。
  • TempTable:MySQL-8.0引入的引擎,用于存储内部临时表。
    InnoDB作为引擎引入到MySQL,是MySQL插件式引擎架构的一个非常重要的里程碑。在互联网发展的初期,MyISAM因其简单高效的访问赢得了互联网业务的青睐,和Linux、Apach、PHP一起被称为LAMP架构。
    随着电商、社交互联网的兴起,MyIASAM的短板越来越明显。InnoDB因其对事务ACID的支持、在并发访问和性能上的优势,大大的拓展了MySQL的能力。在InnoDB的加持下,MySQL成为最流行的开源OLTP数据库。随着MySQL的广泛使用,我们看到有越来越多基于TP数据的分析型查询。InnoDB的架构是天然为OLTP设计,虽然在TP业务场景下能够有非常优秀的性能表现。但InnoDB在分析型业务场景下的查询效率非常的低。这大大的限制了MySQL的使用场景。时至今日,MySQL一直欠缺一个分析型查询引擎。DuckDB的出现让我们看到了一种可能性。

    DuckDB简介

    DuckDB 是一个开源的在线分析处理(OLAP)和数据分析工作负载而设计。因其轻量、高性能、零配置和易集成的特性,正在迅速成为数据科学、BI 工具和嵌入式分析场景中的热门选择。DuckDB主要有以下几个特点:

  • 卓越的查询性能:单机DuckDB的性能不但远高于InnoDB,甚至比ClickHouse和SelectDB的性能更好。
  • 优秀的压缩比:DuckDB采用列式存储,根据类型自动选择合适的压缩算法,具有非常高的压缩率。
  • 嵌入式设计:DuckDB是一个嵌入式的数据库系统,天然的适合被集成到MySQL中。
  • 插件化设计:DuckDB采用了插件式的设计,非常方便进行第三方的开发和功能扩展。
  • 友好的License:DuckDB的License允许任何形式的使用DuckDB的源代码,包括商业行为。
    基于以上的几个原因,我们认为DuckDB非常适合成为MySQL的AP存储引擎。因此我们将DuckDB集成到了AliSQL中。
    图片
    DuckDB引擎的定位是实现轻量级的单机分析能力,目前基于DuckDB引擎的RDS MySQL DuckDB只读实例已经上线,欢迎试用。未来我们还会上线主备高可用的RDS MySQL DuckDB主实例,用户可以通过DTS等工具将异构数据汇聚到RDS MySQL DuckDB实例,实现数据的分析查询。RDS MySQL DuckDB只读实例的架构
    图片
    DuckDB分析只读实例,采用读写分离的架构。分析型业务和主库业务分离,互不影响。和普通只读实例一样,通过Binlog复制机制从主库复制数据。DuckDB分析只读节点有以下优势:
  • 高性能分析查询:基于DuckDB的查询能力,分析型查询性能相比InnoDB提升高达200倍(详见性能部分)。
  • 存储成本低:基于DuckDB的高压缩率,DuckDB只读实例的存储空间通常只有主库存储空间的20%。
  • 100% 兼容MySQL语法,免去学习成本。DuckDB作为引擎集成到MySQL中,因此用户查询仍然使用MySQL语法,没有任何学习成本。
  • 无额外管理成本:DuckDB只读实例仍然是RDS MySQL实例,相比普通只读实例仅仅增加了一些MySQL参数。因此DuckDB和普通RDS MySQL实例一样管理、运维、监控。监控信息、慢日志、审计日志、RDS API等无任何差异。
  • 一键创建DuckDB只读实例,数据自动从InnoDB转成DuckDB,无额外操作。DuckDB 引擎的实现
    图片
    DuckDB只读实例使用上可以分为查询链路和Binlog复制链路。查询链路接受用户的查询请求,执行数据查询。Binlog复制链路连接到主实例进行Binlog复制。下面会分别从这两方面介绍其技术原理。

    查询链路

    图片
    查询执行流程如上图所示。InnoDB仅用来保存元数据和系统信息,如账号、配置等。所有的用户数据都存在DuckDB引擎中,InnoDB仅用来保存元数据和系统信息,如账号、配置等。
    用户通过MySQL客户端连接到实例。查询到达后,MySQL首先进行解析和必要的处理。然后将SQL发送到DuckDB引擎执行。DuckDB执行完成后,将结果返回到Server层,server层将结果集转换成MySQL的结果集返回给客户。
    查询链路最重要的工作就是兼容性的工作。DuckDB和MySQL的数据类型基本上是兼容的,但在语法和函数的支持上都和MySQL有比较大的差异,为此我们扩展了DuckDB的语法解析器,使其兼容MySQL特有的语法;重写了大量的DuckDB函数并新增了大量的MySQL函数,让常见的MySQL函数都可以准确运行。自动化兼容性测试平台大约17万SQL测试,显示兼容率达到99%。

    Binlog复制链路

    图片

    幂等回放

    由于DuckDB不支持两阶段提交,因此无法利用两阶段提交来保证Binlog GTID和数据之间的一致性,也无法保证DDL操作中InnoDB的元数据和DuckDB的一致性。因此我们对事务提交的过程和Binlog的回放过程进行了改造,从而保证实例异常宕机重启后的数据一致性。

    DML回放优化

    由于DuckDB本身的实现上,有利于大事务的执行。频繁小事务的执行效率非常低,会导致严重的复制延迟。因此我们对Binlog回放做了优化,采用攒批(Batch)的方式进行事务重放。优化后可以达到30万行/s的回放能力。在Sysbench压力测试中,能够做到没有复制延迟,比InnoDB的回放性能还高。
    图片

    并行Copy DDL

    MySQL中的一少部分DDL比如修改列顺序等,DuckDB不支持。为了保证复制的正常进行,我们实现了Copy DDL机制。DuckDB原生支持的DDL,采用Inplace/Instant的方式执行。当碰到DuckDB不支持的DDL时,会采用Copy DDL的方式创建一个新表替换原表。
    图片

Copy DDL采用多线程并行执行,执行时间缩短7倍。
图片

DuckDB只读实例的性能

测试环境ECS 实例 32Cpu、128G内存、ESSD PL1云盘 500GB
测试类型TPC-H SF100
图片

结语

通过将DuckDB深度集成到AliSQL中,我们成功打造了兼具高性能与高兼容性的MySQL分析型实例。这一创新不仅弥补了MySQL长期以来在OLAP场景下的能力短板,也开创了一种全新的“HTAP轻量化”实现路径——无需复杂的分布式架构,即可实现强大的实时分析能力。
DuckDB引擎的引入,使得用户可以在不改变现有应用架构的前提下,轻松获得高达200倍的分析查询性能提升。更重要的是,用户可以使用MySQL协议、沿用熟悉的SQL语法、无需学习新工具、无需改造应用程序。一键创建、自动同步、无缝切换,真正做到了“分析能力即服务”。

未来已来,创新不止。我们将持续拓展 AliSQL DuckDB 引擎的能力边界,赋能更高效、更智能的数据处理新体验。
2026年2月3日(星期二)13:30–16:30,2026 AliSQL Innovate 用户大会 暨 AliSQL DuckDB 开发者线下活动 将在杭州盛大启幕!
以“Innovate”之名,我们重启 MySQL 生态的无限可能——重启 · 再创 · 向新而生
这是一场属于开发者的技术盛宴,一次思想碰撞与技术共创的深度交流。诚邀广大开发者、技术爱好者与行业伙伴齐聚杭州,共同见证 AliSQL 的进化之路,携手探索数据库的未来方向。
席位有限,立即扫码报名,锁定你的专属席位!我们在杭州,等你共赴创新之约!
图片

度小满引入 Apache Doris 替换原有 Greenplum,实现整体查询效率提升 82%,与此同时,集群缩减 2/3、年省数百万的巨大效益。本文将分享度小满如何基于 Doris 从 0 到 1 构建超大规模数据分析平台,并围绕平滑迁移、异地多活容灾等方面,分享实践经验。

本文整理自度小满 Doris 数据库负责人汤斯在 Doris Summit 2025 中的演讲,并以演讲者第一视角进行叙述。

度小满金融(原百度金融)作为一家覆盖现代财富管理、支付、金融科技等多板块的科技公司,数据的分析处理对其极为重要,已经深度融入业务生命周期的每个环节,是进行风险控制、商业决策、用户体验优化及运营提效的基石。

随着业务高速发展,度小满原有基于 Greenplum 搭建的 OLAP 平台,逐渐暴露出三大痛点:

  • 规模与稳定性瓶颈:存储已接近饱和,扩容至百余台已接近硬件规模的承载上限,如果继续扩容,将面临更严重的稳定性挑战。

  • 性能与体验不佳:Greenplum SQL 查询执行速度慢,且经常出现 “计算时间远小于排队时间” 的情况,严重影响业务分析效率。

  • 缺失技术支持:当前使用的 Greenplum 6 版本技术架构已显得陈旧,并且 2024 年 Greenplum 宣布将停止开源,后续的技术支持与迭代升级将无法保障。

为了应对这些痛点,度小满金融迫切寻找更为高效、稳定且具备现代化技术架构的数据处理解决方案,以支持其未来的业务发展。

Apache Doris:高吞吐、快查询

面对日益增长的业务体量与复杂多变的分析需求,选用一个高效、可靠的数据库系统,已成为支撑业务稳健发展与快速创新的关键。Apache Doris 以其出色的性能表现与高度灵活的架构,成为众多场景下的优选方案。为深入验证其在海量数据与复杂分析场景中的能力,我们展开了一系列性能测试,关键结果如下:

  • 查询性能:在 1TB TPC-DS 标准测试集中, Apache Doris的查询速度约是 Greenplum 6 的 20-30 倍

  • 导入性能:在基于 Flink 写入的 TPS 测试中,基于单分片导入,压测最大 TPS 为:5000W/s

  • JSON 数据处理:针对新推出的 Variant JSON 数据类型,测试显示:存储 2-3 万 Key 时,其空间占用仅为普通 JSON 的 1/10 甚至更低,查询效率则提升至 10 倍以上

综上可知,Apache Doris 在写入吞吐、响应速度及存储效率上表现卓越,有力证明了其应对大规模、实时化、半结构化数据分析挑战的坚实技术基础。

基于 Apache Doris 的大规模数据分析平台

在上述详实的选型调研之后,我们决定采用 Apache Doris 替代原有 Greenplum 集群,构建超大规模数据分析平台。

为验证 Apache Doris 在真实业务场景中的表现,我们先进行了小范围试点,部署了少量 Doris 集群,并先行接入几个关键业务方。试点期间,系统在性能、稳定性和易用性方面获得高度评价。基于这一积极反馈,我们稳步扩展 Doris 集群规模,最终在效率与成本上实现大幅提升:

  • 整体效率:端到端分析任务耗时从 274 秒降至 47 秒,效率提升 82%,任务超时查杀比例从 1.3%骤降至 0.11%,降幅达 91%,彻底解决高峰期排队问题实现 0 排队,使分析师的工作不再因拥堵而中断,体验和生产力均有极大提升。

  • 集群成本:在同等资源成本下, Doris 仅以 1/3 的集群数量即可提供与 Greenplum 同等的服务能力,存储性能提升 200%。截至目前,已完成 百余台原 Greenplum 服务器的清退工作,以更少的硬件资源支撑了更高的计算与存储需求,实现年度硬件成本节约数百万元

从 0-1 数据平台建设经验

我们基于 Apache Doris 成功替换了 Greenplum,完成了从 0-1 的数据平台重构,覆盖架构设计、数据流转与业务协同的系统性工程。以下将围绕快速平滑迁移、异地多活容灾与全链路生态集成三个核心环节,展开具体实践。

01 快速迁移

为保障业务连续性与数据安全,我们开发了自动化迁移工具 SqlGlot,将大规模数据从原有 GP 集群迁移至 Doris 集群。整个过程历经半年,累计迁移 PB 级规模数据,全程业务无感知。

  • 表结构迁移:在表结构迁移阶段,团队从 GP 系统中导出表结构及相关元数据,借助 SqlGlot 工具实现字段映射与语法适配,并在此基础上完成分区构建与分桶策略设计,确保每个分桶数据量控制在 1G~3G 的合理范围内。该流程最终成功转换超过 20,000 张表,并保障了所有表的分区与分桶结构符合业务与性能要求。

  • 表数据迁移:我们通过分布式导出将 GP 数据并行迁移至 Doris 机器,并基于 Doris 官方推荐的 Stream Load 进行并发控制,以文件流式加载的方式高效导入数据至 Doris 集群。整个过程累计完成 PB 级规模数据迁移,稳定支持了 5000+ 次数据同步任务。

  • SQL 迁移:为解决因业务规模庞大、场景复杂而导致的官方工具语法支持不全的问题,我们基于 SqlGlot 并结合正则匹配能力,将 PostgreSQL SQL 高效转换为 Doris SQL。整个迁移流程包括“转换成功 → 执行成功 → 数据一致” ,累计完成约 47 万个 SQL 的转换,实现 95% 的执行成功率 与 92% 的数据一致率

02 异地双机房灾备

为保障数据安全并实现集群高可用,我们基于 Apache Doris 构建了异地双机房灾备架构,确保数据与服务具备跨机房容灾与双活能力。核心设计如下:

我们将所有 Doris 集群节点均匀部署于 A 与 B 两个异地机房,通过设置 tag.location 属性明确节点所属机房。用户账号按机房绑定,访问请求通过轮询机制自动分配,实现负载均衡(例如首次请求路由至 A 机房,第二次则路由至 B 机房)。建表时通过配置 location 参数,确保每张表在双机房各保留 2 个副本,从而达成数据异地双活与故障自动切换。

关键配置示例

  1. 设置节点机房标签

alter system modify backend ”BE1:9050" set ("tag.location" = "group_a");alter system modify backend ”BE2:9050" set ("tag.location" = "group_b");
复制代码

  1. 建表时指定双机房副本分布

CREATE TABLE ubevent (ts DATETIME, uid INT, ...) DUPLICATE KEY(ts) DISTRIBUTED BY HASH(uid) BUCKETS 10PROPERTIES ("replication_allocation" = "tag.location.group_b: 2, tag.location.group_a: 2");
复制代码

03 生态整合

为构建高效、稳定、易用的数据平台,我们还围绕 Apache Doris 进行系统性生态整合:

  • 计算引擎无缝集成:通过 Doris 官方提供的 Spark Connector 与 Flink Connector,实现了与现有 Spark、Flink 计算引擎的高效对接,保障了数据流水线稳定运行。

  • 运维体系化与自动化:集成 Prometheus、Grafana 及 Doris Manager,构建了覆盖监控、告警、管理与调优的自动化运维体系,全面提升集群稳定性与运维效率。

优化经验

为进一步提升数据平台的效率及资源利用率,在实际落地过程中,围绕集群、负载、存储等多维度总结了以下优化经验:

01 集群隔离

当前我们有多个 Doris 集群,为合理承接不同业务方的接入需求,我们主要依据业务成本与稳定性要求两大维度进行评估与路由。通常而言,稳定性越高,对应成本也越高。

新建集群时,稳定性最优,但相应成本也最高。为在成本与稳定性之间取得平衡,我们大多场景是基于 Workload Group 资源硬隔离方案,对 CPU 与内存进行资源组级别的隔离,有效减少不同业务负载间的资源竞争。若业务对稳定性的要求超出共享集群所能提供的范围,则仍需要通过新建独立集群来满足。

02 存储压力

在 Apache Doris 的落地与运维过程中,我们曾面临因业务快速增长带来的高达 80%-90% 的磁盘存储压力。针对这一问题,进行了一系列优化:

  • 控制表生命周期:部分业务或因对动态分区相关语法不熟悉,未主动采用该策略。为此,集成动态分区的参数配置,简化了开发难度,并提供统一注册入口,业务开发人员仅需选择是否开启、保留天数即可。

  • 修改压缩格式:将默认压缩算法从 LZ4 切换为 ZSTD。实测表明,存储空间平均节省约 50%,虽带来约 20%~30% 的 CPU 与内存负载上升,但整体 ROI 仍然较高。

  • 存储指标监控告警:为预防因误操作或异常行为导致的存储激增,建立了针对“人员”与“表”双维度的监控体系。环比分析业务人员数据占用趋势及单表每日增长量,可自动识别异常(如单日增长飙升至日常 10 倍),并及时触发告警及通知。

  • Hive 与 Doris 打通:在基于 Kerberos 认证的 Hive 环境中,对 Doris Hive Catalog 功能进行了二次开发,实现跨系统的直接数据访问,无需依赖 Flink 等同步工具,简化了架构并提升了数据使用效率。

03 负载均衡

为确保系统在负载高峰期的稳定运行,特别是应对异常 SQL 与大查询带来的资源压力,应对措施如下:

  • 双机房负载均衡:基于已有的异地双机房架构,通过轮询机制实现业务流量在 A 与 B 机房之间的自动分发:首个 SQL 请求路由至 A,次个请求则导向 B,以此循环,确保双机房负载均衡,避免单点资源过载。

  • SQL 参数限制:通过 enable_query_memory_overcommit = falseexec_mem_limit = 256 * 1024 * 1024 * 1024 等参数将最大占用内存限制为 256G,避免集群被打满,后续计划降至 60G。

  • Workload 资源队列动态调整:基于任务类型划分资源队列,配置 CPU 的软隔离和内存的硬隔离,并支持错峰调度。比如:例行任务通常在夜间执行,为其创建专门资源队列,数据分析等公共任务大多在白天执行,将配置更大的资源队列,随着白天/夜间需求的变化动态调整资源。此外,依据各队列负载设定并行度与并发数,控制任务排队时长。

  • 异常 SQL 拦截:实时识别与拦截异常 SQL,避免其影响 BE 节点稳定性。初期使用 Doris 内置正则规则进行拦截,但规则复杂导致 CPU 开销上升。为此,我们将拦截逻辑外移至平台层执行,以避免正则匹配及超大 JOIN 导致的 CPU 负载过高。

04 集群稳定性

随着集群规模不断扩大,保障 FE、BE 节点稳定性成为运维工作的核心挑战,为此,我们构建了以下保障体系:

  • 分层触达+全维度覆盖:根据不同指标优先级设置通知电话、短信、飞书提醒,P0 监控准确率 ≥80%;

  • 自动异常处理:为 FE 和 BE 的宕机重启设置了自动化处理方案,在识别到服务卡住时,系统会自动重启进程。此外,对于磁盘掉线,将自动下线故障盘并触发副本补齐。

我们同时采用对战分析、火焰图和日志查看等方法进行详细记录,以便后续调优。此外,编写了 SOP 手册,涵盖不同场景的应对措施,并进行了异常处理演练。

结束语

截至目前,我们已搭建 3 个基于 Doris 2.1.10 版本的线上集群,其中最大规模的集群达万 core 级别、上百 TB 内存和 PB 级磁盘。目前仍在扩容中,计划在年底前新增百余台 CN 节点和数十台 Mix 节点。未来,我们将重点关注并探索以下能力:

  • 存算分离:重点关注 Doris 3.X 版本的存储分离架构,推动落地实践。

  • 湖仓一体:全面打通数据湖与数据仓库,目前已小规模试点 Paimon;此外,针对数据外置场景,计划通过异步物化视图提升查询性能。

  • 智能物化视图探索:引入语义建模与 AI 智能分析,降低研发与业务沟通门槛,并对智能推荐与模板化方案进行探索与实践。

度小满引入 Apache Doris 替换原有 Greenplum,实现整体查询效率提升 82%,与此同时,集群缩减 2/3、年省数百万的巨大效益。本文将分享度小满如何基于 Doris 从 0 到 1 构建超大规模数据分析平台,并围绕平滑迁移、异地多活容灾等方面,分享实践经验。

本文整理自度小满 Doris 数据库负责人汤斯在 Doris Summit 2025 中的演讲,并以演讲者第一视角进行叙述。

度小满金融(原百度金融)作为一家覆盖现代财富管理、支付、金融科技等多板块的科技公司,数据的分析处理对其极为重要,已经深度融入业务生命周期的每个环节,是进行风险控制、商业决策、用户体验优化及运营提效的基石。

随着业务高速发展,度小满原有基于 Greenplum 搭建的 OLAP 平台,逐渐暴露出三大痛点:

  • 规模与稳定性瓶颈:存储已接近饱和,扩容至百余台已接近硬件规模的承载上限,如果继续扩容,将面临更严重的稳定性挑战。

  • 性能与体验不佳:Greenplum SQL 查询执行速度慢,且经常出现 “计算时间远小于排队时间” 的情况,严重影响业务分析效率。

  • 缺失技术支持:当前使用的 Greenplum 6 版本技术架构已显得陈旧,并且 2024 年 Greenplum 宣布将停止开源,后续的技术支持与迭代升级将无法保障。

为了应对这些痛点,度小满金融迫切寻找更为高效、稳定且具备现代化技术架构的数据处理解决方案,以支持其未来的业务发展。

Apache Doris:高吞吐、快查询

面对日益增长的业务体量与复杂多变的分析需求,选用一个高效、可靠的数据库系统,已成为支撑业务稳健发展与快速创新的关键。Apache Doris 以其出色的性能表现与高度灵活的架构,成为众多场景下的优选方案。为深入验证其在海量数据与复杂分析场景中的能力,我们展开了一系列性能测试,关键结果如下:

  • 查询性能:在 1TB TPC-DS 标准测试集中, Apache Doris的查询速度约是 Greenplum 6 的 20-30 倍

  • 导入性能:在基于 Flink 写入的 TPS 测试中,基于单分片导入,压测最大 TPS 为:5000W/s

  • JSON 数据处理:针对新推出的 Variant JSON 数据类型,测试显示:存储 2-3 万 Key 时,其空间占用仅为普通 JSON 的 1/10 甚至更低,查询效率则提升至 10 倍以上

综上可知,Apache Doris 在写入吞吐、响应速度及存储效率上表现卓越,有力证明了其应对大规模、实时化、半结构化数据分析挑战的坚实技术基础。

基于 Apache Doris 的大规模数据分析平台

在上述详实的选型调研之后,我们决定采用 Apache Doris 替代原有 Greenplum 集群,构建超大规模数据分析平台。

为验证 Apache Doris 在真实业务场景中的表现,我们先进行了小范围试点,部署了少量 Doris 集群,并先行接入几个关键业务方。试点期间,系统在性能、稳定性和易用性方面获得高度评价。基于这一积极反馈,我们稳步扩展 Doris 集群规模,最终在效率与成本上实现大幅提升:

  • 整体效率:端到端分析任务耗时从 274 秒降至 47 秒,效率提升 82%,任务超时查杀比例从 1.3%骤降至 0.11%,降幅达 91%,彻底解决高峰期排队问题实现 0 排队,使分析师的工作不再因拥堵而中断,体验和生产力均有极大提升。

  • 集群成本:在同等资源成本下, Doris 仅以 1/3 的集群数量即可提供与 Greenplum 同等的服务能力,存储性能提升 200%。截至目前,已完成 百余台原 Greenplum 服务器的清退工作,以更少的硬件资源支撑了更高的计算与存储需求,实现年度硬件成本节约数百万元

从 0-1 数据平台建设经验

我们基于 Apache Doris 成功替换了 Greenplum,完成了从 0-1 的数据平台重构,覆盖架构设计、数据流转与业务协同的系统性工程。以下将围绕快速平滑迁移、异地多活容灾与全链路生态集成三个核心环节,展开具体实践。

01 快速迁移

为保障业务连续性与数据安全,我们开发了自动化迁移工具 SqlGlot,将大规模数据从原有 GP 集群迁移至 Doris 集群。整个过程历经半年,累计迁移 PB 级规模数据,全程业务无感知。

  • 表结构迁移:在表结构迁移阶段,团队从 GP 系统中导出表结构及相关元数据,借助 SqlGlot 工具实现字段映射与语法适配,并在此基础上完成分区构建与分桶策略设计,确保每个分桶数据量控制在 1G~3G 的合理范围内。该流程最终成功转换超过 20,000 张表,并保障了所有表的分区与分桶结构符合业务与性能要求。

  • 表数据迁移:我们通过分布式导出将 GP 数据并行迁移至 Doris 机器,并基于 Doris 官方推荐的 Stream Load 进行并发控制,以文件流式加载的方式高效导入数据至 Doris 集群。整个过程累计完成 PB 级规模数据迁移,稳定支持了 5000+ 次数据同步任务。

  • SQL 迁移:为解决因业务规模庞大、场景复杂而导致的官方工具语法支持不全的问题,我们基于 SqlGlot 并结合正则匹配能力,将 PostgreSQL SQL 高效转换为 Doris SQL。整个迁移流程包括“转换成功 → 执行成功 → 数据一致” ,累计完成约 47 万个 SQL 的转换,实现 95% 的执行成功率 与 92% 的数据一致率

02 异地双机房灾备

为保障数据安全并实现集群高可用,我们基于 Apache Doris 构建了异地双机房灾备架构,确保数据与服务具备跨机房容灾与双活能力。核心设计如下:

我们将所有 Doris 集群节点均匀部署于 A 与 B 两个异地机房,通过设置 tag.location 属性明确节点所属机房。用户账号按机房绑定,访问请求通过轮询机制自动分配,实现负载均衡(例如首次请求路由至 A 机房,第二次则路由至 B 机房)。建表时通过配置 location 参数,确保每张表在双机房各保留 2 个副本,从而达成数据异地双活与故障自动切换。

关键配置示例

  1. 设置节点机房标签

alter system modify backend ”BE1:9050" set ("tag.location" = "group_a");alter system modify backend ”BE2:9050" set ("tag.location" = "group_b");
复制代码

  1. 建表时指定双机房副本分布

CREATE TABLE ubevent (ts DATETIME, uid INT, ...) DUPLICATE KEY(ts) DISTRIBUTED BY HASH(uid) BUCKETS 10PROPERTIES ("replication_allocation" = "tag.location.group_b: 2, tag.location.group_a: 2");
复制代码

03 生态整合

为构建高效、稳定、易用的数据平台,我们还围绕 Apache Doris 进行系统性生态整合:

  • 计算引擎无缝集成:通过 Doris 官方提供的 Spark Connector 与 Flink Connector,实现了与现有 Spark、Flink 计算引擎的高效对接,保障了数据流水线稳定运行。

  • 运维体系化与自动化:集成 Prometheus、Grafana 及 Doris Manager,构建了覆盖监控、告警、管理与调优的自动化运维体系,全面提升集群稳定性与运维效率。

优化经验

为进一步提升数据平台的效率及资源利用率,在实际落地过程中,围绕集群、负载、存储等多维度总结了以下优化经验:

01 集群隔离

当前我们有多个 Doris 集群,为合理承接不同业务方的接入需求,我们主要依据业务成本与稳定性要求两大维度进行评估与路由。通常而言,稳定性越高,对应成本也越高。

新建集群时,稳定性最优,但相应成本也最高。为在成本与稳定性之间取得平衡,我们大多场景是基于 Workload Group 资源硬隔离方案,对 CPU 与内存进行资源组级别的隔离,有效减少不同业务负载间的资源竞争。若业务对稳定性的要求超出共享集群所能提供的范围,则仍需要通过新建独立集群来满足。

02 存储压力

在 Apache Doris 的落地与运维过程中,我们曾面临因业务快速增长带来的高达 80%-90% 的磁盘存储压力。针对这一问题,进行了一系列优化:

  • 控制表生命周期:部分业务或因对动态分区相关语法不熟悉,未主动采用该策略。为此,集成动态分区的参数配置,简化了开发难度,并提供统一注册入口,业务开发人员仅需选择是否开启、保留天数即可。

  • 修改压缩格式:将默认压缩算法从 LZ4 切换为 ZSTD。实测表明,存储空间平均节省约 50%,虽带来约 20%~30% 的 CPU 与内存负载上升,但整体 ROI 仍然较高。

  • 存储指标监控告警:为预防因误操作或异常行为导致的存储激增,建立了针对“人员”与“表”双维度的监控体系。环比分析业务人员数据占用趋势及单表每日增长量,可自动识别异常(如单日增长飙升至日常 10 倍),并及时触发告警及通知。

  • Hive 与 Doris 打通:在基于 Kerberos 认证的 Hive 环境中,对 Doris Hive Catalog 功能进行了二次开发,实现跨系统的直接数据访问,无需依赖 Flink 等同步工具,简化了架构并提升了数据使用效率。

03 负载均衡

为确保系统在负载高峰期的稳定运行,特别是应对异常 SQL 与大查询带来的资源压力,应对措施如下:

  • 双机房负载均衡:基于已有的异地双机房架构,通过轮询机制实现业务流量在 A 与 B 机房之间的自动分发:首个 SQL 请求路由至 A,次个请求则导向 B,以此循环,确保双机房负载均衡,避免单点资源过载。

  • SQL 参数限制:通过 enable_query_memory_overcommit = falseexec_mem_limit = 256 * 1024 * 1024 * 1024 等参数将最大占用内存限制为 256G,避免集群被打满,后续计划降至 60G。

  • Workload 资源队列动态调整:基于任务类型划分资源队列,配置 CPU 的软隔离和内存的硬隔离,并支持错峰调度。比如:例行任务通常在夜间执行,为其创建专门资源队列,数据分析等公共任务大多在白天执行,将配置更大的资源队列,随着白天/夜间需求的变化动态调整资源。此外,依据各队列负载设定并行度与并发数,控制任务排队时长。

  • 异常 SQL 拦截:实时识别与拦截异常 SQL,避免其影响 BE 节点稳定性。初期使用 Doris 内置正则规则进行拦截,但规则复杂导致 CPU 开销上升。为此,我们将拦截逻辑外移至平台层执行,以避免正则匹配及超大 JOIN 导致的 CPU 负载过高。

04 集群稳定性

随着集群规模不断扩大,保障 FE、BE 节点稳定性成为运维工作的核心挑战,为此,我们构建了以下保障体系:

  • 分层触达+全维度覆盖:根据不同指标优先级设置通知电话、短信、飞书提醒,P0 监控准确率 ≥80%;

  • 自动异常处理:为 FE 和 BE 的宕机重启设置了自动化处理方案,在识别到服务卡住时,系统会自动重启进程。此外,对于磁盘掉线,将自动下线故障盘并触发副本补齐。

我们同时采用对战分析、火焰图和日志查看等方法进行详细记录,以便后续调优。此外,编写了 SOP 手册,涵盖不同场景的应对措施,并进行了异常处理演练。

结束语

截至目前,我们已搭建 3 个基于 Doris 2.1.10 版本的线上集群,其中最大规模的集群达万 core 级别、上百 TB 内存和 PB 级磁盘。目前仍在扩容中,计划在年底前新增百余台 CN 节点和数十台 Mix 节点。未来,我们将重点关注并探索以下能力:

  • 存算分离:重点关注 Doris 3.X 版本的存储分离架构,推动落地实践。

  • 湖仓一体:全面打通数据湖与数据仓库,目前已小规模试点 Paimon;此外,针对数据外置场景,计划通过异步物化视图提升查询性能。

  • 智能物化视图探索:引入语义建模与 AI 智能分析,降低研发与业务沟通门槛,并对智能推荐与模板化方案进行探索与实践。