Kinesis Data Streamsのプロデューサー、シャード、コンシューマー

Kinesis Data Streamsのレコードとパーティションキー、シャード容量、プロデューサーとコンシューマー、キャパシティモード、拡張ファンアウトを学びます。

学習順Step 109 / 121サービスKinesis試験ドメイン開発

Kinesis Data Streamsの役割

Amazon Kinesis Data Streamsは、継続的に発生するレコードをリアルタイムに取り込み、一定期間保持して、複数のコンシューマーアプリケーションが読み取れるようにするストリーミングデータサービスです。プロデューサーとコンシューマーを直接結び付けず、ストリームを間に置くことで、送信側と処理側をそれぞれの速度で動かせます。データはリージョン内の複数のアベイラビリティーゾーンに冗長化して保存されます。

たとえば、オンライン予約サービスで予約状態が変わるたびにイベントをストリームへ書き込めます。決済照合アプリケーションはイベントを即時に処理し、利用状況を集計する別のアプリケーションは同じレコードを独立して読み取れます。一方の処理が遅れても、もう一方の処理と送信元が直接同期している必要はありません。

Data Streamsはレコードを受け取り、シャードへ振り分け、保持する役割を担います。データ内容を業務ルールに従って自動変換するわけではありません。データの検証や変換、集計はプロデューサー、コンシューマー、または別のストリーム処理サービスで行います。

プロデューサーからシャードを経て標準・拡張ファンアウトのコンシューマーへ届く流れ

レコード、パーティションキー、シャード

プロデューサーはPutRecordまたはPutRecords APIなどを使ってストリームへデータを送ります。1件のデータ単位をレコードと呼び、レコードにはアプリケーションのデータ本体とパーティションキーが含まれます。Data Streamsはパーティションキーからハッシュ値を計算し、その値が属するハッシュ範囲を持つシャードへレコードを振り分けます。書き込み後はレコードにシーケンス番号が割り当てられ、同じシャード内の記録順を追跡できます。

レコードサイズの既定上限は1 MiBです。より大きなレコードを扱う必要があれば、ストリームの最大レコードサイズを設定して最大10 MiBまで拡張できます。ただし、拡張後もシャードあたりの書き込みスループット上限は変わらず、継続的に大きなレコードを大量投入する用途向けではありません。大きなペイロードはS3などに保存し、ストリームには参照情報を送る設計も検討します。

シャードは、ストリームを並列化する基本単位です。各シャードには到着順に並んだレコード列があり、複数シャードはそれぞれ独立して読み書きできます。したがって、順序が保証される範囲はシャード単位です。ストリーム全体で、異なるシャード間の全レコードに共通の順序が付くわけではありません。

パーティションキーは単なる振り分け用の文字列ではなく、並列性や順序の設計にも関係します。同じキーのレコードは同じシャードに向かうため、予約IDをキーにすれば、同じ予約に関する状態変更を同じシャードで処理しやすくなります。しかし、少数のキーに大部分のデータが集中すると、対応するシャードだけが上限に達するホットシャードが発生します。ストリーム全体の容量に余裕があっても、特定シャードの上限によってそのキーの書き込みがスロットリングされることがあります。

この動作が使われるのは、既定のUSER_PARTITION_KEYレコード分散方式です。オンデマンドストリームでは、シャード単位で同じキーの順序を保つ必要がない場合にAUTO分散方式を選べます。この方式では、サービスがレコードをシャードに自動分散し、指定したパーティションキーはルーティングに使われません。キーに基づく処理順が必要かを先に判断してから選択します。

キーの設計 振り分けへの影響 判断のポイント
低カーディナリティのキー 少数のハッシュ範囲にレコードが集まりやすい 同じキーの順序が必要か、偏りが許容できるかを確認する
多くの値に分散するキー シャード間にトラフィックを分散しやすい 高い取り込み量を並列処理したい場合に適する
ランダムなキー 均等な分散に役立つ キー単位の順序が不要な場合に選べる

