存算分离不是”升级”,是架构选择

Apache Doris 从 3.0 开始支持存算分离(Cloud 模式),到 4.0/4.1 已经有 2000+ 家公司在生产环境使用。但”2000 家在用”不等于”你该上”。

先搞清楚一个核心问题:存算分离不是存算一体的”升级版”,而是一种不同的架构选择,有不同的适用场景。

存算一体(Shared-Nothing)

1
2
3
BE 节点 1: [计算 + 本地存储] ← 数据分片 1
BE 节点 2: [计算 + 本地存储] ← 数据分片 2
BE 节点 3: [计算 + 本地存储] ← 数据分片 3

每个 BE 节点既负责计算也负责存储,数据存在本地磁盘。查到哪个节点,就在哪个节点本地计算。

优势: 计算和存储在同一台机器上,数据读取零网络开销,查询延迟最低。

劣势: 计算和存储耦合,扩容时必须同时加计算和存储资源。存储不够了但计算够用?也必须加整台机器。

存算分离(Cloud 模式)

1
2
3
4
计算集群 A: [计算] ←→ 
计算集群 B: [计算] ←→ 对象存储 (S3/OSS/MinIO)

Meta Service (元数据管理)

数据存在对象存储(S3/OSS/MinIO),计算节点本地有 File Cache 缓存热数据。计算和存储独立扩缩容。

优势: 存储用对象存储(极低成本),计算按需弹性扩缩容。

劣势: 数据不在本地,冷查询需要从对象存储拉取,延迟更高。依赖 File Cache 缓存命中率。

什么时候该上存算分离

场景 1:数据量超过单集群物理磁盘容量

存算一体模式下,你的数据量受限于 BE 节点的总磁盘容量。如果集群有 10 个 BE 节点,每个 10TB,总容量就是 100TB(含副本则更少)。

当数据量超过这个规模,存算分离是自然选择——对象存储的容量几乎是无限的。

判断标准: 数据量 > 50TB(经验值,取决于集群规模和预算)。

场景 2:计算负载有明显波峰波谷

典型场景:白天大量查询(BI 报表、即席分析),晚上几乎没人用。

存算一体:白天计算资源不够,晚上计算资源闲置。扩容?晚上浪费。不扩容?白天扛不住。

存算分离:白天弹性扩容计算节点,晚上缩容。计算资源按需分配。

判断标准: 峰值 / 均值 > 3(白天查询量是晚上的 3 倍以上)。

场景 3:需要读写隔离

报表查询和实时写入互相干扰:写入高峰时查询变慢,查询高峰时写入排队。

存算分离可以把写入和查询分到不同的 Compute Group:

1
2
Compute Group A (写入专用): 处理 Kafka Routine Load
Compute Group B (查询专用): 处理 BI 查询

两个计算集群共享同一份存储,但互不干扰。

判断标准: 写入和查询有明显的时间重叠,且互相影响性能。

场景 4:多云 / 多机房

数据在对象存储里,计算可以部署在任何能访问该对象存储的机房。机房 A 挂了,机房 B 的计算集群立刻接管。

不该上存算分离的场景

1. 数据量小(< 10TB)

对象存储的优势在规模效应。数据量小的时候,存算一体的本地磁盘更快更简单,File Cache 的命中率也没有意义——数据本来就在本地。

2. 对查询延迟极端敏感

存算分离的冷查询(File Cache 未命中)需要从对象存储拉数据,延迟可能是存算一体的 5-10 倍。如果你的场景要求所有查询都在 100ms 以内,存算一体更可靠。

3. 团队没有云原生运维能力

存算分离引入了 Meta Service、对象存储配置、File Cache 调优、Compute Group 管理等额外复杂度。如果团队还在用”装个数据库跑 SQL”的运维模式,存算分离的运维成本会很高。

File Cache:存算分离的核心机制

存算分离性能的关键在 File Cache。

原理: Doris 把对象存储中的数据文件(Segment)缓存到计算节点的本地磁盘。查询时优先读 Cache,Cache 未命中才去对象存储拉取。

1
2
查询到达 → 检查 File Cache → 命中:本地读取(快)
→ 未命中:从 S3 拉取(慢)→ 写入 Cache

File Cache 命中率决定查询性能

命中率 查询延迟 说明
> 90% 接近存算一体 热数据几乎都在本地
50%-90% 明显变慢 部分查询需要远程拉取
< 50% 比存算一体慢 5-10 倍 大部分数据需要远程拉取

怎么提高命中率

1. 预热(Warm-up)

Doris 4.0+ 支持表级和分区级预热,提前把数据从对象存储拉到本地 Cache:

