17 ポイント 投稿者 GN⁺ 11 일 전 | 1件のコメント | WhatsAppで共有
  • 月額 $1,432 規模の本番インフラ月額 $233 の専用サーバーへ移しつつ、OS まで入れ替えながらもダウンタイムなしでサービス継続性を維持
  • 30個のMySQLデータベースと34個のNginx仮想ホスト、GitLab EE、Neo4J、Supervisor、Gearmanを新サーバーに同等構成で再現し、リアルタイム複製と最終増分同期で移行を完了
  • データベース移行の要はmydumper・myloader の並列処理MySQL replicationの組み合わせであり、MySQL 5.7 から 8.0 への更新時に発生した sys スキーマと権限の問題も修正
  • カットオーバーはDNS TTL の短縮、既存サーバーのNginx リバースプロキシ化、A レコード一括変更の順で進められ、DNS 伝播中も旧 IP へのリクエストが新サーバーへ転送される構成
  • 結果として月額 $1,199 削減年額 $14,388 削減、CPU・メモリ・ストレージ強化とダウンタイム 0 分を同時に達成した事例

移行の背景

  • トルコでソフトウェア会社を運営する環境において、急激なインフレトルコリラ安により、ドル建てのインフラ費用負担が大きく増加していた状況
  • 既存の DigitalOcean サーバー費用は毎月 $1,432 で、構成は 192GB RAM、32 vCPU、600GB SSD、1TB ブロックボリューム 2本、バックアップ込み
  • 新たな移行先は Hetzner AX162-R 専用サーバーで、AMD EPYC 9454P 48コア 96スレッド、256GB DDR5、1.92TB NVMe Gen4 RAID1 構成
  • 月額費用は $233 まで下がり、月間削減額は $1,199、年間削減額は $14,388 規模
  • 既存サーバーの信頼性や開発者体験に不満はなかったが、steady-state ワークロードでは価格対性能がもはや合理的ではない状態

既存の運用環境

  • 運用スタックは単なるテスト環境ではなく、実際の本番環境構成
    • MySQL データベース 30個、合計 248GB のデータ規模
    • 複数ドメインにまたがる Nginx 仮想ホスト 34個 を運用
    • GitLab EE バックアップ 42GB を含む
    • Neo4J Graph DB を 30GB 規模で運用
    • Supervisor で数十個のバックグラウンドワーカーを管理
    • Gearman のジョブキューを使用
    • 数十万ユーザー向けのライブモバイルアプリを運用
  • 既存サーバーの OS は CentOS 7 で、すでにサポート終了状態
  • 新サーバーの OS は AlmaLinux 9.7 で、RHEL 9 互換ディストリビューションであり、CentOS の自然な後継候補
  • 今回の移行はコスト削減だけでなく、数年間セキュリティアップデートを受けられなかった OS から脱却する契機でもあった