ホットシャードを避けるには、利用者IDや予約IDなど、実際のデータ分布に対して十分に多くの異なる値を持つキーを選びます。特定のキー単位で処理順が必要なのに、そのキーの流量が非常に大きい場合は、キーを細分化すると順序の意味が変わります。順序要件と分散のどちらを優先するかを明示して設計してください。

シャード容量とスループット

プロビジョンドモードではシャード数の合計がストリームの容量になります。1シャードあたりの代表的な上限は次のとおりです。

操作 1シャードあたりの代表的な上限
書き込み 1 MB/秒、または1,000レコード/秒
通常の読み取り 最大2 MB/秒をコンシューマー間で共有

書き込み側では、バイト数とレコード数のどちらか一方でも上限に到達すると書き込みが制限されます。小さなレコードが多ければレコード数の上限が先に問題になり、大きなレコードが多ければバイト数の上限が先に問題になります。これらは単純に合算できる値ではありません。たとえば、2シャードで十分に分散できれば、書き込み容量の合計目安は2 MB/秒かつ2,000レコード/秒ですが、片方に偏ればもう片方の余力を使えません。

負荷を見積もるときは、ストリーム全体の平均値だけでなくシャード単位の流量を確認します。CloudWatchのIncomingBytesとIncomingRecordsで取り込み量を観察し、WriteProvisionedThroughputExceededで書き込みスロットリング、ReadProvisionedThroughputExceededで通常読み取りのスロットリングを調べます。GetRecords.IteratorAgeMillisecondsは、コンシューマーが最新データからどれほど遅れているかを把握する指標です。シャードレベルの詳細メトリクスを有効にすると偏りを見つけやすくなりますが、CloudWatchのカスタムメトリクス料金も考慮します。

プロビジョンドストリームのシャード数は、負荷に応じて増減できます。シャード分割や結合などのリシャーディングを行うと、新しいデータのルーティング先が変わります。既存の親シャードとそこに書き込まれたレコードは直ちに消えず、保持期間中は読み取り可能です。コンシューマーは親シャードの残りを処理してから子シャードを追う必要があるため、リシャーディングに対応したクライアントを使い、処理位置の引き継ぎを考慮します。

オンデマンドモードではAWSがストリームの容量を管理するため、利用者が通常のシャード数を決めて調整する必要はありません。On-demand Standardでは、直近30日間で観測した過去のピーク書き込みスループットの最大2倍までを自動的に処理できるようスケールし、新たなピークに合わせて容量を調整します。トラフィックが15分以内に過去ピークの2倍を超える速さで増えると、スロットリングが発生する可能性があります。指数バックオフなどを用いたリトライ、失敗レコードの記録、過負荷を吸収できるプロデューサー設計を用意します。

オンデマンドには、アカウント単位で利用を有効にするOn-demand Advantageもあります。Standardと同じく実際の利用量に応じて自動スケールし、予想される急増に備えて書き込み容量を事前にウォームアップできます。料金体系には最低スループット利用量のコミットメントがあるため、予測不能な負荷なら常にAdvantageが有利というわけではありません。採用条件と課金の詳細は公式料金情報で確認します。

キャパシティモード 容量管理 向いている状況
プロビジョンド 利用者がシャード数を指定し、監視しながら増減する 流量を予測しやすく、必要容量やコストを自分で細かく管理したい
オンデマンド AWSがトラフィックに合わせて容量を管理する 流量が予測しづらく、シャード数の運用を減らしたい

プロビジョンドでは低利用時にも確保したシャード分の料金が発生するため、適正なシャード数の維持が重要です。オンデマンドでは書き込み・読み取りデータ量に応じた料金体系となり、安定した予測可能な負荷ではプロビジョンドより高くなる場合もあります。料金はモード、リージョン、処理量、拡張ファンアウト、保持期間などで変わるため、Amazon Kinesis Data Streamsの料金で必要な項目を確認してください。