1
2
3
4
5
-- 预热指定分区
WARM UP TABLE orders PARTITION(p20260726);

-- 预热整张表
WARM UP TABLE orders;

策略: 定时任务在查询高峰前预热当天会用到的分区。

2. 分层存储

Doris 4.1 支持把 Cache 分为多个层级:

  • 热数据:本地 NVMe SSD(最快)
  • 温数据:本地 SATA SSD(中等)
  • 冷数据:只在对象存储(最便宜)

Doris 根据数据访问频率自动分层,不需要手动管理。

3. Compaction 读写分离

Doris 4.0.6+ 支持 Compaction 读写分离:Compaction(数据合并)操作在独立的计算集群执行,不影响查询集群的 Cache。

Compute Group:资源隔离的利器

存算分离模式下,BE 节点按 Compute Group 分组,每个组是独立的计算资源池。

典型部署

1
2
3
4
5
6
7
8
9
Meta Service (元数据)

┌───┴───┐
│ │
Compute Group A Compute Group B
(4 个 BE 节点) (8 个 BE 节点)
│ │
写入 + Compaction BI 查询
(Kafka Routine Load) (Tableau / FineBI)

Workload Group 绑定

Doris 4.1 支持把 Workload Group 绑定到 Compute Group,实现细粒度资源隔离:

1
2
3
4
5
6
7
-- 为查询集群创建 Workload Group
CREATE WORKLOAD GROUP bi_query FOR compute_group_b
PROPERTIES ('cpu_share'='2048', 'mem_limit'='60%');

-- 为实时分析创建高优先级 Group
CREATE WORKLOAD GROUP realtime FOR compute_group_b
PROPERTIES ('cpu_share'='4096', 'mem_limit'='30%');

不同 Workload Group 的 CPU 和内存配额独立,BI 大查询不会饿死实时分析。

成本怎么算

存算一体成本

1
成本 = BE 节点数 × (服务器价格 + 磁盘价格)

假设 10 个 BE 节点,每个 64 核 + 256GB 内存 + 4TB NVMe,约 2 万/台。

年成本:约 20 万(不含机房和运维)。

存算分离成本

1
成本 = 计算节点 × 服务器价格 + 存储用量 × 对象存储单价 + Meta Service 成本

假设:

  • 计算节点 6 个(弹性伸缩,均值 6 个),每个 64 核 + 256GB 内存,约 1.5 万/台
  • 数据量 50TB,S3 单价约 0.12 元/GB/月 = 6 元/TB/月
  • Meta Service 3 个节点(轻量),约 0.5 万/台

年成本:

  • 计算:6 × 1.5 = 9 万
  • 存储:50TB × 6 元 × 12 月 = 3.6 万
  • Meta Service:3 × 0.5 = 1.5 万
  • 合计:约 14.1 万

成本对比

维度 存算一体 存算分离
年成本 ~20 万 ~14 万
数据量上限 受物理磁盘限制 几乎无限
弹性扩缩容 不支持 支持
查询延迟 最低 依赖 Cache 命中率
运维复杂度 中-高

结论: 数据量 > 30TB 且有弹性需求时,存算分离在成本上开始有优势。数据量小且延迟敏感时,存算一体更划算。

对正在学 Doris 的人意味着什么

1. 先学存算一体,再学存算分离

存算分离的查询优化、Compaction、数据导入等核心机制和存算一体是一样的。File Cache 和 Compute Group 是存算分离的增量知识,不是替代。

建议学习路径:

  1. 存算一体模式搭建集群,跑通 Kafka → Doris Routine Load 链路
  2. 理解 Compaction、分区、分桶、物化视图等核心概念
  3. 在存算一体上验证查询性能和写入吞吐
  4. 数据量或弹性需求到了再迁移到存算分离

2. 对接 Canal→Kafka→Doris 链路在两种模式下差异不大

Canal→Doris 同步链路 中的 Routine Load 配置、label 机制、exactly-once 语义在存算分离模式下完全一样。区别只在底层存储——存算分离时数据写到对象存储而不是本地磁盘。

3. 存算分离不改变 Doris 和 ES 的分工

Doris 与 ES 同时存在 中讨论的边界划分在存算分离后依然成立。存算分离改变的是 Doris 的部署架构和成本模型,不改变它的能力边界。Doris 做分析、ES 做搜索的分工不变。

但要注意 ES Columnar Mode 带来的变量——如果 ES 未来真的能做列式分析,Doris 的存算分离成本优势能否抵消 ES 的”一个系统做两件事”的简化优势,需要持续观察。

参考链接