← ハンズオン一覧に戻る

AWS Hands-on / Database

データベースの片方が落ちても、止めない

RDS の「Multi-AZ配置」で、別のアベイラビリティーゾーンに待機系のデータベースを持たせます。手動でフェイルオーバーを起こし、接続先のエンドポイントが裏側で切り替わる間、何が起きるかを実際に確かめます。

● Lv.4 設計や運用を意識できる人 ⏱ 所要 50〜70 分 コンソールのみで完結(接続確認はコマンドライン)
01 — Prerequisites

はじめる前に

  • 必須AWS アカウントを持っていること
  • 必須マネジメントコンソールにサインインできること
  • 必須RDS で DB インスタンスを作成した経験があること
  • 必須基本的な SQL の実行経験があること
  • あると良い「可用性」「単一障害点」という言葉のイメージがある

※ コンソール操作に加えて、接続状況を確認するために、お使いのパソコンのターミナルから簡単なコマンドを実行します(EC2 や SSH は使いません。RDS をパブリックアクセス可能にして、ローカルから直接確認します)。

02 — References

参照する公式ドキュメント

手順に迷ったときや、用語の意味を確かめたいときに開きましょう。

※ リンク切れの場合は、ページタイトルで検索してください。

03 — Background

背景・シナリオ

データベースを 1 台だけで運用していると、そのサーバーに障害が起きたときにサービス全体が止まってしまいます。データベースは多くのシステムで唯一の正となるデータを持つ場所であり、ここが止まると他のサーバーが正常でもサービスは機能しません。

Amazon RDS のMulti-AZ 配置を使うと、別のアベイラビリティーゾーンに待機系(スタンバイ)のデータベースを自動的に複製しておき、メイン(プライマリ)に障害が起きると待機系に自動的に切り替わります。今回はこの切り替え(フェイルオーバー)を手動で起こし、何が起きるかを実際の目で確認します。

待機系のデータベースは、普段は何をしているの?

普段はプライマリからのデータを受け取って複製を保持するだけで、通常の読み書きには使われません(読み取り専用として活用できるリードレプリカとは役割が異なります)。フェイルオーバーが起きたときに初めて、本番の役割を引き継ぎます。

フェイルオーバーが起きても、接続先のアドレスを変更する必要はないの?

ありません。RDS はエンドポイント(接続先のアドレス)を変えずに、裏側で実体(プライマリ/スタンバイ)の役割だけを切り替えます。アプリケーション側は同じエンドポイントに接続し続けるだけで、自動的に新しいプライマリにつながります。

Goal

Multi-AZ 配置の RDS for MySQL インスタンスを作成し、手動でフェイルオーバーを起こす。フェイルオーバーの前後で接続を試行し続け、一時的に接続できなくなる時間(ダウンタイム)と、その後自動的に再接続できることを確認する。

04 — Architecture

つくる構成

DB インスタンスの作成画面で、可用性に関する設定を選びます。今回は待機系を持つ構成を選び、自動フェイルオーバーに対応できる状態にします。

データベースの作成 — 可用性とその他の耐久性の設定(イメージ)

DB インスタンスの可用性

マルチAZ DBインスタンス
スタンバイインスタンスを他のAZに作成し、自動フェイルオーバーに対応
シングルAZ DBインスタンス
スタンバイなし。障害時は手動の復旧が必要

可用性を確保するためマルチAZを選びます

05 — Requirements

要件

以下の要件を満たす構成を作り、フェイルオーバー前後の接続状況を確認してください。

No要件
1リージョンは「東京(ap-northeast-1)」を使用する。
2Multi-AZ 配置を有効にした RDS for MySQL インスタンスを 1 つ作成する。パブリックアクセスは「あり」にして、ローカルから直接接続できるようにする。セキュリティグループのインバウンドはマイ IP のみ許可する。
3ローカルのターミナルから、一定間隔で接続を試行するループ処理(例:1 秒ごとに SELECT 1 を実行し、結果と時刻を表示する)を用意する。
4ループ処理を実行したまま、コンソールから「再起動」の際に「フェイルオーバーで再起動する」を選び、フェイルオーバーを発生させる。
5ループ処理の出力から、接続が一時的に途切れた時間と、再接続後も同じエンドポイントで通信が続いていることを確認する。
06 — Steps