無停止戦略

  • 単純な DNS 切り替えとサービス再起動の方式は採らず、6段階の移行手順で無停止移行を実施
  • 第1段階: 新サーバーにスタック全体を構築

    • Nginx を既存環境と同じフラグでソースからコンパイルしてインストール
    • PHP は Remi repo 経由でインストールし、既存サーバーと同じ .ini 設定ファイルを適用
    • MySQL 8.0Neo4J Graph DBGitLab EENode.jsSupervisorGearman をインストールし、既存動作と一致するよう構成
    • DNS レコードに手を触れる前に、すべてのサービスが既存サーバーと同様に動作する状態まで整備
    • SSL 証明書は既存サーバーの /etc/letsencrypt/ ディレクトリ全体を rsync でコピーして対応
    • 全トラフィックが新サーバーへ切り替わった後、certbot renew --force-renewal で証明書を一括強制更新
  • 第2段階: Web ファイルの rsync 複製

    • /var/www/html ディレクトリ全体、約 65GB150万ファイルを SSH ベースの rsync で複製
    • --checksum オプションで整合性を検証
    • カットオーバー直前に変更ファイルを反映する最終増分同期も追加実施
  • 第3段階: MySQL マスター・スレーブ複製

    • ダンプ後に復元してデータベースを止めるのではなく、リアルタイム複製を構成
    • 既存サーバーをマスター、新サーバーを読み取り専用スレーブとして設定
    • 初期の大容量投入には mydumper を使い、その後ダンプのメタデータに記録された正確な binlog 位置から複製を開始
    • カットオーバー時点まで両データベースをリアルタイム同期状態で維持
  • 第4段階: DNS TTL の短縮

    • DigitalOcean DNS API をスクリプトから呼び出し、すべての A/AAAA レコード TTL を 3600 秒から 300 秒へ短縮
    • MX、TXT レコードは変更しない
    • メールレコードの TTL を変更すると配送性の問題を引き起こす可能性があるため除外
    • 既存 TTL が世界中で失効するよう 1時間待機し、その後 5分以内でカットオーバー可能な状態に準備
  • 第5段階: 既存サーバーの Nginx をリバースプロキシ化

    • Python スクリプトが 34個の Nginx サイト設定全体の server {} ブロックを解析
    • 既存設定はバックアップし、新サーバーを向くプロキシ設定へ置き換え
    • DNS 伝播中も旧 IP に到達するリクエストは新サーバーへ静かに転送される構成
    • ユーザー視点では中断が見えない方式
  • 第6段階: DNS カットオーバーと既存サーバー停止

    • Python スクリプトで DigitalOcean API を呼び出し、すべての A レコードを数秒で新サーバー IP に変更
    • 既存サーバーは 1週間 cold standby として維持した後に停止
    • サービスは全過程を通じて直接応答するか、またはプロキシ経由で応答する形で維持され、可用性の空白時間はなかった

MySQL 移行

  • 全作業の中で最も複雑な区間が MySQL の移行工程
  • データダンプ

    • 標準の mysqldump ではなく mydumper を使用
    • 新サーバーの 48 CPU コアを活用した並列 export/import により、単一スレッドの mysqldump なら数日かかる作業を数時間へ短縮
    • 主な使用オプションには --threads 32, --compress, --trx-consistency-only, --skip-definer, --chunk-filesize 256 を含む
    • メインダンプの metadata ファイルにはスナップショット時点の binlog 位置を記録
      • File: mysql-bin.000004
      • Position: 21834307
    • この値が後続の複製開始位置として使われた
  • ダンプ転送

    • ダンプ完了後、SSH ベースの rsync で新サーバーへ転送
    • 合計 248GB の圧縮チャンクを転送
    • mydumper--compress オプションにより、圧縮チャンクがネットワーク転送速度の向上に寄与
  • データ投入

    • myloader を使用
    • 主なオプションは --threads 32, --overwrite-tables, --ignore-errors 1062, --skip-definer
  • MySQL 5.7 から 8.0 への移行時の問題

    • CentOS 7 環境のため、既存サーバーは MySQL 5.7 に留まっていた状態
    • 移行前に mysqlcheck --check-upgrade でデータが MySQL 8.0 と互換か確認し、結果は問題なし
    • 新サーバーには最新の MySQL 8.0 Community をインストール
    • プロジェクト全体でクエリ実行時間が有意に短縮し、原文では MySQL 8.0 の改善された optimizerInnoDB の強化が理由として挙げられている
    • ただし、バージョンジャンプによる問題も発生
      • import 後、mysql.user テーブルのカラム構造が想定の 51個ではなく 45個 だった
      • その結果、mysql.infoschema の欠落やユーザー認証障害が発生
    • 最初の修正試行では以下のコマンドを使用
      • systemctl stop mysqld
      • mysqld --upgrade=FORCE --user=mysql &
    • 最初の試行は ERROR: 'sys.innodb_buffer_stats_by_schema' is not VIEW エラーで失敗
    • 原因は sys スキーマがビューではなく通常テーブルとして import されていたこと
    • 解決策は DROP DATABASE sys; を実行後にアップグレードを再実行する方法
    • その後は正常完了

