アプリケーションサーバーで Amazon Aurora クラスターエンドポイント/ライターエンドポイントを使用していますが、アプリケーションがリーダーインスタンスに接続してしまいます。
簡単な説明
Aurora クラスターエンドポイントまたはライターエンドポイントに接続する際、アプリケーションが代わりにリーダーインスタンスに接続することがあります。これは、エンドポイントとそのマッピングされた IP アドレスがクライアントアプリケーション側でキャッシュされている場合に発生します。
Aurora クラスターのエンドポイントは常に Aurora ライターインスタンスを指します。フェイルオーバーが発生すると、Aurora クラスターエンドポイントは新しいライターインスタンスを指します。クラスターエンドポイントを使用している場合、フェイルオーバー中に読み取り/書き込み接続は自動的に Aurora レプリカにリダイレクトされます。このレプリカインスタンスはプライマリインスタンスに昇格します。
そのため、フェイルオーバー中に Aurora インスタンスの基になる IP アドレスが変更され、キャッシュされた値が使用できなくなる可能性があります。
DNS 名を使用してデータベースに接続しようとするクライアントは、DNS サーバーにクエリを実行して、DNS 名を IP アドレスに変える必要があります。そうすると、クライアントは応答をキャッシュします。DNS レスポンスは、プロトコルごとに、クライアントがレコードをキャッシュする時間を定める有効期限 (TTL) を指定します。Aurora DNS ゾーンは 5 秒という短い TTL を使用します。しかし、多くのシステムでは、さまざまな設定でクライアントキャッシュを実装しているため、TTL が長くなる可能性があります。
DNS レコードの変更が反映されていないときにクライアントがクラスターに接続しようとすると、クライアントは古いアドレスを受け取ります。これにより、クライアントは以前のプライマリインスタンス(現在のリーダーインスタンス)に接続します。
そのため、DNS データを長時間キャッシュすると、接続障害が発生する可能性があります。
フェイルオーバーが開始すると、クライアントはデータベースから TCP トラフィックを取得できなくなります。その代わり、タイムアウトはクライアント次第となります。このように、フェイルオーバー時に元のプライマリデータベースをハードフェンシングするということは、計画的なフェイルオーバーと予期しないフェイルオーバーの際にクライアントに同様の動作が発生することを意味します。
解決方法
接続しているのがライターインスタンスか Aurora レプリカかを確認してください。
クライアントがライターインスタンスに接続しているのか、Aurora レプリカに接続しているのかを判断するには、@@innodb_read_only 変数を使用します。
mysql> select @@innodb_read_only;
値が 0 の場合は、ライターインスタンスに接続していることを意味します。
次のクエリを実行して、接続しているサーバーと、そのサーバーがライターかリーダーかを判断します。
mysql> select concat("You are connected to '",server_id,"', which is a ",if(SESSION_ID='MASTER_SESSION_ID',"Writer","Reader")) as CONNECTION_STATUS from information_schema.replica_host_status where SERVER_ID in (select @@aurora_server_id);
+-----------------------------------------------------------------+
| CONNECTION_STATUS |
+-----------------------------------------------------------------+
| You are connected to 'aurora-test-instance1', which is a Writer |
+-----------------------------------------------------------------+
1 row in set (0.08 sec)
クラスター内の複数のリーダーインスタンスのトラブルシューティング
Aurora リーダーエンドポイントは DNS CNAME エントリです。クラスターに複数のリーダーインスタンスがある場合、リーダーエンドポイントを解決すると、ラウンドロビン方式で選択されたインスタンス IP が取得されます。これは、リーダーエンドポイントにすべての Aurora レプリカが含まれ、新しい接続に対し DNS ベースのラウンドロビン負荷分散を提供するからです。
解決のたびに異なるインスタンス IP を取得するには、DNS をキャッシュせずにエンドポイントを解決し続ける必要があります。エンドポイントを 1 度だけ解決してプールで接続を保持すると、その接続でのすべてのクエリは同じインスタンスに送信されます。DNS をキャッシュする場合、エンドポイントを解決するたびに同じインスタンス IP を取得します。
ベストプラクティスに従う
- ネットワークとクライアントの設定で DNS キャッシュの TTL を長くしないようにしてください。接続プールやその他の多重化を使用する場合、キャッシュされた DNS 情報をフラッシュするか、有効期間の短縮が必要になる可能性があります。クライアントアプリケーションが DB インスタンスの DNS データをキャッシュしている場合は、TTL 値を 30 秒未満に設定します。
- Amazon Relational Database Service (Amazon RDS) プロキシを使用して接続を管理します。詳細については、「Amazon RDS Proxy を使用する」 を参照してください。
- スマートドライバーの使用 に関するベストプラクティスを確認してください。
- エラスティックロードバランシングや HA/Proxy などの TCP ベースのロードバランサーを使用してください。
関連情報
Aurora エンドポイントの種類
DNS キャッシュ
Amazon Aurora DB クラスターがフェイルオーバーした後で、読み取り専用エラーが発生するのはなぜですか?