1706016490
2024-01-23 11:41:25
英国政府通知 でホストされています GOV.UK サービスとしてのプラットフォーム (PaaS)。 PaaS は廃止されるため、すべてのインフラストラクチャを独自のアマゾン ウェブ サービス (AWS) アカウントに移行しています。 このブログ投稿では、どのように移行したかについて説明します。 PostgreSQL ダウンタイムを最小限に抑えたデータベース。

データベースの移行
PaaS はデータベースを提供しており、送信する各通知に関するデータから、サービス チームが通知の送信に使用する何十万ものテンプレートの内容に至るまで、すべてのデータを保存するためにそれを使用します。 これは AWS RDS PostgreSQL データベースは PaaS の AWS アカウントに存在します。 PaaS で実行されるアプリはこのデータベースと通信します。 このデータベースを「ソース データベース」と呼びます。
私たちは独自の AWS アカウントに新しいデータベースをセットアップし、すべてのアプリが新しいデータベースと通信できるようにする必要がありました。 この新しいデータベースを「ターゲット データベース」と呼びます。
私たち自身の AWS アカウントに新しい PostgreSQL データベースを作成することは、それほど難しいことではありません。 難しい部分は、ダウンタイムを最小限に抑えながら、すべてのデータを転送し、アプリでこの新しいデータベースを使用できるようにすることです。
ソースデータベースについてもう少し詳しく
ソース データベースのサイズは約 400 GB です。 約 13 億の行、85 のテーブル、185 のインデックス、および 120 の外部キーがあります。 PostgreSQL バージョン 11 です。
通常の平日では、1 秒あたり 1,000 件程度の挿入または更新 (場合によってはそれよりも少ない場合もあれば、はるかに多い場合もあります) に加えて、同様の数の読み取りが行われます。
GOV.UK Notify は、洪水警報からパスポート申請に関するユーザーの更新まで、毎日何百万もの重要なタイムリーな通知を送信します。 私たちが送信するすべての通知には、データベースとの通信が必要です。 したがって、ダウンタイムを最小限に抑えることが重要です。
AWS データベース移行サービス
PaaS チームは、次を使用してデータベースを移行できる機能を提供してくれました。 AWS データベース移行サービス (DMS)。
DMS は、ソース データベースからターゲット データベースへのデータの転送を担当します。 ソースまたはターゲットの AWS アカウントで実行できます。
DMS は次のように動作します。
- 特定の時点までのすべてのデータをテーブルごとにコピーします。 これは「全ロード」タスクとして知られています。
- レプリケーション モードに入り、ソース データベース上のすべての新しいトランザクションがターゲット データベースで再生され、2 つのデータベースが同期されます。
次に、アプリがソース データベースとの通信を停止し、ターゲット データベースとの通信を開始するようにする責任があります。
データベース移行プロセス
データベースの移行プロセスはいくつかの段階を経て完了しました。
DMS インスタンスのセットアップ
この例では、DMS インスタンスはソース AWS アカウントに作成されました。 私たちがソース アカウントを選択したのは、PaaS チームがすでにアカウントに DMS のインスタンスをセットアップしていたため、これを迅速かつ簡単に行うことができたからです。
DMS インスタンスには、ソース データベースとターゲット データベースの両方と通信するための PostgreSQL 資格情報を与える必要もありました。
DMS インスタンスとターゲット データベースは、異なる Virtual Private Cloud (VPC) 内に存在します。 PaaS チームの協力を得て、 VPC ピアリング これにより、PaaS の VPC 内の DMS インスタンスからのトラフィックを、パブリック インターネットを経由せずに VPC に直接ルーティングできるようになります。
ターゲットデータベースのセットアップ
ターゲットの RDS インスタンスを独自の AWS アカウントに作成しました。 PostgreSQL バージョン 11 がサポートされなくなる予定だったので、この機会に新しいデータベースを PostgreSQL 15 にして PostgreSQL バージョンをアップグレードしました。
次に、「pg_dump」を使用してソース データベースのデータベース スキーマのダンプを取得しました。 これにより、データベース スキーマを再作成するための SQL コマンドを含むファイルが得られました。
データベース スキーマからテーブルの宣言を取得し、それらをターゲット データベースに適用しました。
DMS の完全ロード プロセスでは、外部キーの制約に一致する順序でデータ全体をコピーしようとしないため、この時点では外部キーを適用しませんでした。
全読み込みタスクの速度が大幅に低下するため、この時点では主キーまたはインデックスを作成しませんでした。 個々の挿入にはさらに時間がかかります。 インデックスを更新する必要があり、数十億行を挿入する場合、膨大な時間がかかります。 最初にすべてのデータをコピーし、その後インデックスを追加する方がはるかに高速でした。
全負荷
テーブルを作成したターゲット データベースを作成したら、DMS の全ロード タスクを開始しました。 これにより、「フルロード開始」ボタンを押したときに存在していたすべてのデータがコピーされます。 この時点以降に受信される新しいデータや更新はコピーされません。 全負荷タスクが完了するまでに約 6 時間かかりました。
全ロード タスクが完了した後、インデックスとキー制約を追加するソース データベース スキーマ ファイルの残りの部分を適用しました。 これらの追加には約 3 時間かかりました。
レプリケーション
全ロード タスクが完了すると、ターゲット データベースのデータは、全ロード タスクを開始した時点でのソース データベースのデータと一致しました。 しかし、それ以来、ソース データベースで多くの新しい挿入、更新、削除が発生しました。 そして、さらに多くの変化も今後も起こり続けるでしょう。
これらの新しい変更をコピーするために、DMS の進行中のレプリケーション (変更データ キャプチャとも呼ばれる) タスクを開始しました。 これにより、ソース データベースからすべてのトランザクションが読み取られます。 トランザクションログ これらは完全ロード タスクの開始後に作成され、ターゲット データベースに送信されます。 これにより、ターゲット データベースがソース データベースと、最大でもわずかな遅れで同期することが保証されます。
レプリケーション プロセスが追いつくまでに数時間しかかかりませんでした。 その時点で、DMS レプリケーション プロセスの遅延を監視して、ソース データベースに発生する変更の数を処理できること、および同期を維持できることを確認しました。
DMS レプリケーション プロセスをバックグラウンドで約 10 日間実行し、アプリがソース データベースとの通信を停止し、ターゲット データベースとの通信を開始するまでの間、すべての同期を保ちました。 今回はユーザーに事前に通知していたので、トラフィックの移行時間はすでに設定されていました。
トラフィックの移行の準備
数か月前、私たちはアプリがソース データベースと通信するのを停止し、ターゲット データベースを使用できるようにする方法を計画しました。これが、私たちが使用したプロセスです。
- アプリからソース データベースへのすべてのトラフィックを停止します。 この時点で、Notify が利用できないダウンタイム期間に入ります。
- レプリケーションが追いついて、ソース データベースに対するすべての更新がターゲット データベースに反映されていることを確認します。
- アプリがターゲット データベースと通信できるようにします。 これでダウンタイムは終了します。
一部のアプリがソース データベースと通信し、残りのアプリが同時にターゲット データベースと通信しないようにすることが重要でした。 これが発生した場合、ターゲット データベースでの変更はソース データベースに反映されず、ユーザーは一貫性のないデータを取得することになります。
このプロセス用の Python スクリプトを作成したので、明示的で簡単に繰り返し可能で、手動で行うよりもはるかに迅速に行うことができます。 迅速に実行できればできるほど、Notify ユーザーのダウンタイムは短くなります。 私たちの目標は、ダウンタイムを 5 分未満にすることでした。 事前のさまざまなテストと練習中に、このスクリプトを少なくとも 40 回使用することになりました。
移行のために土曜日の夜を選びました。 これは、私たちがそれほど注意力を持たない真夜中に起きている必要がなく、最も静かな時間の1つであるためです。
ソースデータベースへのトラフィックを停止します
私たちのスクリプトは、アプリからのすべての接続で `pg_terminate_backend` を呼び出すことで、ソース データベースへのすべてのトラフィックを停止します。 これには 1 秒もかかりませんでした。 また、アプリで使用される PostgreSQL ユーザーのパスワードも変更しました。これは、アプリがソース データベースに再接続しようとすると、認証エラーが発生することを意味します。
レプリケーションが追いついたことを確認しています
DMS は、レプリケーションのステータスに関するいくつかの有用なテーブルをターゲット データベースに挿入し、毎分更新します。 これらのテーブルを使用すると、ターゲット データベースとソース データベースの間にどの程度の遅れがあるかを確認できます。 移行スクリプトはこれらのテーブルをチェックして、ターゲット データベースが完全に追い込まれていることを確認します。
さらに安全を確保するために、アプリがソース データベースとの通信を停止した後、移行スクリプトは単一のレコードをソース データベースに書き込み、それがターゲット データベースに安全に到着するまで待機します。 これにより、すべての変更が複製されたという確信がさらに高まりました。
トラフィックのスムーズな交換を実現する
アプリがデータベースに接続するには、データベースの場所と、関連する PostgreSQL ユーザーのユーザー名とパスワードを知る必要があります。 これらは、次の形式の環境変数でアプリに提供されます。
SQLALCHEMY_DATABASE_URI = postgresql://original-username:[email protected]:5432
アプリを別のデータベースに接続したい場合は、URI 内のユーザー名、パスワード、場所を更新し、アプリを再デプロイして、この変更を有効にする必要があります。 アプリの再デプロイには約 5 分かかります。 移行スクリプトの一部としてアプリを再デプロイすると、さらに 5 分間のダウンタイムが発生することになります。 ダウンタイムを最小限に抑えるために、アプリを再デプロイする代わりにドメイン ネーム システム (DNS) を簡単に変更できるように、移行前に 2 つの変更を加えました。
最初の変更は、ソース データベースとターゲット データベースの両方に、同じユーザー名とパスワードを持つユーザーを作成することでした。 これは、移行中にアプリに提供されたユーザー名やパスワードを変更する必要がないことを意味します。
2 番目の変更は、DNS レコードを作成することでした。 AWS ルート 53 「database.notifications.service.gov.uk」の場合、TTL (存続時間) は 1 秒です。 重み付けを含む 2 つのレコードがありました。
- DNS 結果の 100% がソース データベースの場所に重み付けされました
- DNS 結果の 0% がターゲット データベースの場所に重み付けされました
新しいユーザー名とパスワードを使用し、データベースの場所に新しいドメイン名を使用するように、アプリで使用される URI を設定します。
SQLALCHEMY_DATABASE_URI = postgresql://shared-username:[email protected]:5432
ここで、アプリが指すデータベースを交換したい場合、移行スクリプトは AWS の DNS 重み付けをターゲット データベースの場所に送信される結果の 100% に更新し、TTL が期限切れになるまで 1 秒待つだけで済みました。 。 その後、アプリが次にデータベースにクエリを実行しようとするときに、ターゲット データベースにクエリを実行することになります。
その日何が起こったのか
11 月 4 日土曜日の夜に集まったとき、私たちはターゲット データベースをセットアップし、全ロード プロセスが実行され、新しいトランザクションがコピーされていました。 確認したところ、ターゲット データベースとソース データベースの間には数秒の遅れしかありませんでした。
その後、移行スクリプトが正常に実行されたため、アプリはソース データベースとの通信を停止し、新しいターゲット データベースとの通信を開始しました。 移行中に、約 11 秒の短いダウンタイムが発生しました。 これは目標の 5 分をはるかに下回っていたので、私たちだけでなくユーザーも非常に満足しました。
私たちが学んだこと
DMS を使用することを選択したのは、GOV.UK PaaS によって十分にサポートされており、AWS からもサポートを受けることができたからです。 将来、PostgreSQL から PostgreSQL データベースへの移行を行う場合は、次のような代替ツールを試すことにもっと時間を費やすでしょう。 言語学的。 DMS は、他のツールで見つかったものよりもさらに複雑になり、馴染みのないレプリケーション プロセスを追加する可能性があります。 これはバックアップします PostgreSQL から PostgreSQL への移行について AWS が自ら述べていること。
GOV.UK Notify の AWS への移行の次のステップ
これでデータベースの移行が完了しました。次のステップはアプリを移行することです。 こっそり – AWS Elastic Container Service (ECS) に移行中です。 これがどうなるかについては、今後数か月間ブログでお知らせする予定です。
#秒のダウンタイムで #PostgreSQL #データベースを移行した方法