主备容灾:两台 VPS 做故障自动切换,小业务也用得起

单台 VPS 挂了业务就停?小够讲小业务的主备容灾:RTO/RPO 通俗解读、数据同步、DNS 切换、演练流程,两台便宜 VPS 就能搭起故障切换,不用买贵方案。

我是小够。备份是"数据丢了能找回来",容灾是"机器挂了业务不停"。备份人人都在做,容灾很多人觉得那是大厂的事——其实小业务也能做,两台便宜 VPS 就够。这篇把主备容灾讲透,不堆概念,只讲能落地的。

先搞懂两个词:RTO 和 RPO

容灾圈有两个黑话,翻译成人话:

  • RTO(恢复时间目标):挂了之后,多久能恢复?1 小时还是 1 天?
  • RPO(恢复点目标):最多能丢多少数据?1 小时的数据还是 1 天的?

小够的建议:先给自己的业务定个数。比如个人博客:RTO 4 小时、RPO 24 小时,完全可以接受。小电商:RTO 1 小时、RPO 1 小时。有了目标,方案才知道做到什么程度——容灾做到"够用"就行,别为用不上的指标花钱。

架构:主备两台

        [DNS]
       /     \
   [主VPS]   [备VPS]
   跑业务     待命+同步数据
  • 主:正常跑业务
  • 备:平时待命,数据实时/定时从主同步过来
  • 故障时:把流量切到备机

备机平时可以跑点不重要的东西(监控、测试),别让它完全闲置,闲置的机器出故障了你都不知道。

数据同步:核心中的核心

切换的前提是备机的数据是新的。分两层:

文件同步:rsync 定时同步,前面讲过:

# 在备机上定时从主机拉
rsync -az --delete user@primary:/var/www/ /var/www/

数据库同步:主从复制。MySQL/PostgreSQL 都支持,备库实时跟着主库走。配一次,之后自动同步。注意:主从有延迟(通常秒级),RPO 就取决于这个延迟。

不同步什么:日志、缓存、临时文件不同步,只同步"丢了会心疼的"。

切换:DNS 是最通用的方案

VPS 容灾切换最常用的办法是 DNS 切换:

  1. 平时域名 A 记录指向主机 IP
  2. 主机挂了,把 A 记录改成备机 IP
  3. 等 DNS 生效,流量就过去了

关键点:TTL 提前调小。平时 TTL 设 300 秒(5 分钟),故障时改记录,全球大部分地区几分钟内生效。如果 TTL 是 24 小时,切换了也要等一天,黄花菜都凉了。

# 平时就把 TTL 设小,应急时才来得及
# 以 Cloudflare 等 DNS 服务商为例,TTL 300

小够提醒:keepalived + 浮动 IP 是更高级的方案(秒级切换),但多数 VPS 商家不支持浮动 IP,别照着教程硬套。DNS 切换虽然慢几分钟,但通用、便宜、够用。

切换 checklist:故障时别慌

提前写好,贴在备忘录里,故障时照着打勾:

  1. 确认主机真的挂了(不是自己网络问题:换个网络 ping 一下)
  2. 确认备机数据是最新的(看最后一次同步时间)
  3. 备机上启动业务服务(平时待命的服务先起起来)
  4. DNS A 记录切到备机 IP
  5. 用手机流量访问一次,确认业务正常
  6. 发公告(如果有用户的话)
  7. 修主机,修好后数据反向同步,再决定切不切回去

第 1 条最重要:别把"我家断网了"当成"服务器挂了",先确认。

演练:不演练等于没有

容灾方案最大的坑是"从来没试过"。每季度演练一次:

  1. 挑个业务低峰期(比如周日凌晨)
  2. 按 checklist 走一遍完整切换
  3. 计时:RTO 达标了吗?数据丢了多少?RPO 达标了吗?
  4. 记录问题,修方案

演练一定会发现问题——这就是演练的意义。真故障时第一次用这套流程,基本都会翻车。

成本

