Appearance
高可用与容灾
很多方案里反复出现“K8s 自愈”“多副本”“故障域”,但没有把 HA 和 DR 分开讲。这两个词经常被混着用,实际是两件不同的事,成本也差一个量级。
一、三个词,先分清
| 概念 | 全称 | 一句话 | 典型手段 |
|---|---|---|---|
| HA | High Availability,高可用 | 局部故障不停服:一台机器、一个进程挂了,服务自动切到别的副本 | 多副本、选主、健康检查、滚动升级、PDB |
| DR | Disaster Recovery,灾难恢复 | 整个站点没了还能活:机房断电、光缆挖断、云区域故障、勒索软件 | 异地备份、跨站点复制、冷/温/热备站、切换预案、演练 |
| Backup | 备份 | 删错了、被加密了还能找回来:不是高可用,也不是容灾 | 全量 + 增量、快照、异地保存、恢复演练 |
一句话记:HA 解决"坏一台",DR 解决"坏一片",备份解决"手一抖"。
二、HA 和 DR 的差别
| 维度 | HA | DR |
|---|---|---|
| 故障范围 | 单节点、单进程、单可用区 | 整个机房 / 城市 / 云区域 |
| 目标 | 业务不中断 | 业务能恢复 |
| 切换方式 | 自动(秒级~分钟级) | 手动或半自动(分钟级~小时级) |
| 数据丢失 | 通常 RPO≈0 | RPO 取决于复制/备份频率 |
| 成本 | 中(多副本、多节点) | 高(第二套环境、专线、演练) |
| 最常见错误 | 以为有副本就不用备份 | 以为有备份就能立刻接管 |
三、RPO 和 RTO
这两个指标是 HA/DR 的验收口径,必须先定,否则"高可用"没法验收。
| 指标 | 含义 | 例子 |
|---|---|---|
| RPO | Recovery Point Objective,能容忍丢多少数据(按时间算) | RPO=15 分钟:故障时最多丢最近 15 分钟的数据 |
| RTO | Recovery Time Objective,能容忍停多久 | RTO=4 小时:从故障发生到业务恢复,最多 4 小时 |
分级示例(按数据底座的实际业务定,不要照抄):
| 级别 | 数据 | RPO | RTO | 方案 |
|---|---|---|---|---|
| T1 | 交易/主数据 | ≤15 分钟 | ≤4 小时 | 同城双活或温备 + 持续复制 |
| T2 | 分析/报表 | ≤24 小时 | ≤24 小时 | 每日备份 + 冷备重建 |
| T3 | 测试/沙箱 | 可丢 | 可重建 | 不备份,环境即代码 |
四、本栈的 HA 清单
| 层 | 组件 | HA 方式 | 故障切换 | 单点在哪 |
|---|---|---|---|---|
| 基础 | K8s 控制面 | 3 master + stacked etcd | 秒级选主 | 负载均衡/注册地址 |
| 基础 | Harbor | 2 副本 + 共享对象存储 | 分钟级 | 后端存储 |
| 基础 | OpenBao | 3 节点 Raft | 秒级选主 | 需要多数节点活着 |
| 基础 | Envoy Gateway | 2 副本 + 云 LB | 秒级 | LB 本身 |
| 存储 | Ceph | 3+ 节点、3 副本或 EC、CRUSH 故障域 | 自动重平衡 | 少于 2 个节点存活会丢数据 |
| 存储 | PostgreSQL | 主备流复制 + Patroni/自动 failover | 分钟级 | 仲裁/ VIP |
| 目录 | Polaris | 无状态多副本 + PG HA | 秒级 | PG |
| 消息 | Kafka | 3 broker、RF=3、minISR=2 | 秒级 | controller |
| OLAP | Doris | 3 FE(1 leader + 2 follower)+ 3 BE | 分钟级 | FE 多数派 |
| 计算 | Flink | K8s HA + checkpoint/Savepoint | 分钟级 | 状态存储(S3) |
| 计算 | Spark | K8s 重调度,作业级重试 | 作业重跑 | 无(批作业可重跑) |
| 调度 | DolphinScheduler | master/worker 多副本 + PG | 分钟级 | PG |
| 治理 | OpenMetadata | 多副本 + PG/ES HA | 分钟级 | PG/ES |
| 可观测 | Prometheus | 双实例 + 远程写 | 分钟级 | 存储 |
注意:副本数 ≠ 高可用。Kafka RF=3 但三个 broker 在同一台物理机上,照样一起挂;Ceph 三副本但在同一个机柜,照样一起断电。副本必须跨故障域。
五、本栈的 DR 设计
备份矩阵
| 对象 | 方式 | 频率 | 保留 | 恢复方式 |
|---|---|---|---|---|
| PostgreSQL(Catalog/元数据) | 全量 + WAL 归档(PITR) | 每日全量 + 持续 WAL | 30 天 | 恢复到任意时间点 |
| Iceberg 表数据 | 对象存储跨站点复制 | 持续/每日 | 按合规 | 从副本站点读 |
| Iceberg 元数据 | Catalog 逻辑导出(库表清单、快照) | 每日 | 30 天 | 重建 Catalog 后注册 |
| OpenBao | Raft 快照 | 每日 | 30 天 | 恢复 Raft |
| K8s 清单/配置 | Git | 每次变更 | 永久 | 重新 apply |
| 镜像 | Harbor 复制 + 保留策略 | 每次构建 | 最近 N 版 | 从副本拉 |
| 告警/看板配置 | Git + Grafana provisioning | 每次变更 | 永久 | 重新导入 |
站点级方案
| 方案 | 说明 | RTO | 成本 |
|---|---|---|---|
| 冷备 | 只保留备份和 IaC,灾难后重新买资源重建 | 小时~天 | 最低 |
| 温备 | 第二站点常驻最小集群,数据持续复制,需要时扩容 | 分钟~小时 | 中 |
| 热备/双活 | 两站点同时承载,流量切换 | 秒~分钟 | 最高 |
对本栈的现实建议:先做冷备 + 异地对象存储复制,把 RTO 压到"半天内能重建";等业务真的到 T1,再上温备。
演练
- 每季度做一次 restore drill:从备份恢复 PG + 一张 Iceberg 表,记录实际 RTO。
- 每半年做一次 站点切换演练:DNS/入口切到备站,验证 runbook。
- 备份失败要告警;没有演练过的备份,等于没有备份。
六、测试集群怎么摆
3 节点测试集群可以验证一部分 HA,但不要当成生产验收:
| 能验证 | 不能验证 |
|---|---|
| K8s 调度、Pod 重建、节点 drain | 跨机房/跨区域故障 |
| Kafka 3 broker、RF=3、broker 挂一个 | 机柜级故障、脑裂 |
| Doris 3 BE、副本分布、BE 挂一个 | 大规模并发、跨 AZ |
| Ceph 3 OSD、副本重平衡(如果裸盘可用) | 真实磁盘故障、PB 级 |
| PG 主备切换 | 同城双活、仲裁 |
| 滚动升级、PDB | 真实流量下的切换 |
测试集群的目标是"验证机制能跑",不是"验证指标达标"。
七、常见误区
- 有副本就不备份:副本会被误删、被勒索软件加密、被错误 DDL 同步。备份必须独立、离线或不可变(对象锁)。
- K8s 会自愈就不需要 DR:K8s 只能在同一集群内重建 Pod;集群没了、云区域没了,它无能为力。
- 备份文件在同一个账号/同一个桶:删库跑路或被攻击时一起没。至少一份异地、不同账号。
- 只看 RTO 不看 RPO:恢复得很快但丢了三天数据,业务照样不答应。
- 没有 runbook:真出事时靠现场发挥,切换步骤没人记得。