从 DigitalOcean 迁移到 Hetzner:零停机,月省 1200 美元

今天 HN 上最让人心里一动的一条,是这篇《Migrating from DigitalOcean to Hetzner》。它最打动人的地方,不是"从 1432 美元降到 233 美元"这个结果本身,而是整个迁移过程的完整性和可复现性。一个土耳其团队,在里拉大幅贬值的压力下,把一套 248GB MySQL、34 个 Nginx 站点、GitLab EE、Neo4j 的完整栈,从 DigitalOcean 迁移到 Hetzner 的独立服务器,全程零停机。

嗯,这个"零停机"不是运气,而是一套设计好的工程流程。他们把整个迁移拆成了六个阶段,每个阶段都有明确的目标和验证方法。

第一阶段是"在新服务器上完整安装所有服务"。他们不是简单装个 LAMP,而是连 Nginx 的编译 flag、PHP 的 ini 配置、MySQL 的版本、GitLab 的配置都完全复制过去。SSL 证书直接 rsync 整个 /etc/letsencrypt/ 目录,等迁移完成后再统一 renew。这一步的目的是确保新服务器在配置层面和旧服务器完全一致,避免"功能差异"导致的意外。

第二阶段是"用 rsync 克隆所有 web 文件"。65GB、150 万文件,用 rsync over SSH,带 checksum 验证。然后在 cutover 前再做一次增量 sync,确保没有遗漏任何变更。这一步的关键是"增量":先做一次全量,然后在最后时刻做一次增量,把时间窗口压缩到最小。

第三阶段是"MySQL 主从复制"。这是整个迁移的核心。他们没用 dump/restore,而是用 mydumper 做初始全量加载,然后从 binlog 位置开始做实时复制。这样旧服务器是 master,新服务器是 slave,数据一直在同步。cutover 的时候,只需要把 slave 切成 master,就能无缝接管。这一步的关键是"实时同步":在 cutover 前,新服务器的数据已经和旧服务器完全一致,差值只有几秒。

第四阶段是"降低 DNS TTL"。他们提前通过 DigitalOcean 的 DNS API,把所有 A 记录和 AAAA 记录的 TTL 从 3600 秒降到 300 秒。这样 cutover 的时候,DNS 传播只需要 5 分钟左右,而不是 1 小时。这一步的关键是"提前准备":TTL 的降低必须在 cutover 前就完成,否则 cutover 时的等待时间会不可控。

第五阶段是"在旧服务器上配置反向代理"。这一步最巧妙。他们不是直接改 DNS,而是先在旧服务器上把所有 Nginx 站点配置改成反向代理,代理到新服务器的 IP。这样在 cutover 的瞬间,旧服务器还能继续处理流量,只是把请求转发到新服务器。这给了一个缓冲:如果新服务器有问题,可以立刻回滚到旧服务器,而不用等 DNS 传播。这一步的关键是"可回滚":反向代理的存在,让 cutover 不再是"一次性操作",而是一个可逆的过程。

第六阶段才是"cutover"本身。他们的步骤非常清晰:先在新服务器上停止 slave 复制、关闭 read_only、重置 slave 配置、启动所有服务;然后在旧服务器上 reload Nginx(反向代理生效)、停止所有服务;最后通过脚本批量更新 DNS 记录。整个过程大概 10 秒,DNS 传播 5 分钟,全程没有用户感知。

嗯,这个过程最有价值的地方,其实是几个工程细节:

第一,他们把所有脚本都开源了。DNS 更新、Nginx 配置转换、MySQL 对比、GitLab webhook 更新,全部有现成的 Python 脚本,而且支持 DRY_RUN 模式。这意味着你可以直接复用他们的工具,而不是重新发明轮子。

第二,他们特别强调了 MySQL 的 SUPER 权限问题。如果应用用户有 SUPER 权限,那么即使 slave 设置了 read_only,这些用户仍然能写数据。这会导致主从不一致,在 cutover 时产生数据丢失。所以他们提前检查了所有用户的权限,确保 slave 真正是只读的。

第三,他们用 mydumper/myloader 替代 mysqldump/mysqld。对于 248GB 的数据,mydumper 的并行 dump/restore 能把原本几天的工作压缩到几小时。这个工具的选择,直接决定了迁移的可行性。

从成本角度看,这个迁移的回报很直接:从 1432 美元/月降到 233 美元/月,一年省 14388 美元。而且新服务器在性能上全面碾压:CPU 从 32 vCPU 变成 48 核 96 线程,RAM 从 192GB 变成 256GB DDR5,存储从混合 SSD 变成 NVMe RAID1。这种"更便宜、更强"的组合,在云厂商的定价体系里几乎不可能出现。

从工程角度看,这个迁移最有价值的,其实是那套方法论:提前准备、分阶段执行、实时同步、可回滚设计、脚本自动化。这套方法论不仅适用于 DigitalOcean 到 Hetzner,也适用于任何需要零停机迁移的场景。

所以今天真正值得记住的,不是"省了 1200 美元",而是另一句更根本的话:当你的工作负载是稳态的、可预测的、不需要弹性伸缩时,独立服务器往往比云厂商的虚拟机更划算。而"零停机迁移"不是一种运气,而是一套可以设计、可以复现的工程流程。