コンシューマーとデータ保持

ストリームからレコードを取得して処理する側をコンシューマーと呼びます。標準的なコンシューマーはGetRecords APIでシャードをポーリングします。同じシャードを複数の標準コンシューマーが読み取ると、最大2 MB/秒の読み取り帯域を共有します。利用者が複数あると、一つのコンシューマーの読み取りがほかのコンシューマーの遅延やスロットリングに影響する場合があります。

Amazon Kinesis Client Library(KCL)は、シャードを複数のワーカーへ割り当て、コンシューマーアプリケーションを並列化するためのライブラリです。KCLアプリケーションは処理位置をチェックポイントとして管理し、障害や再起動後にどこから再開するかを制御できます。シャード数に応じてワーカーを動かす構成では、シャード単位の順序を保ちながら複数シャードを並列に処理できます。KCLはデータ処理そのものをAWSへ委ねるものではなく、コンシューマーアプリケーションの作成と運用は必要です。

レコードの保持期間はデフォルトで24時間です。保持期間は24時間から最大365日まで延長できます。24時間を超える延長保持と、7日を超える長期保持には追加料金がかかります。また、7日を超えて保持したデータを通常コンシューマーのGetRecordsで読み出す場合は、取得データ量に応じた料金が発生することがあります。保持期間内のデータは、一つのコンシューマーが読み取ったあとでもストリームから消えません。各コンシューマーは独自のチェックポイントから読み進め、必要であれば保持中の過去データを再処理できます。保持期間を超えたレコードは読めなくなるため、処理障害から復旧するのに必要な時間や、再処理の要件を基に保持期間を決めます。

拡張ファンアウトで読み取り帯域を分離する

**拡張ファンアウト(Enhanced Fan-Out / EFO)**は、登録されたコンシューマーごとに専用の読み取り帯域を割り当てる仕組みです。通常読み取りのように複数コンシューマーが同じ2 MB/秒を共有せず、各コンシューマーは各シャードから最大2 MB/秒を利用できます。Data StreamsはHTTP/2を使うSubscribeToShard APIでレコードをコンシューマーへプッシュするため、ポーリング間隔による待ち時間を抑えられます。

ProvisionedおよびOn-demand Standardのストリームでは、1ストリームにつき最大20のEFOコンシューマーを登録できます。On-demand Advantageモードでは最大50という別の上限があります。したがって「EFOは常に20まで」と固定して覚えず、容量モードによる例外を区別します。たとえばプロビジョンドのストリームに8シャードがある場合、1つのEFOコンシューマーは最大16 MB/秒の読み取り帯域を利用でき、他の登録コンシューマーにもそれぞれ専用帯域が割り当てられます。

AWSが示す代表的な伝搬遅延は、通常コンシューマーが1つの場合で平均約200ミリ秒、同じシャードを5つのコンシューマーが読む場合で平均約1,000ミリ秒、EFOではコンシューマー数にかかわらず平均約70ミリ秒です。これは一般的な条件での平均値であり、個別のアプリケーションで保証される遅延ではありません。低遅延かつ複数の読み取り先が必要な場合に、帯域分離の効果と追加料金を比べます。

EFOは、複数の独立したアプリケーションが同じストリームを低遅延で処理するときに適しています。専用読み取り帯域が必要なため、EFOコンシューマーと取得データ量に応じた追加料金を考慮します。消費者が少なく、共有読み取り帯域で処理が間に合うなら、標準コンシューマーの方が構成も料金も単純です。

ログファイルを送るKinesis Agent

