Kinesis Data Streams の ReadProvisionedThroughputExceeded 例外を検出してトラブルシューティングするにはどうすればよいですか?
最終更新日: 2021 年 4 月 28 日
Amazon Kinesis Data Streams で ReadProvisionedThroughputExceeded エラーが発生しました。その理由と、この問題をトラブルシューティングする方法を教えてください。
簡単な説明
ReadProvisionedThroughputExceeded エラーは、GetRecords 呼び出しが一定時間にわたって Kinesis データストリームによってスロットル済みになったときに発生します。
Amazon Kinesis データストリームは、次の制限を超えた場合にスロットル済みとなります。
- 各シャードは、1 秒あたり最大 5 つの読み込みトランザクション (つまり、シャードごとに 毎秒 5 回の GetRecords 呼び出し) をサポートできます。
- 各シャードは、最大 2 MB/ 秒の読み込みレートまでサポートできます。
- GetRecords は、1 つのシャードから呼び出しあたり最大 10 MB のデータ、および呼び出しあたり最大 10,000 レコードを取得できます。GetRecords の呼び出しが 10 MB のデータを返した場合、次の 5 秒以内に行われたそれ以降の呼び出しはエラーになります。
ReadProvisionedThroughputExceeded エラーが発生した場合は、次のアプローチを検討してください。
- 問題の根本原因を特定します。
- 可能性のあるマイクロバーストを特定します。
- データストリームのベストプラクティスに従います。
解決方法
問題の根本原因を特定
データストリームの ReadProvisionedThroughputExceeded エラーの根本原因を特定するには、Amazon CloudWatch で Amazon Kinesis Data Streams サービスをモニタリングします。CloudWatch の次のメトリクスに注意してください。
- GetRecords.Bytes: 指定した期間に測定された Kinesis データストリームから取得されたバイト数。
- GetRecords.Records: 指定した期間に Kinesis データストリームから取得されたレコード数。
- ReadProvisionedThroughputExceeded:Kinesis データストリームでスロットリングされている GetRecords 呼び出し数。
期間を 1 分に設定して、統計を Sum として表示するように CloudWatch ダッシュボードを設定します。次に、Sum を 60 秒で割って平均値を取得します。
例えば、GetRecords.Records メトリクス値を使用する場合、Sum を 60 秒で割って、1 秒あたりに送信されるレコードの平均数を算出します。次に、Kinesis データストリームに設定された 1 秒あたりに送信されるレコード数の上限値よりも、平均値が小さいかどうかを確認します。シャードの制限の詳細については、「Kinesis Data Streams のクォータと制限」をご参照ください。
注: 拡張モニタリング機能を有効にして、負荷がすべてのシャードに均等に分散されるようにできます。
また、統計が SampleCount として表示され、期間が 1 分に設定された GetRecords.Records メトリクスを使用することもできます。SampleCount 値を 60 秒で割って、各シャードの 1 秒あたりに行われた GetRecords 呼び出しの平均数を計算します。平均値が 1 秒あたり約 5 回の GetRecords 呼び出しであり、ReadProvisionedThroughputExceeded エラーが発生する場合は、コンシューマーがシャードの制限を超えていないことを確認します。シャードの制限を超えていない場合、ReadProvisionedThroughputExceeded エラーは、コンシューマーが 1 秒あたり 5 回以上の GetRecords 呼び出しを行った結果である可能性があります。
最後に、シャードの ReadProvisionedThroughputExceeded 値の間に相違があるかどうかを確認します。シャードの分散が不均等であるか、一方のシャードが他方のシャードよりも多いまたは少ないデータを受け取った場合、分散の不均衡が生じる可能性があります。このシャード分散の不均衡を解決し、ホットシャードを回避するには、putRecords API 呼び出しで UUID をパーティションキーとして使用します。
可能性のあるマイクロバーストを特定
稀に、メトリクス値がシャード制限を下回り、Kinesis データストリームが読み取り中にスロットリングを起こす可能性があります。
例えば、GetRecords のバイト数合計: 1 分 が 1 分間の読み取りデータの 10 MB を表すシナリオを考えてみます。1 秒で、GetRecords のバイト 呼び出しはスロットリングなしで 2 MB のデータを読み取ります。したがって、2 秒で GetRecords のバイト 呼び出しは 8 MiB のデータを読み取ります。3 秒では、読み取りオペレーションやスロットリングが発生しない可能性があります。1 分あたりのシャード制限には達していませんが (2MiB * 60 = 120MiB のデータ)、 ReadProvisionedThroughputExceeded エラーを受け取ることがあります。メトリクス値の急上昇に気付いた場合は、ReadProvisionedThroughputExceeded 例外の原因となっているマイクロバーストを探します。
データストリームのベストプラクティスに従う
ReadProvisionedThroughputExceeded 例外を軽減するには、以下のベストプラクティスを適用します。
- ストリームを再度シャードして、ストリーム内のシャードの数を増やします。
- GetRecords リクエストのサイズを減らします。これを行うには、limit パラメータを設定するか、GetRecords リクエストの頻度を減らします。
注: コンシューマーが Amazon Kinesis Data Firehose の場合、Kinesis データストリームは、実行中の GetRecords 呼び出しの頻度に合わせて調整されます。コンシューマーがイベントソースマッピングを使用する AWS Lambda 関数である場合、ストリームは 1 秒に 1 回ポーリングされます。ポーリング頻度は変更できません。コンシューマーが Amazon Kinesis Client Library (KCL) アプリケーションである場合は、ポーリング頻度を調整します。ポーリング頻度を調整するには、KinesisClientLibConfiguration ファイルで DEFAULT_IDLETIME_BETWEEN_READS_MILLIS パラメータ値を変更します。この値はコード内で動的に設定できます。KCL でこの値を変更する方法の詳細については、GitHub ウェブサイトの Amazon Web Services - Labs をご参照ください。 - データストリーム内のすべてのシャードに、読み取りおよび書き込みオペレーションを可能な限り均等に分散します。
- 拡張ファンアウトでコンシューマーを使用します。拡張ファンアウト の詳細については、「専用スループットを使用したカスタムコンシューマーの開発(拡張ファンアウト)」をご参照ください。
注意: Kinesis データストリームで 5 つ以上のコンシューマーを使用している場合は、拡張ファンアウトでコンシューマーを使用することをお勧めします。 - ReadProvisionedThroughputExceeded 例外が発生した場合は、コンシューマーロジックで エラーの再試行とエクスポネンシャルバックオフメカニズムを使用します。AWS SDK を使用するコンシューマーアプリケーションの場合、リクエストはデフォルトで再試行されます。