

# DynamoDB Streams の使用状況を評価する
<a name="CostOptimization_StreamsUsage"></a>

このセクションでは、DynamoDB Streams の使用量を評価する方法についての概要を説明します。DynamoDB には最適ではない特定の使用パターンがあり、パフォーマンスとコストの両方の観点から最適化の余地があります。

ストリーミングとイベントドリブンのユースケースには、次の 2 つのネイティブストリーミング統合が用意されています。
+ [Amazon DynamoDB Streams](Streams.md) 
+ [Amazon Kinesis Data Streams](Streams.KCLAdapter.md) 

このページでは、これらのオプションのコスト最適化戦略のみに焦点を当てます。2 つのオプションのどちらかを選択する方法については、「[変更データキャプチャのストリーミングオプション](streamsmain.md#streamsmain.choose)」を参照してください。

**Topics**
+ [DynamoDB Streams のコストの最適化](#CostOptimization_StreamsUsage_Options_DDBStreams)
+ [Kinesis Data Streams のコストの最適化](#CostOptimization_StreamsUsage_Options_KDS)
+ [どちらのタイプの Streams 使用にも適したコスト最適化戦略](#CostOptimization_StreamsUsage_GuidanceForBoth)

## DynamoDB Streams のコストの最適化
<a name="CostOptimization_StreamsUsage_Options_DDBStreams"></a>

DynamoDB Streams の[料金ページ](https://aws.amazon.com/dynamodb/pricing/on-demand/)に記載されているように、テーブルのスループットキャパシティモードに関係なく、DynamoDB ではテーブルの DynamoDB Streams に対して行われた読み取りリクエストの数に応じて料金が発生します。DynamoDB Streams に対して行われる読み取りリクエストは、DynamoDB テーブルに対して行われる読み取りリクエストとは異なります。

Streams に関する各読み取りリクエストは `GetRecords` API コールの形式で行われ、最大 1,000 件のレコードまたは 1 MB 相当のレコードがレスポンスとして返されます。[他のいずれの DynamoDB Streams API](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations_Amazon_DynamoDB_Streams.html)、またはアイドル状態の DynamoDB Streams では料金が発生しません。つまり、DynamoDB Streams に対して読み取りリクエストが行われない場合、テーブルで DynamoDB Streams を有効にしても料金は発生しません。

DynamoDB Streams コンシューマーアプリケーションをいくつか紹介します。
+ AWS Lambda 関数
+ Amazon Kinesis Data Streams ベースのアプリケーション
+ AWS SDK を使用して構築されたお客様向けコンシューマーアプリケーション

DynamoDB Streams の AWS Lambda ベースのコンシューマーによる読み取りリクエストは無料ですが、他の種類のコンシューマーによる呼び出しには料金が発生します。毎月、Lambda 以外のユーザーによる読み取りリクエストのうち、最初の 2,500,000 件も無料です。これは、各 AWS リージョンの AWS アカウント内の DynamoDB Streams に対するすべての読み込みリクエストに適用されます。

**DynamoDB Streams 使用量のモニタリング**  
請求コンソールの DynamoDB Streams の料金は、AWS アカウント内の AWS リージョンにあるすべての DynamoDB Streams でまとめられます。現在、DynamoDB Streams のタグ付けはサポートされていないため、コスト配分タグを使用して DynamoDB Streams の詳細なコストを特定することはできません。`GetRecords` の呼び出し量を DynamoDB Streams レベルで取得して、ストリームあたりの料金を計算することは可能です。呼び出し量は DynamoDB Streams の CloudWatch メトリクス `SuccessfulRequestLatency` とその `SampleCount` 統計によって表されます。このメトリクスには、継続的なレプリケーションを行うためのグローバルテーブルによる `GetRecords` コールや、AWS Lambda コンシューマによるコールも含まれますが、いずれも料金は発生しません。DynamoDB Streams によって公開されるその他の CloudWatch メトリクスについては、「[DynamoDB のメトリクスとディメンション](metrics-dimensions.md)」を参照してください。

**AWS Lambda をコンシューマーとして使用する**  
AWS Lambda 関数を DynamoDB Streams のコンシューマーとして使用できるかどうかを評価してください。これにより、DynamoDB Streams からの読み取りに関連するコストを削減できるためです。一方、DynamoDB Streams Kinesis Adapter または SDK ベースのコンシューマーアプリケーションでは、DynamoDB Streams に対して行った `GetRecords` 呼び出しの数に応じて料金が発生します。

Lambda 関数の呼び出しは Lambda の標準料金に基づいて課金されますが、DynamoDB Streams では料金は発生しません。Lambda は、レコードの DynamoDB Streams にあるシャードを 1 秒あたり 4 回の基本レートでポーリングします。レコードが利用可能になると、Lambda は関数を呼び出し、結果を待機します。処理が成功すると、Lambda は、レコードをさらに受け取るまでポーリングを再開します。

**DynamoDB Streams Kinesis Adapter ベースのコンシューマーアプリケーションのチューニング**  
Lambda ベースではないコンシューマーによる読み取りリクエストは DynamoDB Streams に対して課金されるため、ほぼリアルタイムの要件と、コンシューマーアプリケーションが DynamoDB Streams をポーリングしなければならない回数とのバランスをとることが重要です。

DynamoDB Streams Kinesis Adapter ベースのアプリケーションを使用して DynamoDB Streams をポーリングする頻度は、設定された `idleTimeBetweenReadsInMillis` 値によって決まります。このパラメータは、同じシャードへの前回の `GetRecords` 呼び出しでレコードが返されなかった場合に、コンシューマーがシャードを処理する前に待機する時間をミリ秒単位で決定します。デフォルトでは、このパラメータの値は 1,000 ミリ秒です。ほぼリアルタイムの処理が必要ない場合は、このパラメータを増やしてコンシューマーアプリケーションが行う `GetRecords` 呼び出しを減らし、DynamoDB Streams 呼び出しを最適化できます。

## Kinesis Data Streams のコストの最適化
<a name="CostOptimization_StreamsUsage_Options_KDS"></a>

Kinesis Data Streams が DynamoDB テーブルの変更データキャプチャイベントの送信先として設定されている場合、Kinesis Data Streams は個別のサイズ管理を必要とする場合があり、これは全体のコストに影響を与えます。DynamoDB は、変更データキャプチャユニット (CDU) 単位で課金されます。この場合、各ユニットは、DynamoDB サービスが送信先の Kinesis Data Streams に対して試行する 1 KB の DynamoDB 項目サイズで構成されます。

DynamoDB サービスによる料金に加えて、Kinesis Data Streams の標準の料金が発生します。[料金ページ](https://aws.amazon.com/kinesis/data-streams/pricing/)に記載されているように、サービスの料金は、DynamoDB テーブルのキャパシティモードとは異なり、ユーザー定義のキャパシティモード (プロビジョニングまたはオンデマンド) によって異なります。おおまかに言うと、Kinesis Data Streams は、キャパシティモードと DynamoDB サービスによってストリームに取り込まれたデータに基づいて、時間単位で課金されます。Kinesis Data Streams のユーザー設定によっては、データ検索 (オンデマンドモードの場合)、データ保持の延長 (デフォルトの 24 時間を超える場合)、拡張ファンアウトコンシューマーの取得などの追加料金が発生する場合があります。

**Kinesis Data Streams の使用量のモニタリング**  
DynamoDB 用 Kinesis Data Streams は、標準の Kinesis Data Streams CloudWatch メトリクスに加えて、DynamoDB からのメトリクスを発行します。Kinesis Data Streams のキャパシティ不足の場合は Kinesis によって、または Kinesis Data Streams の保管中のデータを暗号化するように設定された AWS KMS サービスなどの依存コンポーネントによって、DynamoDB サービスによる `Put` の試みがスロットリングされる可能性があります。

DynamoDB サービスが Kinesis Data Streams 用に発行する CloudWatch メトリクスの詳細については、「[Kinesis Data Streams を使用した変更データキャプチャのモニタリング](kds_using-shards-and-metrics.md#kds_using-shards-and-metrics.monitoring)」を参照してください。スロットリングが原因のサービスの再試行による追加コストを回避するために、プロビジョニングモードの場合は Kinesis Data Streams のサイズを適切に設定することが重要です。

**Kinesis Data Streams に適したキャパシティモードの選択**  
Kinesis Data Streams は、プロビジョニングモードとオンデマンドモードの 2 つのキャパシティモードでサポートされています。
+ Kinesis Data Streams を含むワークロードのアプリケーショントラフィックが予測可能な場合や、トラフィックが安定しているか徐々に増加している場合、またはトラフィックが正確に予測できる場合は、Kinesis Data Streams **プロビジョニングモード**が適しており、コスト効率も高くなります。
+ ワークロードが新しい場合や、アプリケーショントラフィックが予測できない場合、またはキャパシティを管理したくない場合は、Kinesis Data Streams の**オンデマンドモード**が適しており、コスト効率も高くなります。

コストを最適化するためのベストプラクティスは、Kinesis Data Streams に関連する DynamoDB テーブルが、Kinesis Data Streams のプロビジョニングモードを活用できる予測可能なトラフィックパターンを持っているかどうかを評価することです。ワークロードが新しい場合は、最初の数週間は Kinesis Data Streams にオンデマンドモードを使用し、CloudWatch メトリクスを確認してトラフィックパターンを理解してから、同じストリームをワークロードの性質に基づいてプロビジョニングモードに切り替えることができます。プロビジョニングモードの場合、Kinesis Data Streams のシャード管理に関する考慮事項に従うことでシャード数を推定できます。

**DynamoDB 用 Kinesis Data Streams を使用したコンシューマーアプリケーションの評価**  
Kinesis Data Streams は DynamoDB Streams のように `GetRecords` の呼び出し回数で課金されないため、`GetRecords` のスロットリング制限内であれば、コンシューマーアプリケーションで何度でも呼び出しを行えます。Kinesis Data Streams のオンデマンドモードでは、データ読み取りは GB 単位で課金されます。プロビジョニングモードの Kinesis Data Streams では、データが 7 日未満の場合、読み取りは課金されません。Kinesis Data Streams コンシューマーとしての Lambda 関数の場合、Lambda は 1 秒あたり 1 回の基本レートで、レコードの Kinesis Data Streams にある各シャードをポーリングします。

## どちらのタイプの Streams 使用にも適したコスト最適化戦略
<a name="CostOptimization_StreamsUsage_GuidanceForBoth"></a>

**AWS Lambda コンシューマー向けイベントフィルタリング**  
Lambda イベントフィルタリングを使用すると、フィルター条件に基づくイベントを Lambda 関数呼び出しバッチで使用できないように破棄できます。これにより、コンシューマー関数ロジック内の不要なストリームレコードを処理または破棄するための Lambda コストが最適化されます。イベントフィルタリングの設定とフィルタリング条件の記述の詳細については、「[Lambda のイベントフィルタリング](https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventfiltering.html)」を参照してください。

**AWS Lambda コンシューマーの調整**  
`BatchSize` を大きくして呼び出しごとに処理する量を増やす、`BisectBatchOnFunctionError` を有効にして重複処理 (追加コストが発生する) を防ぐ、再試行回数が多すぎることのないように `MaximumRetryAttempts` を設定するなど、Lambda の設定パラメータを調整することで、コストをさらに最適化できます。デフォルトでは、コンシューマーの Lambda 呼び出しが失敗すると、ストリームからレコードの有効期限が切れるまで無限に再試行されます。DynamoDB Streams 場合は 24 時間前後、Kinesis Data Streams では 24 時間から最長 1 年まで設定できます。上記の DynamoDB Streams コンシューマー向けの Lambda 設定オプションなど、その他の Lambda 設定オプションについては、「[AWS Lambda デベロッパーガイド](https://docs.aws.amazon.com/lambda/latest/dg/with-ddb.html#services-ddb-params)」を参照してください。