MySQL 複製構成

  • 両サーバーでダンプ投入が終わった後、新サーバーを既存サーバーの replica として構成
  • CHANGE MASTER TO 構文に既存サーバー IP、複製ユーザー、ポート 3306、MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=21834307 を指定
  • その後 START SLAVE; を実行
  • ほぼ即座に error 1062 Duplicate Key で複製が停止
  • 原因はダンプが2回に分かれて行われ、その間に一部テーブルへ書き込みが発生し、import 済みダンプと binlog 再生が同じ行を重複挿入しようとしたこと
  • 解決のため以下の設定を適用
    • SET GLOBAL slave_exec_mode = 'IDEMPOTENT';
    • START SLAVE;
  • IDEMPOTENT モードは duplicate key と missing row エラーを静かにスキップする方式
  • すべての重要データベースがエラーなく同期され、数分以内に Seconds_Behind_Master の値は 0 に低下

カットオーバー前の検証

  • DNS レコードに手を触れる前に、新サーバー上ですべてのサービスが正しく動作するか確認が必要
  • 検証方法はローカルマシンの /etc/hosts ファイルを一時的に修正し、ドメインを新サーバー IP にマッピングする方式
  • ブラウザと Postman は新サーバーへリクエストを送り、外部ユーザーは引き続き既存サーバーへ接続する構成
  • API エンドポイント、管理パネル、各サービスの応答状態を確認
  • すべて確認後に実際のカットオーバーを実施

SUPER 権限の問題

  • マスター・スレーブ複製が完全同期した後、新サーバーで read_only = 1 にもかかわらず INSERT 文が成功する現象を確認
  • 原因はすべての PHP アプリケーションユーザーに SUPER 権限が付与されていたため
  • MySQL では SUPER 権限が read_only を回避する
  • SHOW GRANTS FOR 'some_db_user'@'localhost'; の結果で SUPER 権限が含まれていることを確認
  • 合計 24個のアプリケーションユーザーに対して REVOKE SUPER ON *.* FROM 'some_db_user'@'localhost'; を繰り返し実行
  • その後 FLUSH PRIVILEGES; を実行
  • 以後は read_only = 1 がアプリケーションユーザーの書き込みを正しくブロックしつつ、複製は継続して許可される状態になった

DNS の準備

  • すべてのドメインは DigitalOcean DNS で管理され、ネームサーバーは GoDaddy で接続されていた状態
  • TTL 短縮作業は DigitalOcean API を対象にスクリプト化
  • 変更対象は A、AAAA レコードのみに限定
  • MX、TXT レコードには手を触れない
    • Google Workspace の配送性問題の可能性があるため、メール関連レコードの TTL 変更は除外
  • 既存 TTL の失効のため 1時間待機し、カットオーバー準備を完了

既存サーバー Nginx のリバースプロキシ化

  • 34個の設定ファイルを手作業で編集する代わりに、Python スクリプトで自動変換を実施
  • スクリプトはすべての設定ファイルの server {} ブロックを解析し、主要な content block を特定してプロキシ設定へ置換
  • 元の設定は .backup ファイルとしてバックアップ
  • 例示された設定では proxy_pass https://NEW_SERVER_IP;, proxy_set_header Host $host;, proxy_set_header X-Real-IP $remote_addr;, proxy_read_timeout 150; を適用
  • 重要なオプションは proxy_ssl_verify off
    • 新サーバーの SSL 証明書はドメインに対しては有効だが、IP アドレスに対しては有効ではないため
    • 両端を自分たちで制御する環境であるため、ここでは検証無効化を許容

カットオーバー手順

  • カットオーバー直前の条件は複製遅延が Seconds_Behind_Master: 0 で、リバースプロキシ準備完了状態
  • 実行順序は以下の通り
    • 新サーバーで STOP SLAVE;
    • 新サーバーで SET GLOBAL read_only = 0;
    • 新サーバーで RESET SLAVE ALL;
    • 新サーバーで supervisorctl start all
    • 既存サーバーで nginx -t && systemctl reload nginx を実行し、プロキシを有効化
    • 既存サーバーで supervisorctl stop all
    • ローカル Mac で python3 do_cutover.py を実行し、DNS のすべての A レコードを新サーバー IP に変更
    • 5分 伝播を待機
    • 既存サーバーですべての crontab エントリをコメントアウト
  • DNS カットオーバースクリプトは DigitalOcean API を呼び出し、すべての A レコードを約 10秒 で変更

