Skip to content
On this page

📆 2024-03-13

複数の AWS RDS クラスタを一つに統合した

複数の AWS RDS クラスタを一つに統合して、インフラ費用と保守コストを削減した。

概要

私が開発に携わっている SaaS はデータストアとして Aurora MySQL の RDS クラスタを利用している。

障害耐性を高めるために、マイクロサービス毎に RDS クラスタが分割されていた。

しかしインフラ費用が高額だったり、保守工数をとられていたため、統合することになった。

  • 統合前

    統合前のイメージ

  • 統合後

    統合後のイメージ

タスクの洗い出し

まずは統合に必要なタスクを洗い出した。

以下のようなタスクがあるだろうということになった。

検証と手順の確立

  • ノーメンテでの統合方法の検討

    • 稼働中の RDS クラスタ間の バイナリログ(binlog)レプリケーションができるかの検証
    • AWS RDS Proxy を使ったダウンタイムの軽減ができるかの検証
  • 影響範囲の洗い出し

    • アプリケーションサーバ
    • Terraform, GitHub Actions, AWS Lambda
    • 監視
  • 手順の確立

    • 手順書作成
    • 開発環境での試験的な実施

試験

  • 負荷試験
  • アプリケーションサーバの動作確認

実施

  • 実施スケジュールの作成と、SaaS 利用ユーザへの告知
  • 実施
  • 事後作業
    • 振り返り
    • 各種ドキュメントへの反映

ノーメンテでの統合方法の検討

要件として、ある程度ダウンタイムを減らす必要があった。

このため、統合予定の稼働中の RDS クラスタ間で バイナリログ レプリケーションをしておいて、統合時に新しいクラスタに切り替える方法を検討した。

また、アプリケーションサーバと RDS クラスタ間に AWS RDS Proxy を挟んでおくことで、アプリケーションサーバからの向き先は変更ることなく統合する方法をとった。

検証した結果、2,3分のダウンタイムで切り替えることが出来ることがわかった。

※ 切替時に手作業があったため2,3分になっているが、作業を自動化することでさらにダウンタイムを短縮できそうではあった。今回は2,3分のダウンタイムを許容できたので、そこまでの自動化は行わなかった。

切り替えイメージはこちら

ノーメンテでの統合方法のイメージ

なお、この記事では次のように呼ぶことにする

  • 統合して無くなる方を ソースDB (レプリケーションのマスターになる)
  • 統合して残る方を ターゲットDB (レプリケーションのスレーブになる)

影響範囲の洗い出し

RDS クラスターが統合されることによる影響範囲を洗い出した。 以下が影響した。

  • GitHub Actions, AWS Lambda など

    接続先を統合後のクラスターに変更する必要がある

  • データ集計プログラム

    接続先を統合後のクラスターに変更する必要がある

  • 監視

    統合後のクラスターのみ監視するように変更する必要がある

手順の確立

手順は以下のようになった。

  1. 準備

    1. ソース DB と ターゲット DB 間で、バイナリログ設定を有効化

    2. ターゲット DB にアプリケーションサーバが使う MySQL ユーザを作成

    3. RDS Proxy を作成

      向き先は ソース DB

    4. ソース DB のクローンを作成

      ※ クローンして作成された RDSクラスタ のイベントログにバイナリログのポジションが表示されるのでメモしておく

    5. クローンしてできた DB からデータをダンプする

    6. ターゲット DB にデータをインポート

    7. ソース DB をマスター、ターゲット DB をスレーブとして、バイナリログレプリケーションを設定

      ※ このときに前の手順でメモしておいたバイナリログのポジションを使う

    8. 問題なくレプリケーションができていることを確認

    9. アプリケーションサーバの接続先を RDS Proxy に変更

    INFO

    なお、通常のバイナリログ レプリケーションでは、ターゲット DB の書き込みは禁止しておくほうが安全であるが、今回はターゲット DB も利用されているため、書き込みを禁止しなかった。

    MySQL スキーマ(データベース)毎に、MySQL ユーザを分けておいて、MySQL ユーザの権限を落とすことで、書き込みを禁止する方法もあった。

  2. 統合作業

    1. ソース DB の書き込み停止

      パラメータグループで read_only1 に変更

      ソース DB でread_only が ONになっていることを以下のコマンドで確認

      sql
      mysql> show global variables like 'read_only';
      
      +---------------+-------+
      | Variable_name | Value |
      +---------------+-------+
      | read_only     | ON    |
      +---------------+-------+
      
    2. レプリケーションが完了していることを確認

      以下のようにして、レプリケーションのポジションが一致していることを確認する

      • ソース DB のレプリケーションのポジションを確認

        sql
        mysql> show master status;
        
        +----------------------------+-----------+--------------+------------------+-------------------+
        | File                       | Position  | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
        +----------------------------+-----------+--------------+------------------+-------------------+
        | mysql-bin-changelog.000001 | 123456789 |              |                  |                   |
        +----------------------------+-----------+--------------+------------------+-------------------+
        
      • ターゲット DB のレプリケーションのポジションを確認

        sql
        mysql> show slave status\G
        
            ...
            Master_Log_File: mysql-bin-changelog.000001
        Read_Master_Log_Pos: 109156484
            ...
        
    3. ターゲット DB でレプリケーションを停止

      sql
      mysql> stop slave;
      

      レプリケーション設定を削除

      sql
      mysql> call mysql.rds_reset_external_master;
      
    4. RDS Proxy の向き先をターゲット DB に変更

      これで、ターゲット DB に向けてアプリケーションが動き始める

  3. 事後作業

    1. ソース DB の削除
    2. アプリケーションサーバの接続先を RDS Proxy から ターゲットDBに向ける
    3. RDS Proxy の削除
    4. その他、洗い出しておいて影響範囲の修正

上記の作業を、全ての RDS クラスタに対して行う。

INFO

Aurora MySQL v2 (MySQL 5.7 互換) では、マルチソースレプリケーションがサポートされていないため、一度に複数の RDS クラスタを統合することはできなかった。

試験

  • 負荷試験

    統合後のクラスターに向けて負荷試験を実施し、パフォーマンスが要件を満たすことを確認した。

  • アプリケーションサーバの動作確認

    統合後のクラスターに向けてアプリケーションの e2e テストを実施して、アプリケーションが正常に動作することを確認した。

実施

統合作業のスケジュールを作成し、SaaS 利用ユーザへのメンテナンスの告知を行った。

切り替えは深夜帯に行った。

振り返り

  • 本番・開発環境を含めて 50 クラスタあったものを大幅に減らすことができ、インフラ費用と保守コストを大きく削減できた

  • だいたい 8ヶ月くらいはかかった

    • 2023年1,2月 : 統合手順の調査・検証
    • 2024年3月 : 事前準備(MySQL ユーザの整理など)
    • 2024年4月 : (4月は別プロジェクトで忙しくて何もできなかった)
    • 2024年5,6月 : パフォーマンス検証、動作検証
    • 2024年7月 : テスト環境の統合実施
    • 2024年8,9月 : 本番環境の統合実施

    ※ 統合プロジェクト以外にも色々やっていたので、統合プロジェクトにかけた時間は実際にはもう少し短い。

Released under the MIT License.