Doris 容量与灾备:演练到底是为了什么
英文版:English
两个问题,一个习惯
数据平台接生产流量之前,有两个问题常被按错顺序问:要多大,坏了怎么办。两者的失败模式一样:拿出一个看起来很权威、却从没对着实物核对过的数字。这篇讲的是我核对过的两个地方,以及发现了什么。
先交代范围。这里所有数字都是在上线前的非生产环境测的(一个生产规模的 preprod 集群和一个较小的 dev 集群)。我不声称经过验证的 RTO 或 RPO,容量模型也只建了一个 region 的生产。
容量:2.5 倍的偏差是单位搞混了
旧的容量文档按 15 TB 来规划存储和池深度。这个数是一块 EBS 卷的大小,也就是挂在节点上的盘,不是数据量。我从实测的源端重做了规划:三张宽表,约 70 亿行,源端 6.4 TiB。把卷大小换成数据量,去掉了约 2.5 倍 的多配。多买两倍半不会造成任何报错,只是每个月都多花那么多钱。
另一半是池深度,这是并发问题,不是存储问题。我取了 90 天的小时峰值并发,剔除 35 个堆积小时(那些小时的数字是积压撑起来的,不是需求)。分布如下:
| 分位 | 小时峰值并发 |
|---|---|
| p50 | 9 |
| p90 | 23 |
| p99 | 60.8 |
| max | 138 |
p50 到 max 差 15 倍,整个设计难点就在这个差距里。按 max 配,容量几乎一直闲着;按中位数配,每次高峰必然排队。p99 是个合理的常驻水位锚点,尾部交给弹性容量,而不是自己永久持有。我把它写成采购的依据,不是最终数字:模型里好几项输入自己标了「推断」,用真实负载检验模型的流量回放 A/B 也没做完。这项工作我不声称有成本节省。
灾备:工具链
我围绕存算分离架构做了一套备份恢复工具链。这种架构里表数据在对象存储上,要保护的是元数据。它做四件事:每 12 小时把元数据 bundle 到 S3;5 阶段原地恢复,破坏性操作都隔离在一个 CLI 里;通过 API 在集群间拷贝数据集;外加围绕这些的 precheck、teardown、guard 命令。
设计意图是分层的:对象存储版本控制、元数据卷快照、元数据 KV 的时间点恢复层、逻辑导出。时间点恢复那一层我评估后在 9 月下旬放弃了。还有一点要直说:对象存储版本控制目前是关的,因为当时只有测试环境。这是依赖这套东西之前必须补的口子。
演练实测了什么
| 演练 | 环境 | 结果 |
|---|---|---|
| 原地恢复,2.74 TB / 1,799 个 tablet | preprod,生产规模 | clear 到 promote 55 分钟,其中约 25 分钟 花在一次失败和重试上;对象检查通过,行数与基线一致 |
| 同一数据集跨集群拷贝 | preprod | restore 阶段 33.5 分钟;重新设计后一次拷贝约 35 分钟,之前约 65 分钟 |
| 故障注入,17 个场景 | dev 集群 | 15 个场景验证零丢数;例如元数据卷被删,从快照恢复,约 43 秒回到 Ready |
| Frontend 与 KV 存储联合恢复 | dev 集群 | 恢复后数据逐字节一致 |
| 全流程 DR | dev 集群 | clear 到 promote 约 22 分钟 |
第一行要读仔细。含 25 分钟失败的 55 分钟,不是我愿意写进 SLA 的恢复时间。它是一条恢复路径,加上一次失败尝试的代价(约 25 分钟)。我报的是带着这次失败的数字。
论点:演练的价值是找到缺口
全流程跑完 22 分钟,单看是个好看的数字。但它真正的产出是别的:runbook 的 8 处缺口和 1 个代码 bug。有的步骤漏了,有的顺序错了,有的默认执行者在凌晨三点具备他其实没有的知识;还有一个只有跑完整条路径才会撞上的工具 bug。
这是我想推给任何团队的结论:演练不是用来测恢复时间的 benchmark,而是对 runbook 的一次审计。一次排练好的 RTO 只能说明作者执行自己的流程有多快。能预测真实事故的数字是,换一个人会在多少地方卡住。一次演练如果一处都没找到,要么不够真实,要么没有诚实地看。第一次全流程跑出 8 处缺口,是正常而健康的结果,每一处在 dev 集群上发现,都比在事故中发现便宜。
出于同样的原因,我不发布 RTO。在非生产集群、一个规模、带一次失败重试的单次演练,撑得起一个区间和一张待修清单,撑不起一个承诺。
目前的状态
平台已上线生产。上面的恢复数字早于上线,来自文中写明的环境。还没做的:开启对象存储版本控制、建立定期演练的节奏(这几次都是一次性的),以及让作者以外的人重跑一遍全流程,这才是检验 8 处缺口有没有真正补上的办法。