Amazon DynamoDB リクエストの応答時間が増加していることを確認しましたが、増加の理由がわかりません。
簡単な説明
エンドツーエンドのレイテンシーには、DynamoDB サービス側のレイテンシーとユーザーのクライアント側のレイテンシーにおいて、責任の共有が伴います。
Amazon CloudWatch の SuccessfulRequestLatency メトリクスは、DynamoDB が API リクエストを完全に処理するのにかかる時間のみを測定します。DynamoDB は、アプリケーションが DynamoDB エンドポイントに接続したり、エンドポイントから結果をダウンロードしたりするのにかかる時間を測定しません。
解決策
レイテンシーを分析するときは、最大レイテンシー値ではなく、平均レイテンシーを確認するのがベストプラクティスです。レイテンシーが時折急上昇するのは、正常です。平均レイテンシーが高い場合は、根本的な問題がある可能性があります。
GetItem や PutItem などのほとんどのアトミック操作では、平均レイテンシーは 1 桁ミリ秒単位です。Query、Scan、BatchGetItem、BatchWriteItem などの非アトミック操作のレイテンシーは、さまざまな要因に左右されます。かかる要因には、結果セットのサイズ、挿入されたレコードの数、クエリ条件とフィルターの複雑さなどがあります。
レイテンシーが高くなる一般的な理由
アクセス頻度が低い
レイテンシーを避けるために、DynamoDB のすべてのフロントエンドホストはローカルキャッシュを維持しています。リクエスト率が低いと、フロントエンドフリートがしばらくの間リクエストを受信しなかったことにより、キャッシュ有効期間 (TTL) の期限が切れる可能性があります。キャッシュの期限が切れた後にリクエストがホストに到着した場合、ホストは内部の DynamoDB コンポーネントからデータを取得する必要があります。ホストがキャッシュに入力すると、ホストが応答できるようになります。データの取得と入力にかかる時間が原因で、待ち時間が長くなる可能性があります。
パーティションが分割されたり、リーダーシップが変更されたりすると、キャッシュが古くなり、最初の数回の呼び出しにおいてレイテンシーが高くなる可能性があります。DynamoDB は複数のキャッシュを参照して、パーティション情報、署名検証、および各リクエストに関するその他の情報を取得します。リクエストレートが低いと、キャッシュがウォーム状態を維持できなくなり、通常、最初の数回のリクエストのレイテンシーが高くなります。
リクエスト率が高く、受信トラフィックが安定していると、各リクエストは一貫してフロントエンドフリートに到達するため、レイテンシーの急上昇は発生しません。アクセス頻度が低いことによる問題を回避するには、クライアントで DynamoDB テーブルにダミートラフィックを送信します。
非常に一貫性のある読み取り
GetItem、Query、Scan などの読み取り操作には、オプションで使用できる ConsistentRead パラメータがあります。ConsistentRead を true に設定すると、DynamoDB は最新のデータを含むレスポンスを返します。このデータは、以前に成功したすべての書き込み操作の更新を反映していますが、それが原因でレイテンシーが高くなる可能性があります。
DynamoDB アーキテクチャでは、1 つのパーティションに 1 つのリーダーノードと 2 つのレプリカノードがあります。DynamoDB はリーダーノードを使用して強力かつ一貫した読み取りリクエストを処理しますが、読み取りレプリカにはサービスを実行しません。DynamoDB はリーダーノードを見つけてリクエストをサービスにリダイレクトする必要があるため、ある程度のレイテンシーが発生する可能性があります。
アプリケーションが強力で一貫した読み取りを必要としない場合は、最終的に一貫的となる読み取りを使用します。
レイテンシーを減らす方法
リクエストのタイムアウト設定を減らす
クライアント SDK パラメータ requestTimeOut と clientExecutionTimeout を調整して、50 ミリ秒後など、タイムアウトや失敗までの時間が大幅に短くなるよう調整します。このようにタイムアウトが短くなると、クライアントは指定された時間が経過した後、待ち時間の長いリクエストを放棄するようになります。次に、クライアントは 2 番目のリクエストを送信しますが、通常は最初のリクエストよりも大幅に速く完了します。タイムアウト設定に関する詳細については、「レイテンシーを考慮して、Amazon DynamoDB アプリケーション用に AWS Java SDK HTTP リクエスト設定を調整する」を参照してください。
クライアントと DynamoDB エンドポイントの間の距離を縮める
ユーザーがグローバルに分散している場合は、グローバルテーブルを使用して、テーブルを利用可能にする AWS リージョンを指定します。DynamoDB ゲートウェイエンドポイントを使用して、インターネット経由のトラフィックを回避することもできます。
キャッシュを使用する
トラフィックの読み取り量が多い場合は、Amazon DynamoDB Accelerator (DAX) などのキャッシュサービスを使用すると、レイテンシーを短縮できます。
接続の再利用
新しい接続を確立するときは、その接続を認証して検証する必要があります。また、リクエストを処理する前に、DynamoDB は内部システムからテーブルのメタデータを取得する必要があります。DynamoDB フロントエンドフリートは、この情報を保存するために使用するキャッシュを保持します。接続を再利用する場合、そのキャッシュをリクエストの処理に使用します。
AWS Key Management Service (AWS KMS) ユーザーの DynamoDB リクエストでは、認証を受けるために追加のホップが必要になるため、レイテンシーが増加する可能性があります。AWS KMS キーは 5 分ごとに更新されます。クライアント接続を再利用しない場合は、リクエストごとに新しい TCP 接続を確立する必要があります。これらのリクエストの接続には TCP ハンドシェイクや確認応答などのプロセスが含まれており、クライアント側のレイテンシーの原因となります。
新しい接続を行うたびに認証が必要となり、キャッシュを使用しないため、サーバー側でレイテンシーが発生します。接続を再利用するには、TCP keep-alive パラメータを使用します。また、接続オブジェクトのインスタンスが 1 つだけであることを保証する設計パターンを使用してください。詳細については、Amazon CloudGuru のウェブサイトで「AWS クライアントが Lambda 関数で再利用されない」を参照してください。
関連情報
SuccessfulRequestLatency
Amazon DynamoDB のレイテンシーについて
データのクエリとスキャンのベストプラクティス