構築の進め方

「Multi-AZ で DB インスタンスを作る → ローカルから接続を確認する → フェイルオーバーを起こす → 切り替わりの様子を見る」という順番で進みます。

  1. マネジメントコンソールにサインインし、リージョンを合わせる

    ブラウザで AWS マネジメントコンソールにサインインし、画面右上のリージョンが「アジアパシフィック(東京)ap-northeast-1」になっていることを確認します。

  2. RDS の「データベースの作成」で、マルチAZ DBインスタンスを選ぶ

    RDS コンソールの「データベースの作成」を開き、エンジンの種類で「MySQL」を選びます。可用性とその他の耐久性の設定で、「マルチAZ DBインスタンス」を選びます。

    データベースの作成 — 可用性の設定(イメージ)

    DB インスタンスの可用性

    マルチAZ DBインスタンス
    スタンバイインスタンスを他のAZに作成し、自動フェイルオーバーに対応
    シングルAZ DBインスタンス
    スタンバイなし。障害時は手動の復旧が必要

    可用性を確保するためマルチAZを選びます

    DB インスタンス識別子自由に決める(例:multi-az-handson-db
    マスターユーザー名・パスワード自由に決める(パスワードは控えておく)
    パブリックアクセスあり
    VPC セキュリティグループ新規作成し、インバウンドで MySQL/Aurora(3306)をマイ IP のみから許可
    なぜパブリックアクセスを「あり」にするの?

    今回はローカルのパソコンから直接接続して、フェイルオーバー前後の通信を観察するためです。インバウンドをマイ IP のみに絞ることで、他の場所からはアクセスできないようにしています。

  3. DB インスタンスの作成が完了するまで待つ

    作成には数分から十数分かかります。DB インスタンスの一覧でステータスが「利用可能」になるまで待ちます。

  4. ローカルのターミナルから、接続を繰り返すループ処理を用意する

    mysql クライアントがインストール済みのターミナルで、一定間隔で接続・簡単なクエリを実行し続けるループ処理を用意します。エンドポイントは DB インスタンスの詳細画面で確認できます。

    接続ループ(シェルスクリプトの例)
    #!/bin/bash
    ENDPOINT=# 例:multi-az-handson-db.xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
    while true; do
      RESULT=$(mysql -h "$ENDPOINT" -u ユーザー名 -pパスワード -e "SELECT NOW();" 2>&1)
      echo "$(date '+%H:%M:%S') -- $RESULT"
      sleep 1
    done
    間隔は短めに

    1 秒程度の短い間隔にしておくと、フェイルオーバー中の短いダウンタイムも見逃さずに記録できます。パスワードを直接書きたくない場合は、実行時にプロンプトで入力する形に変えても構いません。

  5. ループ処理を実行したまま、RDS コンソールを開く

    手順 4 のスクリプトを実行したまま、別のターミナルまたはブラウザのタブで RDS コンソールを開きます。出力が 1 秒ごとに増え続けていることを確認してから、次に進みます。

  6. 「フェイルオーバーで再起動する」を選んで実行する

    対象の DB インスタンスを選び、「再起動」を開きます。確認ダイアログの中にある「フェイルオーバーで再起動する」のオプションを明示的に選んでから実行します。

    通常の再起動とは違う

    このオプションを選ばずに再起動すると、同じアベイラビリティーゾーンのまま再起動されてしまい、フェイルオーバーは発生しません。プライマリとスタンバイの役割を切り替えるには、必ずこのオプションを選びます。

  7. ループ処理の出力と、アベイラビリティーゾーンの表示を確認する

    ターミナルの出力を見ると、ある時点から数回〜数十回ぶんの接続が失敗し、その後また成功に戻る様子が見えます。失敗の前後で、表示されているホスト(エンドポイント)の文字列自体は変わっていないことも確認しましょう。RDS コンソールの DB インスタンスの詳細画面でも、アベイラビリティーゾーンの表示が、フェイルオーバー前と変わっていることを確認します。

07 — Pitfalls

つまずきポイント

初学者がよく引っかかる箇所を先回りでまとめました。答えそのものは載せていませんが、「どこを見直せばよいか」の手がかりとして使ってください。

Pitfall 01 — ダウンタイムが分かりにくい

「フェイルオーバーをしても、接続が途切れたのかよく分からない」

ループ処理の間隔が長すぎると、短い切断時間を見逃しやすくなります。1 秒程度の短い間隔にしておき、出力をスクロールして見比べれば、失敗が連続している区間を見つけやすくなります。

Pitfall 02 — 通常の再起動になってしまう

「再起動を選んだのに、フェイルオーバーが起きない」

確認ダイアログの中にある「フェイルオーバーで再起動する」のチェックボックス(またはオプション)を、明示的に選ぶ必要があります。選び忘れると、プライマリとスタンバイの役割は切り替わらず、同じ場所での再起動になります。

08 — Checklist

完了チェック

要件の再確認ではなく、画面のどこを見れば達成を確認できるかをまとめました。RDS コンソールとターミナルの出力を見て、次を順に確かめましょう。

  • DB インスタンスの設定で「マルチAZ」が有効になっている。
  • フェイルオーバー実行後に、DB インスタンスの詳細画面でアベイラビリティーゾーンの表示が変わっている。
  • ループ処理のログに、接続失敗の区間が記録されている。
  • 失敗区間の前後で、エンドポイントのアドレス自体は変わっていない
  • フェイルオーバー後も、追加のクエリが正常に実行できる。
09 — Think

考えてみよう

手を動かすことに加えて、次の問いに自分の言葉で答えられるようにしておくと、理解がより深まります。

  1. フェイルオーバー中の数十秒のダウンタイムは、サービスのどんな使われ方であれば許容でき、どんな使われ方であれば問題になりそうでしょうか。
    ヒント
    バッチ処理のように多少の遅延が許される使われ方と、決済や予約のように一瞬の応答が常に求められる使われ方を比べてみましょう。利用者がそのとき何をしようとしているか、という観点で考えると違いが見えてきます。
  2. シングルAZ構成で同じ障害(プライマリの停止)が起きた場合、復旧までにどんな作業が必要になりそうでしょうか。
    ヒント
    待機系が存在しないため、自動的に切り替わる先がありません。誰かが障害に気づき、バックアップやスナップショットから新しいインスタンスを作り直す、といった人手を介した復旧作業が必要になる場面を想像してみましょう。
  3. Multi-AZ配置はコストが上がりますが、それでも採用する判断はどんな基準でされそうでしょうか。
    ヒント
    サービスが止まった場合の損失(売上・信頼・対応の手間)と、追加でかかる料金とを比べる考え方があります。止まった場合の影響が大きいシステムほど、追加コストを払って可用性を確保する判断がされやすい、という観点で考えてみましょう。
10 — Clean up

後片づけ

確認が終わったら、次の順で後片づけをしましょう。

  1. ループ処理を停止する:ターミナルで実行しているスクリプトを Ctrl + C などで停止します。
  2. RDS インスタンスを削除する:RDS コンソールで対象の DB インスタンスを選び、削除します。削除時には最終スナップショットを作成するかどうかを選べます。今回の検証用データを残す必要がなければ作成不要を選んでも構いませんが、迷う場合は作成しておくと安心です。
  3. セキュリティグループを削除する:DB インスタンスの削除が完了したあと、手順 2 で新規作成したセキュリティグループを削除します。
Caution — 他で使っているリソースは消さない

削除するのは、このハンズオンで自分が作ったものだけ

セキュリティグループや DB インスタンスの一覧には、すでに使っている他のリソースが並んでいるかもしれません。間違えて削除しないよう、このハンズオンのために作成したものだけを選んで削除してください。デフォルト VPC やデフォルトのサブネットは消さないようにしましょう。

コストに関する注意: Multi-AZ 配置の RDS インスタンスは、待機系(スタンバイ)の分の課金が加わるため、シングルAZ構成と比べて約 2 倍の料金になります。検証が終わったら速やかに削除することをおすすめします。最終スナップショットを作成した場合は、スナップショットの保管にも料金がかかります。VPC セキュリティグループ自体には料金はかかりません。最新の料金は AWS の公式料金ページで確認してください。