カットオーバー後の追加作業

  • 移行完了後、多数の GitLab プロジェクト Webhook が依然として既存サーバー IP を指していることを確認
  • GitLab API を使って全プロジェクトを走査し、Webhook を一括更新するスクリプトを作成して適用

最終結果

  • 月額費用は $1,432 から $233 に減少
  • 年間削減額は $14,388
  • 性能面でもより強力なサーバーを確保
    • CPU は 32 vCPU から 96 logical CPU へ増加
    • RAM は 192GB から 256GB DDR5 へ増加
    • ストレージは約 2.6TB の混在構成から 2TB NVMe RAID1 へ移行
    • ダウンタイムは 0分
  • 移行全体の所要時間はおよそ 24時間
  • ユーザー影響はなかった

重要な学び

  • MySQL replication は無停止移行の中核手段
    • 早い段階で設定し、十分に追いつかせた上でカットオーバーする方式
  • MySQL ユーザー権限は移行前に必ず点検が必要
    • SUPER 権限があると read_only を回避し、スレーブ環境が実際には読み取り専用でなくなる問題
  • DNS 更新、Nginx 設定変更、Webhook 修正はスクリプト化が重要
    • 34サイト以上を手作業で処理すると時間がかかり、エラーの可能性も増える
  • mydumper + myloader の組み合わせは大規模データセットで mysqldump よりはるかに高速
    • 32スレッド並列ダンプ・復元により、数日かかる作業を数時間へ短縮
  • steady-state ワークロードではクラウドプロバイダーが高価になり得ず、専用サーバーがより低コストで高性能を提供できる例

GitHub スクリプト

  • 移行に使った Python スクリプトをすべて GitHub で公開
  • 含まれるスクリプト一覧
    • do_list_domains_ttl.py
      • すべての DigitalOcean ドメインの A レコード、IP、TTL を取得
    • do_ttl_update.py
      • すべての A/AAAA レコード TTL を 300秒へ一括短縮
    • do_to_hetzner_bulk_dns_records_import.py
      • すべての DNS zone を DigitalOcean から Hetzner DNS へ移行
    • do_cutover_to_new_ip.py
      • すべての A レコードを既存サーバー IP から新サーバー IP へ切り替え
    • nginx_reverse_proxy_update.py
      • すべての nginx サイト設定をリバースプロキシ設定へ変換
    • mysql_compare.py
      • 2台の MySQL サーバー全体のすべてのテーブル row count を比較
    • final_gitlab_webhook_update.py
      • すべての GitLab プロジェクト Webhook を新サーバー IP に更新
    • mydumper
      • mydumper ライブラリ
  • すべてのスクリプトは DRY_RUN = True モードをサポートし、実適用前に安全なプレビューが可能

