Doris 4.x 存算分离:什么时候上、怎么上、成本怎么算
存算分离不是”升级”,是架构选择
Apache Doris 从 3.0 开始支持存算分离(Cloud 模式),到 4.0/4.1 已经有 2000+ 家公司在生产环境使用。但”2000 家在用”不等于”你该上”。
先搞清楚一个核心问题:存算分离不是存算一体的”升级版”,而是一种不同的架构选择,有不同的适用场景。
存算一体(Shared-Nothing)
1 | BE 节点 1: [计算 + 本地存储] ← 数据分片 1 |
每个 BE 节点既负责计算也负责存储,数据存在本地磁盘。查到哪个节点,就在哪个节点本地计算。
优势: 计算和存储在同一台机器上,数据读取零网络开销,查询延迟最低。
劣势: 计算和存储耦合,扩容时必须同时加计算和存储资源。存储不够了但计算够用?也必须加整台机器。
存算分离(Cloud 模式)
1 | 计算集群 A: [计算] ←→ |
数据存在对象存储(S3/OSS/MinIO),计算节点本地有 File Cache 缓存热数据。计算和存储独立扩缩容。
优势: 存储用对象存储(极低成本),计算按需弹性扩缩容。
劣势: 数据不在本地,冷查询需要从对象存储拉取,延迟更高。依赖 File Cache 缓存命中率。
什么时候该上存算分离
场景 1:数据量超过单集群物理磁盘容量
存算一体模式下,你的数据量受限于 BE 节点的总磁盘容量。如果集群有 10 个 BE 节点,每个 10TB,总容量就是 100TB(含副本则更少)。
当数据量超过这个规模,存算分离是自然选择——对象存储的容量几乎是无限的。
判断标准: 数据量 > 50TB(经验值,取决于集群规模和预算)。
场景 2:计算负载有明显波峰波谷
典型场景:白天大量查询(BI 报表、即席分析),晚上几乎没人用。
存算一体:白天计算资源不够,晚上计算资源闲置。扩容?晚上浪费。不扩容?白天扛不住。
存算分离:白天弹性扩容计算节点,晚上缩容。计算资源按需分配。
判断标准: 峰值 / 均值 > 3(白天查询量是晚上的 3 倍以上)。
场景 3:需要读写隔离
报表查询和实时写入互相干扰:写入高峰时查询变慢,查询高峰时写入排队。
存算分离可以把写入和查询分到不同的 Compute Group:
1 | Compute Group A (写入专用): 处理 Kafka Routine Load |
两个计算集群共享同一份存储,但互不干扰。
判断标准: 写入和查询有明显的时间重叠,且互相影响性能。
场景 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 | 查询到达 → 检查 File Cache → 命中:本地读取(快) |
File Cache 命中率决定查询性能
| 命中率 | 查询延迟 | 说明 |
|---|---|---|
| > 90% | 接近存算一体 | 热数据几乎都在本地 |
| 50%-90% | 明显变慢 | 部分查询需要远程拉取 |
| < 50% | 比存算一体慢 5-10 倍 | 大部分数据需要远程拉取 |
怎么提高命中率
1. 预热(Warm-up)
Doris 4.0+ 支持表级和分区级预热,提前把数据从对象存储拉到本地 Cache:
1 | -- 预热指定分区 |
策略: 定时任务在查询高峰前预热当天会用到的分区。
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 | Meta Service (元数据) |
Workload Group 绑定
Doris 4.1 支持把 Workload Group 绑定到 Compute Group,实现细粒度资源隔离:
1 | -- 为查询集群创建 Workload Group |
不同 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 是存算分离的增量知识,不是替代。
建议学习路径:
- 存算一体模式搭建集群,跑通 Kafka → Doris Routine Load 链路
- 理解 Compaction、分区、分桶、物化视图等核心概念
- 在存算一体上验证查询性能和写入吞吐
- 数据量或弹性需求到了再迁移到存算分离
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 的”一个系统做两件事”的简化优势,需要持续观察。
