設定のガイドライン
このセクションでは、RDS Proxy で使用できる設定について説明し、アプリケーションスタック全体で設定を調整するためのベストプラクティスを提供します。これらは、Amazon RDS と Amazon Aurora で RDS Proxy を使用するためのガイドラインをまとめたものです。RDS 固有および Aurora 固有の注意事項は、該当する場合に明記されています。
特に明記されていない限り、「データベース」または「ターゲット」という用語は、Aurora クラスター、Amazon RDS マルチ AZ DB クラスター、または Amazon RDS インスタンスを指します。
RDS Proxy の設定
MaxConnectionsPercent
| 最小値 | 最大値 | デフォルトの値 |
|---|---|---|
| (1、MaxIdleConnectionsPercent) のうち小さい方 | 100 | 100 |
詳細については、「MaxConnectionsPercent」を参照してください。
この設定では、RDS Proxy がターゲットデータベースと確立できる接続の数を、データベースで許可される最大接続数に対する割合で制限します。プロキシは必要に応じてバックエンド接続を開くため、任意の時点での実際の接続数が設定された最大数を下回る可能性があります。
MaxConnectionsPercent 設定がデータベース接続制限の割合である場合、プロキシの接続プールのサイズは自動的にデータベース設定に従います。つまり、データベースインスタンスのサイズを変更したり、設定を変更したりするたびに、プロキシを再設定する必要はありません。また、暗黙的か明示的かにかかわらず、データベース設定が変更される可能性があるシナリオに注意する必要があります。
-
データベースのパラメータグループで接続制限 (
max_connectionsパラメータなど) を明示的に設定しなかった場合、Amazon RDS と Aurora はデータベースインスタンスクラスに基づいて自動的に計算します。その結果、データベースインスタンスをスケールするときに暗黙的な接続制限が変更され、プロキシの最大プールサイズに影響する可能性があります。詳細については、「Amazon RDS ユーザーガイド」の「データベース接続の最大数」、「Aurora MySQL DB インスタンスへの最大接続数」、および「Amazon Aurora ユーザーガイド」の「Aurora PostgreSQL DB インスタンスへの最大接続数」を参照してください。 -
Aurora Serverless v2 データベースインスタンスは、データベースの最大 ACU 設定に基づいて接続制限を決定します。詳細については、「Amazon Aurora ユーザーガイド」の「Aurora Serverless v2 の最大接続数」を参照してください。
ベストプラクティス:
-
デフォルト設定の 100% は、プロキシを介してすべてのトラフィックを受信し、管理アクセスやその他のクライアントにヘッドルームを必要としないデータベースに適しています。
-
データベースがアプリケーションから直接 (プロキシをバイパスして) トラフィックを受信し、プロキシがすべての接続を消費しないようにする場合、またはデータベース管理者による直接アクセスなど、他の目的で特定の数の接続を確保したい場合は、この設定を減らします。
-
Aurora Global Database クラスターで RDS Proxy を使用し、書き込み転送が有効になっている場合は、書き込み転送に割り当てられたクォータ分だけプロキシの
MaxConnectionsPercent値を減らします。詳細については、「Amazon Aurora ユーザーガイド」の Aurora MySQL および Aurora PostgreSQL での書き込み転送の設定パラメータを参照してください。この推奨事項は、プロキシがグローバルデータベースのプライマリリージョンまたはセカンダリリージョンのいずれのクラスターを提供している場合でも適用されます。セカンダリクラスターはプライマリの役割に昇格できるため、グローバルトポロジ全体でプロキシ設定の一貫性を保つことをお勧めします。プライマリリージョンとセカンダリリージョンに対応するプロキシには非対称設定を使用できますが、グローバルフェイルオーバーまたはスイッチオーバーのたびにこれらの設定を調整する必要があります。 -
ターゲットが複数のプロキシを提供する場合、データベースがオーバーサブスクライブされないように、これらのプロキシ全体の
MaxConnectionsPercentの合計値は 100 を超えることはできません。設定と管理を簡素化するために、ターゲットごとに 1 つのプロキシを使用することをお勧めします。特に、冗長性のためにデータベースごとに複数のプロキシを使用する必要はありません。詳細については、「1 つのターゲットに対して複数のプロキシを使用する」を参照してください。
デフォルトの MaxConnectionsPercent 設定とカスタム値のどちらを使用している場合でも、ピーク時に許可される接続数と予想されるクライアント接続の最大数の間に少なくとも 30% の余裕を確保してください。例えば、次のようになります。
-
プロキシがデータベース用に設定された接続制限の最大 50% を必要とすると思われる場合は、
MaxConnectionsPercentの設定を少なくとも1.3 * 50% = 65%に設定します。 -
デフォルトの
MaxConnectionsPercent設定の 100 を使用する場合は、データベースの制限自体に十分なヘッドルームがあることを確認してください。
この追加ヘッドルームにより、予期しないワークロードの急増時にもクライアントエクスペリエンスが向上し、RDS Proxy が内部インフラストラクチャ全体に接続を再分散して、熱管理やその他の目的に役立てることができます。
MaxConnectionsPercent を 1 という低い値に設定できますが、インスタンスタイプに基づいて以下の最小値を使用することをお勧めします。
db.t3.small: 100
db.t3.medium: 55
db.t3.large: 35
db.r3.large またはそれ以上: 20
MaxIdleConnectionsPercent
| 最小値 | 最大値 | デフォルト値 (SQL Server) | デフォルト値 (他のエンジン) |
|---|---|---|---|
| (ゼロ) | MaxConnectionsPercent | MaxConnectionsPercent の 5% | MaxConnectionsPercent の 50% |
詳細については、「MaxIdleConnectionsPercent」を参照してください。
この設定は、RDS Proxy が接続プールに保持するアイドル状態のデータベース接続数を、データベースで許可される接続の最大数に対するパーセンテージで制限します。データベース (バックエンド) 接続は、接続に対するアクティビティが 5 分間なかった場合、アイドル状態とみなされます。この設定は、プロキシとバックエンドデータベース間の接続に適用されます。
次の点に注意してください。
-
この設定は、プール内のアイドル接続の数を制限しますが、プロキシが一定数のアイドル接続を保持するように強制することはありません。クライアントアクティビティが非常に少ない場合、バックエンドデータベース接続の実際の数は
MaxIdleConnectionsPercentを下回る可能性があります。 -
プロキシの接続プールで再利用できる場合、接続はアイドル状態としてカウントされます。固定接続は他のクライアントで再利用できないため、
MaxIdleConnectionsPercentの適用においてはアイドル状態としてカウントされません。固定の詳細については、「RDS Proxy の固定の回避」を参照してください。 -
データベースのメタデータによって報告されるアイドル接続の数は、通常、RDS Proxy のメトリクスによって記録されたアイドル接続の数よりも多くなります。これは、プロキシをバイパスする直接クライアント接続と、Amazon RDS および Aurora オートメーションで使用される内部接続が原因である可能性があります。
注記
プロキシレイヤーで観察および適用される接続アイドル時間は、MySQL のプロセスリストや PostgreSQL のアクティビティ統計テーブルなどのデータベースツールによって報告されるアイドル時間とは異なる場合があります。RDS Proxy はバックエンド接続に ping を送信することがあります。これにより、クライアントアクティビティに関して接続がアイドル状態のままであっても、データベースアイドルタイマーがリセットされます。
ベストプラクティス:
デフォルト設定の 50 は、ほとんどのワークロードに適しており、推奨されます。設定を変更すると、次の効果があります。
-
MaxIdleConnectionsPercentを上げると、データベースはより多くのアイドル接続を検出し、ピーク時間外にデータベースリソースの消費量が増加する可能性があります。一方、プロキシを介して処理される接続の急増は、プールですぐに利用できる接続が多いため、借用レイテンシーが低くなります。 -
MaxIdleConnectionsPercentを下げると、プロキシはアイドル状態の接続をより積極的に閉じ、それらの接続による競合とリソースの消費を減らす可能性があります。ただし、プロキシを通過する接続の急増により、借用時間が長くなる可能性があります。プールで使用できる接続が少ないため、プロキシは急増中に新しいバックエンド接続を開くために余分の時間を費やす必要があります。
プロビジョニングされたインスタンスタイプを使用するデータベースでは、アイドル状態の接続によるリソース消費が重要な懸念事項ではない場合がありますが、Serverless v2 インスタンスタイプを使用する Aurora データベースでは、アイドル状態のリソース消費を最適化してコストを削減することが望ましい場合があります。
IdleClientTimeout
| 最小値 | 最大値 | デフォルトの値 |
|---|---|---|
| 1 分 | 8 時間 | 30 分 |
詳細については、「IdleClientTimeout」を参照してください。
この設定は、プロキシがクライアント接続を閉じる前にアイドル状態を維持できる時間を決定します。RDS Proxy は、接続がアイドル状態であるかどうかにかかわらず、最大接続有効期間を 24 時間とすることに注意してください。例えば、IdleClientTimeout を 30 分 (デフォルト) に設定し、1 分ごとにデータベースに ping を実行する場合、接続がアイドルタイムアウトを超えることはありませんが、無期限に開いたままになることはありません。RDS Proxy は、アイドル状態とみなされない場合でも、24 時間後に接続を閉じます。
IdleClientTimeout 設定は、クライアント (アプリケーションまたはインタラクティブユーザー) と RDS Proxy 間の接続に適用されます。RDS Proxy とデータベース間のバックエンド接続のアイドル状態の動作については、「MaxIdleConnectionsPercent」を参照してください。
ベストプラクティス:
-
アイドルタイムアウトは、クライアント接続またはトランザクション内の SQL アクティビティの通常の一時停止に対応するのに十分な長さである必要があります。これは、クライアントが実質的には不要になったリソースを保持し続け、そのリソースを必要とする他のクライアントが利用できなくなるほど長く設定するべきではありません。これは、あるクライアントによって固定された接続を他のクライアントで再利用できないため、接続の固定が見られる場合に特に重要です。
-
RDS Proxy がタイムアウトを正しく適用するには、クライアント接続がクエリ (
SELECT 1;などの単純なヘルスチェックを含む) やプロトコル ping (MySQL のCOM_PINGなど) を送信せずに、本当にアイドル状態である必要があります。タイムアウトを超過しても接続が閉じられない場合は、アプリケーションドライバーの接続ロジックを確認してください。アプリケーションレベルの接続プールは、独自のライブネスチェックを実行する可能性が高く、IdleClientTimeoutと干渉する可能性があります。
ConnectionBorrowTimeout
| 最小値 | 最大値 | デフォルトの値 |
|---|---|---|
| (ゼロ) | 5 分 | 2 分 |
詳細については、「ConnectionBorrowTimeout」を参照してください。
クライアントが RDS Proxy に接続する場合、プロキシはプールから既存の利用可能な接続を借用するか、新しいデータベース接続を開く必要があります。この設定では、RDS Proxy が接続を借用または開くのを待つ時間を定義します。この時間を過ぎるとエラーを返します。
次の点に注意してください。
-
ConnectionBorrowTimeoutに 0 を設定すると、接続プールに使用可能な接続がまだ含まれていない場合、タイムアウトエラーが発生します。これは、プールが最大容量を下回っていて、新しいバックエンド接続を開く可能性がある場合でも当てはまります。 -
MaxIdleConnectionsPercentがMaxConnectionsPercentと等しい場合でも、プール内の実際の接続数は、設定された最大値を下回る可能性があります。つまり、MaxIdleConnectionsPercentはアイドル状態の接続の量を制限しますが、接続を強制的に開いたままにすることはありません。
接続プールが最大容量を下回って稼働するのは正常です。この状況では、ConnectionBorrowTimeout の設定を 0 にすることで、プールが新しい接続が開かれるのを待つことができないため、プールが増大するのを防ぐことができます。そのため、前述の動作が優先されない限り、すべてのワークロードにおいて、ConnectionBorrowTimeout の値をゼロ以外に設定する必要があります。
注記
この設定は、オフラインメンテナンスオペレーションやフェイルオーバー中など、データベースが接続を受け入れる準備ができていない場合にも適用されます。ConnectionBorrowTimeout を適用するロジックは、データベースが稼働中か停止中かにかかわらず同じです。
初期化クエリと固定フィルター
RDS Proxy は、接続の固定を減らし、結果として多重化の効率を向上させることができる追加機能をサポートしています。
初期化クエリは、プロキシが新しいバックエンドデータベース接続を設定するたびに実行される 1 つ以上のステートメントです。クライアントが同じステートメントを使用してセッションパラメータを設定する場合は、それらのステートメントをプロキシの初期化クエリに移動できます。これにより、固定の可能性が減り、効率も向上します。特定のバックエンドデータベース接続は、セットアップ中に初期化クエリを 1 回実行しますが、その後、多くのクライアントによって再利用される可能性があります。SQL ステートメントを初期化クエリに含めても、クライアントトラフィックから除外されないことに注意してください。アプリケーションコードからこれらのステートメントを削除して、多重化を妨げないようにする必要があります。
セッション固定フィルターは、プロキシが特定のセッション状態を固定できないようにする設定プロパティです。現在利用可能な唯一のフィルターオプションである EXCLUDE_VARIABLE_SETS は、セッションを固定するかどうかを決定するときに、すべての SET ステートメントを無視するようにプロキシに指示します。SET ステートメントは引き続きデータベースに渡され、セッション状態に影響する可能性があります。つまり、このオプションは、次の状況でのみ安全です。
-
SETステートメントが何もしない場合、例えばシステム変数をサーバーのデフォルトと同じ値に設定している場合です。 -
SETステートメントと後続のクエリは同じトランザクションの一部であり、すべてのトランザクションは、他のトランザクションによって設定された変数の影響を受けないように、完全に独立して独自の状態を設定します。
注記
EXCLUDE_VARIABLE_SETS 固定フィルターはすべてか無かの設定であり、無視する SET ステートメントを個別に選択することはできません。ユースケースが前のリストで説明したカテゴリのいずれかに該当しない限り、このフィルターを固定の包括的な解決策として使用しないでください。
最良の結果を得るには、可能な限りアプリケーションコードから不要なステートメントを削除し、アプリケーションの変更が不可能な場合にのみフィルターを使用します。これにより、そもそも必要のないステートメントに特別な処理を適用するのではなく、ノイズが少なく予測可能なクライアントサーバー環境が促進されます。
重要
初期化クエリも固定フィルターも、RDS Proxy がクライアントとサーバーのクエリトラフィックを変更する原因にはなりません。クライアントから到着したステートメントは、初期化クエリや固定フィルターの設定に関係なく、データベースに渡されます。
詳細については、以下を参照してください。
PostgreSQL 接続の場合、クライアントドライバーとプロキシの間で交換される起動メッセージに、サポートされている接続パラメータを含めることもできます。これにより、個別の SET コマンドが送信されなくなり、ラウンドトリップが減少し、明示的な SET ステートメントによる接続の固定が回避されます。詳細については、「PostgreSQL への接続に関する考慮事項」を参照してください。
アプリケーション、プロキシ、データベース設定の調整
前のセクションで説明したように、RDS Proxy はプロキシの動作をアプリケーションのニーズに合わせるのに役立つさまざまなパラメータをサポートしています。ただし、適切な設定値を選択することは、アプリケーション、プロキシ、データベース自体など、スタックのすべてのレイヤーにまたがるタスクです。これらのすべてのコンポーネントの設定は、以下の目標を念頭に置いて調整する必要があります。
-
通常のオペレーション中に期待されるレベルのパフォーマンスとスケーラビリティを提供します。
-
ワークロードの問題発生時のトラブルシューティングの明確さと容易性を促進します。
-
アプリケーションへの影響を最小限に抑えながら、スタックが予期しないイベント (ワークロードの急増など) に対処できるようにします。
多層環境で設定を選択して調整する場合は、下位レイヤーの制限とタイムアウトが、上位レイヤーの制限とタイムアウトに対応する値以上になるように設定値を調整してください。つまり、1 つのレイヤーの設定を、スタックのさらに下にある次の設定エンベロープに収まるエンベロープとして扱います。
例えば、アプリケーションが最上位レイヤー、プロキシが中間レイヤー、データベースが下位レイヤーであるとします。プロキシレベルのタイムアウトと制限がアプリケーションレベルの制限より低い場合、プロキシ制限はアプリケーション制限よりも優先されます。アプリケーションは設定を実行できず、独自の設定では説明できない動作が発生します。
例として IdleClientTimeout プロキシ設定を考えてみましょう。アプリケーションドライバーまたはクライアントプールが独自のアイドルタイムアウトを適用する場合、プロキシのアイドルタイムアウトはアプリケーション設定上のセーフティネットとして機能します。つまり、混乱を防ぐために、IdleClientTimeout はアプリケーションレベルのアイドルタイムアウトと少なくとも等しくなければなりません。
-
アプリケーションのアイドルタイムアウトがプロキシタイムアウトよりも短い場合、アプリケーションは設定どおりに接続を閉じることが予想されます。アプリケーションがアイドル状態の接続をタイムリーに閉じられない場合、プロキシはバックストップとして機能します。
-
アプリケーションのアイドルタイムアウトがプロキシタイムアウトよりも長い場合、アプリケーションは途中で接続が閉じられる可能性があります。これにより、アプリケーション側で混乱が生じる可能性があります。
接続制限などの他の設定にも同じロジックが適用されます。各レイヤーの設定は、次のレイヤーの設定で定義されたエンベロープ内に収まる必要があります。
最良の結果を得るには、設定において、1 つのレイヤーと次のレイヤーの間にパディングを含める必要があります。例えば、クライアント/サーバーのクロックドリフトによる散発的なエラーを回避するために、またはクライアントが接続を適切に閉じるために追加の時間が必要な場合に備えて、プロキシのタイムアウトをアプリケーションのタイムアウトよりも数秒長くすることができます。
つまり、次のように設定を調整します。
client timeout < proxy timeout < database timeout
次の例は推奨されません:
client timeout = proxy timeout = database timeout
また、以下は避けてください。
client timeout > proxy timeout > database timeout
データベース設定
接続制限
RDS Proxy は MaxConnectionsPercent 設定を使用して接続プールの最大サイズを決定します。つまり、プロキシの接続プールのサイズはデータベースの接続制限に相対的です。データベースの接続制限を変更すると、プロキシのプールサイズも自動的に変更されます。データベースで非プロキシユーザーの接続制限の一部を予約する場合は、データベース制限を増やすのではなく、プロキシの MaxConnectionsPercent 設定を下げる必要があります。
RDS Proxy を使用しても、データベース接続制限を適切に設定する必要性がなくなるわけではありません。単一のプロキシ接続は、本質的に単一の直接クライアント接続よりも軽量ではないため、プロキシを使用しているという理由だけでデータベース制限を増やさないでください。プロキシは、データベースがクエリを処理するために実行する作業量を削減するわけではありませんが、データベースがより少ない接続で同じワークロードを処理するのに役立ちます。
アイドルタイムアウト
データベースは、MySQL の wait_timeout および interactive_timeout 設定、PostgreSQL の transaction_timeout および idle_in_transaction_session_timeout 設定などを使用して、独自のアイドルタイムアウトを適用できます。これらの設定のデフォルト値がプロキシ設定に干渉する可能性は低いですが、カスタムのデータベースレベルのタイムアウトを使用する場合は、対応するプロキシタイムアウトと同じ長さ以上であることを確認してください。そうでない場合、タイムアウトが早すぎるためにプロキシで接続エラーが発生します。
接続キラーを使用するデータベース環境にも同じロジックが適用されます。接続キラーは、セッション状態をモニタリングし、特定の基準に基づいて接続をアクティブに終了させるスクリプトまたはプロセスです。環境がこのような手法を使用している場合は、接続終了ロジックがプロキシ設定と一致していることを確認してください。
プロキシを介してすべてのワークロードを処理するデータベースは、通常、アイドルタイムアウトのプロキシ設定に依存し、データベースレベルの設定をデフォルト値のままにすることができます。
アプリケーションの構成
セッション状態の管理
多くのデータベースドライバー、アプリケーションフレームワーク、オブジェクトリレーショナルマッピング (ORM) ツールでは、セッション変数または SET ステートメントを使用して、クエリトラフィックを送信する前に接続を設定します。接続およびトランザクションの初期化ステートメントの使用は、アプリケーションコードのみを見ると明確ではない場合があり、データベース自体と SQL ステートメントおよびアプリケーションロジックの間に複数の抽象化レイヤーが存在する可能性があります。RDS Proxy の拡張ログ記録機能を使用して、接続固定の理由を記録できます。また、データベースクエリログは、データベース接続を介して送信されるすべてのステートメントに関する詳細情報を提供できます。
以下のベストプラクティスを考慮します。
-
接続パラメータは、データベースのデフォルトと異なる場合、クライアントセッションがそれらのデフォルトから逸脱する必要がある場合にのみ設定します。不要な初期化ステートメントを削除することは、多重化に役立つだけでなく、新しいデータベース接続ごとにクライアントとサーバーのラウンドトリップの数を減らすことにもつながります。
-
すべての接続間で可変と構成設定を一貫して設定します。
-
クエリ実行時に適用できるセッション設定は避けてください。例えば、異なるクライアントが異なるタイムゾーンのデータを参照する必要がある場合は、セッションレベルでタイムゾーンを設定するのではなく、クエリレベルでタイムゾーン変換関数を使用することを検討してください。
-
可能であれば、初期化クエリ機能を使用してセッション設定ステートメントをプロキシレイヤーに移動します。詳細については、以下を参照してください。初期化クエリと固定フィルター
ライブネスチェック
アプリケーションが接続プーリングまたは高度なドライバーを使用している場合は、プロトコル ping、ヘルスチェックステートメント、キープアライブクエリなどのライブネスチェックに関連する設定を探します。RDS Proxy はすべてのクライアントリクエストを均等に扱うため、アプリケーションの観点からは SELECT 1; クエリまたは COM_PING リクエストが何もしない場合も、プロキシがアイドル状態のクライアントタイムアウトを適用や、MaxIdleConnectionsPercent に基づく接続プールサイズの管理を妨げることになります。
注記
RDS Proxy は、接続のアクティビティに関係なく、最大接続期間に 24 時間を適用します。
ほとんどの場合、クライアント側のライブネスチェックを無効にしてプロトコルノイズを減らし、RDS Proxy がアイドル状態の接続を管理できるようにすることをお勧めします。以下に関係なく、これらのヘルスチェックを実行するエッジケースがあります。
-
意図的にプロキシレイヤーで特定の接続がタイムアウトしないようにしたい。
-
アプリケーションドライバーまたはプールが、プロキシによって接続が切断されたことをプロアクティブに検出できるようにしたい。例えば、固定されたバックエンド接続がデータベースの再起動によって閉じられたり、クライアント接続が 24 時間の最大存続期間を超えたりする可能性があります。
アプリケーション側でライブネスチェックを無効にするか、タイムアウトを防ぎたい特定の接続に対してのみ実行することを検討してください。
セッション状態の追跡
MariaDB ドライバーなどの一部の MySQL データベースドライバーは、セッション状態の追跡を有効にするために session_track_* 変数を使用します。この機能を有効にすると、クライアントがサーバーが追跡できるセッション状態を変更するたびに、サーバーはレスポンスパケットに状態変更情報を含めます。これにより、ドライバーはサーバーからセッション状態に関する通知を受け取ることができます。
このセッション状態の追跡方法は、クライアントがサーバーと直接やり取りし、マルチサーバー環境でのセッション移行などの独自のセッション管理機能を実装する場合に有効です。RDS Proxy は独自の状態追跡メカニズムを実装し、session_track_* 変数によって有効化された情報は使用しませんが、これらの変数を設定するとセッションが固定されます。
データベースドライバーがこれらの変数を設定する場合は、ドライバーの追跡機能を無効にしたり、別のドライバーに切り替えたり、安全であればセッション固定フィルターを使用してステートメントを無視したりする方法を探すことができます。詳細については、以下を参照してください。初期化クエリと固定フィルター