1件のコメント

 
GN⁺ 11 일 전
Hacker News のコメント
  • 数か月前にサーバー2台をLinodeとDOからHetznerへ移したが、コストをかなり大きく、しかも同程度に削減できた。さらに印象的だったのは、数十のサイトが異なる言語、古いライブラリ、MySQLやRedisまで絡み合ったカオスなスタックだったことだ。ところがClaude Codeがこれを丸ごと移行してくれて、存在しないライブラリは一部コードを書き直しながら対応していた。こうした複雑な移行はいまやずっと簡単になっていて、今後は事業者間の移動性がさらに高まる気がする

    • 私の考えでは、人々がお金を払っていたのは魔法のようなコンピュートのためではなく、10年分継ぎ足してきたglue codeに触れずに済ませるためだった。だがエージェントがそのglueを食い始めるなら、既存事業者のmoatは急速に薄くなりそうだ
    • 正直、これはClaudeの広告の中にHetznerの広告がさらに入っている感じだ。いったいどこまで入れ子になるのか気になる
    • 何でもかんでも必ずAIの話に持っていく必要はないと思う
    • 私も今後数か月のうちにLinodeを離れる予定だ。10年以上使っていて顧客もかなり紹介したが、価格を上げ続けたせいで、今ではHetznerのような所でより安くメモリ8倍、専用NVMe、専用CPUを得られる。仮想サーバーの移しやすさのような利点は少し失うが、障害が起きてもHetznerのサポートはいつも速くて有能だった
    • 私もClaudeをだんだんDevOpsに使うようになっている。手元のベアメタル上でProxmoxによりVMを動かしているが、Claudeが複数マシンにまたがる新しいネットワークを驚くほど素早く最適化して構成してくれて、ほとんど同僚か、報酬の高いsysadminのように感じる
  • AWSからHetznerへ移る計画を立てている。Amazonは競合より時には20倍高い価格を付け、少しまともな価格を得ようとすると長期契約を強要し、データ移行も非常に高くつくようにしていて、あまりに顧客敵対的だと感じる。egress料金で人を囲い込んでいるつもりなのだろうが、実際には一部だけ競合へ移しても全体を移させる圧力として働く。それでも私はAmazon専用サービスの上にプラットフォームを積んでいないので、移行は多少しやすい方だ

    • この点は以前はその通りだったが、2024年1月にGCPがegress費用免除ポリシーを出して空気が変わり、AWSも数か月後に似たポリシーを合わせてきた。残るよう説得したいわけではなく、技術的にはwaiver申請が可能だと言いたいだけだ。実際にどこまで適用されるのかは私も確信がなく、AWSの文言を見るとEU Data Actの影響もありそうだった
  • こういう記事を見るたびに、みんな冗長化やロードバランサーの話をあまりしないのが不思議だ。サーバー1台が死ねば複数のサービスが一緒に落ち得るのに、本当にそれで問題ないと思っているのか気になる。金は節約できても、保守時間や将来の頭痛の種を余計に抱えるかもしれない

    • これはサービスの性質とその重要度によると思う。サーバー1台が10年動き続け、その間の停止が1週間〜1か月程度なら十分受け入れられるケースは多い。小規模ビジネス、趣味サイト、フォーラム、ブログのようにWebサイトが中核業務でない所では、短いダウンタイムは大きな問題にならないかもしれない。実際、こうした低トラフィックサイトのロングテールこそWebの多数派かもしれない。すべてが高可用性である必要はなく、望むならこうした事業者もロードバランサーのような機能は提供している
    • こうした記事が人気になる理由は、しばしば要件と解決策の不一致が露わになるからだと思う。趣味プロジェクトや小さなビジネスにエンタープライズ級アーキテクチャを載せて過剰設計しているだけなら、たまに1日くらい落ちても構わず、クラウド式のフルセットは必須ではないかもしれない。ただ今回の記事は無停止マイグレーションを強調しつつ、到着後の構成は障害耐性が高く見えない点が少し奇妙だった。Hetzner側で構成を少し足すだけでも十分改善できた気がする
    • 多くのワークロードでは、そのレベルの備えは必要ないと思う。そしてシンプルさの信頼性を過小評価すべきではない。私は長年Linuxのsysadminとして働いてきたが、複雑なシステムで見るダウンタイムは単純なシステムよりずっと多かった。理論と現実のどこかの地点で、たいていの場合は結局シンプルな方がよく耐えるという印象を持っている
    • 公平に言えば、もともとDigitalOceanの単一VMを使っていたのだから、クラウド事業者の利点を大きく享受していた状況ではなかったと思う。たいていこういう話は、間違った理由でクラウドに乗っていて物理寄りへ行くのが正しいケースと、逆にそう移すと惨事になるケースに分かれるが、今回は前者に近そうだ。DOでうまく回っていた構成なら、Hetznerでも適切なDRポリシーさえ入れれば十分問題なさそうだ
    • おそらくこの判断は、実際には長いあいだ保守地獄や将来の頭痛の種をあまり経験してこなかったことに基づいているのかもしれない
  • 私たちはlithus.euで、さまざまなクラウドからHetznerへ顧客をよく移してきた。通常はマルチサーバー、時にはマルチAZ構成にし、Kubernetesでワークロードを分散してHAを提供している。単一ノードならKubernetesはやり過ぎかもしれないが、ノードが複数あるならずっと筋が通る。バックアップはVeleroとアプリケーションレベルのバックアップを併用し、たとえばPostgresではWALバックアップでPITRまで持っていく。状態データは最低2ノードに置いてHAを保証する。性能面でもベアメタルの方が概して良く、AWS比で応答時間が半分になることが多かった。理由は仮想化そのものというより、NVMe、低いネットワーク遅延、少ないcache contentionといった周辺要因のおかげだと思う。関連内容は以前書いたHN投稿にもさらに書いてある

    • 私も数年前に自分で測定してみたが、それ以来仮想サーバーに戻れなくなった。CPU時間はRAMのように予約されるものではないので、実ハードウェアに対して本当に性能がひどかった。計測記事も参考になる
    • k8sデプロイは持ち運びが本当にしやすいと感じる。各クラウドのマネージドサービス群に比べてベンダーロックインが少ない。私のスタックもk8s、hosted Postgres、S3系ストレージ程度なので、Postgresはいつでも自前運用できるし、結局コアはk8sとS3くらいしか残らない。HetznerにもS3っぽいものがあるようだがまだ見ておらず、100TBを移すのはかなり大仕事になりそうだ
    • 参考までにHAはhigh availabilityの意味だ
    • 記事は筋が通っていたが、最後にメールアドレスを載せていたのは少し宣伝文句っぽく見えて残念だった
  • この記事はかなり読みにくかった。Claudeがマイグレーションをして、その次にClaudeが書いたレポートを読まされている感じだった。LLMのおかげでこれだけ節約できたならそれは素晴らしいが、公開するならせめて推敲して、重複やLLMっぽい語り口は整理してほしかった

    • 原文を読まない人が多いのは分かるが、今回の記事は本当につらいレベルで読みにくかった
  • Hetznerには注意が必要だと思う。以前は本当に気に入っていたが、最近離れた。うちのCI/CDパイプラインで使っていたVM約30台を、36ドルの請求争議1件で全部落とされた。銀行記録を含めて全額支払い済みの証拠を出しても見ようとせず、緊急で連絡を取っている最中にも結局アクセスをすべて遮断された。今はScalewayへ移した

    • カスタマーサービスが意外と敵対的だと感じる。それでも重要でない用途にはまだ使っている
    • Hetznerの請求処理はかなり自動化されているが、通常はカード決済が失敗しても1か月ほどの猶予をくれることが多かった
  • 数か月前、小さなSaaSのサイドプロジェクト向けにAWS代替を探していたとき、コスト削減とEUクラウド支援の観点から最初はHetznerを真剣に検討していた。自分でやることが多くても受け入れるつもりだったが、決定的にIPレピュテーションが足を引っ張った。会社で使っているマネージドAWSファイアウォールのルールの1つがHetznerのIPを多く、もしかすると全部ブロックしていて、私の業務用ノートPCでもHetzner IP上のサイトはITポリシーのせいで開けなかった。Cloudflareのようなものを使えば多少ましになるかもしれないが、DDoS保護が弱いという話も見た。結局私はEUリージョンのDO App Platformを選び、マネージドDBオプションも大きな利点だった

    • 競合をこんなふうにブロックしてしまうなら、Amazonにとっては実に都合のいいやり方だと思う
    • どのファイアウォールルールのことか分からないが、DOがHetznerより信頼されているというのはかなり意外だった。私がスクレイパーやハッカーを見るときはDOのASNもよく出てくるので、あちらもいつかはブロックされ得ると思う
    • 私の経験ではDOのIPの方がひどかった。私もまさにその理由でDOから移った
    • 私は以前Tor関連スレッドでこの問題について書いたことがある。HetznerがTorフレンドリーなのでIPレピュテーションに影響しているのではと推測していたが、そのときはレピュテーション問題はないという返答もあった。だがTor Projectの資料を見ると、HetznerがTorネットワークの約7%を占めているようで、話はそれほど単純ではなさそうだった
    • 皮肉なことに、私はAWSとAzureのブロックだけでボット問題の99%を解決した。実ユーザーへの被害は0で、だからこのブロック機能だけをサービスとして売ろうかと考えている
  • こうしたマイグレーション体験を共有してくれたのはかなり有益でありがたい。私はDOとHetznerの比較を、DoorDashやUberEatsを開くのと自分で夕食を作ることのトレードオフのように見ている。コスト比率も似たような感じだ。私は3大クラウドとオンプレミスの両方を扱うが、細かい作業やPoCテストでは今でもDigitalOceanのコンソールに向かう。ボタンを数回押すだけでサーバーやバケットが用意され、sane defaultがあり、バックアップもチェックボックス1つで付くといった利便性は、時間の価値を考えれば確かに意味がある

    • どういう意味か完全には自信がないが、HetznerのConsoleも同様に動くと感じる
    • この記事で興味深かったのは2点あった。1つは無停止移行の手順そのもので、これは汎用的に参考になる。もう1つはクラウドインスタンスをベアメタルに変えた判断で、コスト削減とともに迅速なフェイルオーバーやバックアップ損失も価格に含まれていると考えるべきだ。私なら200ドルほど余分に出してhot spareを1台置き、数日おきに主従を入れ替えながら両方が正常動作するか検証したと思う。比較的小さなコストで致命的障害のリスクを大きく下げられる
    • いま説明したものは、実はHetzner Cloudがもう何年も提供している体験とほぼ同じだ。しかもHetzner Cloud APIもあるので、ボタンをクリックすることすらなくIaCで全部構成できる
    • 私の場合、Hetznerサーバー上にCoolifyを載せて、ほぼワンクリックサービスのような体験を得ている
    • この状況を見て思い浮かんだのは単にこの xkcdだった
  • DBバックアップをどうしているのか気になった。replicaやstandbyがあるのか、それとも単に時間単位バックアップなのか知りたかった。こうした単一サーバー構成では、SSDのようなハードウェア障害が起きるとアプリがすぐ止まり得るし、特にSSDが死ぬと再構築のあいだ何時間、あるいは何日も停止するかもしれないと思った

    • Hetznerは通常、ハードウェアサーバーを2x 1TB SSDとして宣伝し、実効容量1TBのためにSW RAID1構成を強く推奨している。イメージインストーラも既定でその方向だ。数年後に最初のSSDが死んでも、監視で検知できれば新しい箱へ移すか、中間的な代替やreplicaを使うか、別ディスクでしのぎながらホットスワップ対応を受けられる。もちろん物理サーバーへ行けばクラウドの冗長性の一部は失うので、節約額と合わせてリスクモデルに入れて計算すべきだ。そして最低でもリモートストレージへの日次バックアップすらないなら、それは無謀だと思う。これはクラウドでも同じで、設定がより簡単なだけだ
    • それだけ長く落ちていても、誰もあまり気にしないかもしれない。たとえば私のHOAモバイルアプリが1週間落ちていても、私は大して困らない。何もかもに常時稼働が必要なわけではない
    • 私も同じ懸念を抱いた。この記事は、筆者が十分に考えず攻めたコスト削減だけを見ていたように感じた。DigitalOceanのVMはおそらくライブマイグレーションやスナップショットをサポートしていたはずだが、Hetznerでもそれはcloud製品でしか可能ではない。Hetznerベアメタルではディスクや部品が死ねば本当に終わりで、ディスク交換はしてくれても復旧は利用者がゼロからやるしかない。Hetzner自身もこの点をいくつもの場所で明確にしている
    • 私がやった中で最も簡単だったのはMongoDBの方で、replication、sharding、failoverが非常に簡単だった。最近はPostgreSQLでもpg_auto_failoverでmonitor 1台、primary 1台、replica 1台の構成にしたが、設定と落とし穴を少し学べばこれもかなり簡単だった。私の経験では無停止移行も可能だった
    • 彼らがそのトレードオフを受け入れると判断したのなら、それが間違いだと断定はできないと思う。すべてのアプリが24/7の可用性を必要とするわけではなく、大半のWebサイトは数時間のダウンタイムがあっても大きな打撃はない。コスト削減がリスクを上回るなら、十分合理的なビジネス判断になり得る。むしろ気になるのは、彼らがどんなバックアップ・復旧戦略を持っているのか、そしてHetznerへ移ることで何が変わったのかだ
  • ヘッダーに入っていたミーム画像は私が作ったものだった。この記事に載せたもので、こんなふうに2回も使われているのを見るとうれしかった