Kinesis Agentは、サーバー上のファイルを継続的に監視して、追加されたデータをKinesis Data StreamsまたはAmazon Data Firehoseへ送るスタンドアロンのJavaアプリケーションです。ログファイルを発生元とする既存システムに導入でき、ファイルのローテーション、送信位置のチェックポイント、失敗時の再試行、CloudWatchメトリクスの出力などを扱います。サーバーにエージェントをインストールして設定する必要はありますが、アプリケーションに独自の送信ロジックを追加せず、ファイルからデータを転送できます。

CloudWatch Agentもサーバー上で動くエージェントですが、主な役割はログをCloudWatch Logsへ送ったり、ホストのメトリクスをCloudWatchへ送ったりすることです。どちらもCloudWatchで監視できる場合がありますが、Kinesis AgentはData Streams / Data Firehoseへのデータ取り込み、CloudWatch AgentはCloudWatchへのログ・メトリクス収集を中心とする点で用途が異なります。送信先や処理経路を確認して選択します。

Kinesis Data StreamsとSQSの使い分け

どちらもデータを直接同期せずに連携できますが、基本となるデータモデルが異なります。

観点 Kinesis Data Streams Amazon SQS
主な単位 順序を持つレコード列。シャードごとに並列化する キューに置かれた個々のメッセージ
消費方法 コンシューマーが位置を管理して読み進める ワーカーが受信し、通常は処理後にメッセージを削除する
複数の処理先 複数コンシューマーが保持データをそれぞれ読み取れる 通常は複数ワーカー間でタスクを分配する。複数システムへの配信にはSNSなどとのファンアウトを組み合わせる
主な用途 大量のイベントを継続的に取り込み、順序や再読込を活用してリアルタイム処理する 処理待ちのジョブを蓄積し、ワーカーが非同期で処理する

請求状態の変更を分析用システムと監査用システムがそれぞれ追跡し、途中から読み直す必要があるならData Streamsが候補です。帳票生成の依頼をキューへ入れ、空いているワーカーへ一件ずつ処理を割り当てたいならSQSが候補です。要件が「順序付きのデータ列を保持して複数アプリケーションで読み取る」か、「個々の作業項目をワーカーへ渡して完了させる」かを軸に判断します。

暗号化と監視

Data Streamsは保存時の暗号化に対応し、AWS所有キー、AWS管理キー、またはカスタマー管理のAWS KMSキーを使えます。暗号化の選択によって必要なIAM権限、KMSキーポリシー、料金が変わります。書き込みや読み取りが拒否された場合は、ストリームの権限に加えてKMSキーへのアクセスも確認します。

CloudWatchではストリーム全体および設定に応じたシャード別のメトリクスを確認できます。IncomingBytes / IncomingRecordsの偏り、書き込み・読み取りのスロットリング、コンシューマーのIteratorAgeMillisecondsを組み合わせると、ストリーム容量不足、ホットシャード、処理側の遅延を切り分けやすくなります。ストリーム全体の平均値だけで判断せず、必要に応じてシャード別の詳細値を見ます。

公式ドキュメント

重要ポイント

  • ▸プロデューサーが書き込むレコードは、パーティションキーのハッシュ値に基づいてシャードへ振り分けられる
  • ▸プロビジョンドの1シャードあたりの書き込み上限は1 MB/秒または1,000レコード/秒のいずれかに先に達する方であり、ホットシャードを避けるにはキーの分散が重要
  • ▸通常コンシューマーはシャードごとの読み取り帯域を共有し、拡張ファンアウトはコンシューマーごとに専用の読み取り帯域を割り当てる
  • ▸レコードはデフォルト24時間、設定により最大365日保持され、保持期間内は別のコンシューマーで再読込できる
  • ▸プロビジョンドはシャード数を利用者が調整し、オンデマンドはAWSが容量を管理する。トラフィック急増時はリトライも設計する
  • ▸Kinesis AgentはファイルをData StreamsまたはData Firehoseへ送り、CloudWatch Agentは主にCloudWatch LogsやCloudWatchメトリクスへ送る

このトピックの学習を完了しますか?

完了状態はいつでも切り替えられます