两台 VPS,一台主力、一台备机(备机可以配置低一点,只保证能跑起来)。对比业务中断几小时的损失,这钱花得值。但小够也要说句实在话:个人博客、小实验项目,真没必要做主备——做好备份就行,RTO 4 小时完全可以接受。容灾是给"停不起"的业务准备的,别为用不上的指标花钱。

什么时候不做主备

  • 纯个人博客/实验项目:备份做好就行
  • 业务能容忍半天中断:修机器比养备机便宜
  • 数据不重要:丢了重搭的,随缘

什么时候必须做

  • 靠网站吃饭:电商、接单、SaaS,停一小时就丢钱
  • 有用户在用:服务挂了影响别人
  • 合规要求:某些业务要求有容灾方案

常见问题

Q:备机平时完全闲置吗? A:别完全闲置。跑点监控、测试环境之类的轻量东西,既利用了资源,又能保证机器是活的。完全闲置的机器,故障时才发现它三个月前就起不来了。

Q:DNS 切换期间,部分用户还在访问旧 IP 怎么办? A:正常。DNS 全球生效需要时间,TTL 300 秒的情况下,大部分地区几分钟内完成。极少数地区的旧缓存可能撑几小时,接受这个现实。

Q:主备切换后,数据写到备机了,主机修好怎么合并? A:这是最难的部分。简单方案:修好后把备机当成新的主,旧主机降级成备(反向同步一次)。双向同步容易冲突,别碰。

Q:演练会影响线上业务吗? A:选低峰期,提前公告。演练本身就是一次"可控的故障",比真故障时手忙脚乱强一百倍。

MySQL 主从复制实战

数据库同步用主从复制,备库实时跟着主库:

# 主库 my.cnf
server-id = 1
log_bin = mysql-bin
binlog_format = ROW
# 主库建复制用户
CREATE USER 'repl'@'%' IDENTIFIED BY '强密码';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
# 备库指向主库
CHANGE MASTER TO
  MASTER_HOST='主库IP',
  MASTER_USER='repl',
  MASTER_PASSWORD='强密码',
  MASTER_AUTO_POSITION=1;
START SLAVE;
# 检查同步状态
SHOW SLAVE STATUS\G
# 关键看这两个:Yes Yes
# Slave_IO_Running: Yes
# Slave_SQL_Running: Yes

Seconds_Behind_Master 是延迟秒数,正常应该是 0 或个位数。延迟大了查网络和备库性能。

健康检查脚本:自动发现,别自动切换

#!/bin/bash
# health-check.sh:每分钟跑一次,连续 3 次失败才判定
URL="http://主库IP/health"
fail=0
for i in 1 2 3; do
    curl -sf --max-time 5 $URL > /dev/null || fail=$((fail+1))
    sleep 10
done
if [ $fail -eq 3 ]; then
    echo "主库连续3次健康检查失败" | mail -s "容灾告警" [email protected]
fi

注意两点:一是 /health 要真的检查业务(连一下数据库,返回 200 才算健康),只检查"ping 得通"不够——机器活着、业务死了,是最常见的"假活";二是只告警、不自动切换,切换按钮留在人手里。自动切换最怕误判:网络抖动一下,两边都觉得自己是主,数据写散了(脑裂),比停机更惨。

脑裂:最可怕的故障

脑裂 = 主备同时认为自己是主,同时写数据。恢复时两边数据对不上,神仙难救。预防:

  1. 切换前确认主库真的死了(多路检查:本机、外网、商家面板)
  2. 主库恢复后,先当备库同步,别直接写
  3. 业务允许的话,切换期间短暂只读,等确认再放开写

演练剧本

每季度一次,按这个剧本走:

时间:周日 03:00(低峰)
1. 03:00 宣布演练开始,业务切维护页(可选)
2. 03:05 模拟主库故障(停服务)
3. 03:06 按 checklist 切换到备库
4. 03:15 验证业务正常,记录 RTO
5. 03:20 检查数据:备库和主库差多少,记录 RPO
6. 03:30 切回主库,恢复正常
7. 整理演练报告:哪里卡了,下次改进

第一次演练一定超时,这很正常。演练三次后,RTO 会稳定在一个可预期的数字。

小够的最终建议

容灾是个光谱,不是非黑即白:

  1. 备份做好(人人都要)
  2. 文档写好(切换 checklist)
  3. 主备搭起来(停不起的业务)
  4. 演练跑起来(搭了不练等于没搭)

一步一步来,别想着一次到位。先把第 1、2 步做到位,已经超过 90% 的个人站长了。

DNS 服务商的选择

DNS 切换是容灾的核心环节,DNS 服务商得靠谱:

  • 生效速度:改记录后全球生效要多久,TTL 设小是前提,服务商本身的推送速度也有差异
  • API 支持:故障时手动改太慢,有 API 就能写脚本自动切(配合健康检查)
  • 监控联动:有些 DNS 服务商自带健康检查,机器挂了自动切记录,连脚本都不用写

小够的建议:DNS 别用域名注册商送的免费版,找个专业的。TTL 300 秒是底线,平时就这么设着。

切换后的 DNS 传播

# 从多个地点查 DNS,看切换进度
dig @8.8.8.8 yourdomain.com +short
dig @1.1.1.1 yourdomain.com +short

不同地区的生效时间不一样,盯着看,别假设"改了就全生效了"。

数据一致性:切换时最痛的部分

主备切换必然丢一点数据(主从延迟那几秒),怎么办:

  1. 接受它:RPO 就是干这个的,提前和业务方对齐"最多丢 X 秒数据"
  2. 减小它:主从延迟平时就监控,延迟大了先优化,别等故障时才发现延迟 10 分钟
  3. 记录它:切换后记下"大约丢了 X 分钟的数据",事后对账用

电商订单这种,丢几秒可能是真金白银。RPO 定 1 小时的业务,和 RPO 定 1 分钟的业务,架构完全不是一个级别——先定 RPO,再定架构。

小够的实话

说实话,个人站长做主备,90% 的时间备机都在闲置,心理上会觉得"浪费钱"。算笔账:备机一台便宜 VPS,一年几百块;真出一次故障,手动恢复+数据丢失+用户流失,损失只多不少。

但反过来,为了"万一"过度投入也是浪费。判断标准就一条:这业务停 4 小时,你心疼吗?心疼就做,不心疼就把备份做好。够用就好,容灾也一样。

切换演练记录表

每次演练填一张表,贴在文档里:

演练日期:2025-XX-XX
场景:模拟主库宕机
开始时间:03:00
业务恢复时间:03:12  → RTO 12 分钟(目标 60 分钟,达标)
数据丢失:约 2 分钟 → RPO 2 分钟(目标 5 分钟,达标)
发现的问题:
  1. 备机上有个服务没设开机自启,手动起的
  2. DNS 生效比预期慢,某地区 20 分钟才切过来
改进:
  1. 备机服务全部 systemctl enable
  2. 换 DNS 服务商 / 接受现实

演练记录是容灾方案的"体检报告",一年攒四张,方案越来越靠谱。

多云容灾:要不要跨商家

主备在不同商家,优点是商家级故障也不怕,缺点是网络延迟大、同步慢、成本高。

小够的建议:先同商家不同机房,跑顺了再考虑跨商家。跨商家是"进阶版",别第一步就上难度。记住:能稳定跑起来的简单方案,胜过跑不起来的完美方案。

容灾和备份的关系

最后再理一遍两者的关系:

  • 备份:数据丢了,找回来。RTO 长(几小时),RPO 取决于备份频率
  • 容灾:机器挂了,业务不停。RTO 短(几分钟),RPO 取决于同步延迟
  • 关系:容灾不能替代备份。备机也可能丢数据(误删、逻辑错误会同步过去),备份是最后一道防线

备份是 1,容灾是后面的 0。没有 1,再多 0 都是 0。

给不同规模的建议

规模方案
个人博客备份做好,容灾不需要
小电商/接单备份 + 文档化的手动切换流程
日活上万的业务主备 + 自动健康检查 + 季度演练
再大请专职运维,别看博客了

对号入座,够用就好。容灾做到"匹配业务规模",就是最好的容灾。