NTTドコモR&Dの技術ブログです。

KinesisDataStreamsのコスト最適化

はじめに

こんにちは、NTTドコモでAWSインフラを担当している高橋です。

ある日、ふとAWSの請求書を見て「おや、Kinesis Data Streamsの料金が思ったより高いぞ…?」と気づいたのが、今回の話の始まりです。

コストの内訳を調べていくと、どうやら「シャード数」の最適化が鍵になりそうだと分かりました。

そこで、自システムの適正なシャード数を計算するために試行錯誤した内容を、備忘録としてまとめてみることにしました。

この記事が役に立ちそうな方

  • Kinesis Data Streamsのコストを削減したいと思っている方
  • システムのシャード数が本当に適切か、見直してみたい方
  • これからAWSのデータ分析基盤を学ぼうとしている方

Amazon Kinesis Data Streamsって何?

サービス概要

一言でいうと「大量のデータをリアルタイムで受け取り、処理するためのパイプライン」のようなサービスです。

言葉で説明するよりも、まずは公式の資料に目を通してみるのがイメージが湧きやすいと思います。
特にBlack Beltは図も多くて分かりやすいです。

AWS公式ページ aws.amazon.com

AWS Black Belt Online Seminar 資料
https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2023_AmazonKinesisDataStreams_0430_v1.pdf

料金体系をざっくり理解する

Kinesisのコスト削減を考える上で、まず料金体系の理解は欠かせません。
料金モードは2種類あります。

オンデマンドモード

「使った分だけ支払う」シンプルなモードです。
主に以下の3つの要素で料金が決まります。

  • ストリーム基本料金: ストリームが存在するだけでかかる基本料金
  • インプットデータ料金: Kinesisに書き込んだデータ量(GB単位)
  • アウトプットデータ料金: Kinesisから読み込んだデータ量(GB単位)

トラフィックの予測が難しいシステムに向いています。

プロビジョンドモード

こちらが今回の本題です。「シャード」という処理単位をあらかじめ確保しておくモードで、料金は主に以下の2つで構成されます。

  • シャード料金: 確保したシャードの数 × 時間
  • PUT料金: 書き込み回数(25KBごとのペイロードユニット数)

この他に、拡張ファンアウト機能の利用やデータ保持期間の延長で追加料金がかかります。

まとめ

料金モード 特徴 こんな場合にオススメ
オンデマンドモード ・使った分だけ支払うシンプルさ
・急なトラフィック増にも自動対応
トラフィックの予測が難しい、または変動が激しいシステム
プロビジョンドモード ・処理能力を確保してコストを最適化
・計画的な運用が可能
トラフィックが予測可能で、安定しているシステム

コスト削減への3ステップ

ここからが本題です。プロビジョンドモードでコストを最適化するための考え方を、3つのステップで整理しました。

ステップ1:適切なモードを選ぶ

そもそも、自分たちのシステムがプロビジョンドモードに向いているのかを判断する必要があります。
私は、以下のような流れで考えました。

1. データ量は予測可能か?

 No → トラフィックの増減が激しいなら、無理せずオンデマンドモードが安心です。

 Yes → ある程度予測できるなら、次の質問へ。

2. プロビジョンドモードで大きなコストメリットは出るか?

 No → オンデマンドモードと大差ないなら、管理の手間がないオンデマンドモードを選ぶのも手です。

 Yes → 明らかに安くなるなら、次の質問へ。

3. シャード数を調整する運用経験や知見はあるか?

 No → まずはオンデマンドモードで始めて、データ量の傾向を掴んでから移行するのも良い戦略です。

 Yes → プロビジョンドモードに挑戦する価値ありです!

ステップ2:現状のデータ量を把握する

プロビジョンドモードを選ぶと決めたら、次は「じゃあ、どれくらいのデータ量が流れているの?」を正確に知る必要があります。
ここで登場するのが CloudWatch Metrics です。

書き込みデータ量とレコード数を確認する

Kinesisのダッシュボードから、以下の2つのメトリクスを確認します。

  • IncomingBytes: ストリームに書き込まれた合計バイト数
  • IncomingRecords: ストリームに書き込まれた合計レコード数

見る際のポイントは、CloudWatchの設定です。

  • 統計 (Statistic): Sum
  • 期間 (Period): 1 Minute

こうすることで「1分間にどれだけのデータが来たか」が分かります。
そして一番大事なのは、時間範囲 (Time Range)でシステムのトラフィックが最も多いピークタイムを指定することです。閑散期のデータで計算しても意味がありませんからね。

より詳しくは、公式のモニタリングガイドも参考になります。

docs.aws.amazon.com

ステップ3:適正なシャード数を計算する

データ量が分かれば、いよいよシャード数の計算です。
公式ドキュメントにも計算式がありますが、少し複雑なので、ここではもっとシンプルに考えてみましょう。

基本ルールは「書き込みに必要なシャード数」と「読み込みに必要なシャード数」をそれぞれ計算し、最終的に大きい方の数値を採用する、というものです。

公式ドキュメントの計算方法はこちら docs.aws.amazon.com

1. 「書き込み」に必要なシャード数を計算する

シャード1つあたりの書き込み上限は「1MB/秒 または 1,000レコード/秒」です。この上限を超えないように、必要なシャード数を計算します。

  • データ量で計算: ピーク時の秒間書き込みデータ量(MB/秒) ÷ 1MB
    例:「ピーク時に3MB/秒のデータが流れる場合:3MB ÷ 1MB = 3シャード」

  • レコード数で計算: ピーク時の秒間書き込みレコード数 ÷ 1,000
    例:「ピーク時に2,000/秒のレコードが流れる場合:2,000 ÷ 1000 = 2シャード」

この2つを計算して、大きい方の数字を切り上げたものが、書き込みに必要なシャード数です。

2. 「読み込み」に必要なシャード数を計算する

次に読み込み側です。これはコンシューマー(データを読み取るアプリケーション)の種類で考え方が変わります。

標準コンシューマーの場合

1シャードあたりの読み込み上限は「2MB/秒」で、この帯域をすべてのコンシューマーで共有します。 そのため、計算式は以下のようになります。

シャード数 = (ピーク時の秒間書き込みデータ量(MB/秒) × コンシューマーの数) ÷ 2MB
例:「ピーク時に4MB/秒のデータが流れて、コンシューマーの数が3個の場合:4MB × 3 ÷ 2MB = 6シャード」

コンシューマーが多ければ、その分多くのシャードが必要になるわけですね。

拡張ファンアウトコンシューマーの場合

こちらはコンシューマーごとに専用の帯域(最大2MB/秒)が与えられるため、読み込みが原因でシャード数を増やす必要はほとんどありません。
基本的には「書き込み」に必要なシャード数だけ考えればOKです。

最終的なシャード数を決める

これで材料は揃いました。

最終的なシャード数 = MAX ( ①で計算した書き込みシャード数 , ②で計算した読み込みシャード数 )

これで算出されたのが、システムに必要な最低限のシャード数です。
ただし、ここで一つ注意点があります。計算結果ピッタリのシャード数に設定すると、少しトラフィックが増えただけですぐにスロットリング(処理詰まり)が発生してしまいます。

私の経験上、算出したシャード数に20%〜30%程度のバッファ(余裕)を持たせることをお勧めします。将来のデータ増加も見越して、少し余裕のある設計にしておくと、安心して運用できます。

運用しながら最適化する方法

一度計算して設定したシャード数も、永続的に最適とは限りません。
ビジネスの成長や新しい機能の追加によって、システムを流れるデータ量は日々変化するからです。
「一度設定したら終わり」ではなく、継続的に監視し、改善していくことがコスト最適化の鍵となります。

シャード数の最適化

システムの安定運用とコスト効率を両立させるためには、定期的なメンテナンスが不可欠です。
ここでは、日々の運用の中でシャード数を最適に保つための具体的なアクションをご紹介します。

1. CloudWatchメトリクスで健全性を監視する

まず基本となるのが、CloudWatchを使った継続的な監視です。特に以下のメトリクスは、ストリームの健全性を判断する上で非常に重要です。

WriteProvisionedThroughputExceeded (書き込みスロットリング): このメトリクスの値が0より大きい場合、書き込みリクエストが上限を超えて拒否されたことを意味します。定常的に発生するようであれば、シャード数が不足している明確なサインです。

ReadProvisionedThroughputExceeded (読み込みスロットリング): 標準コンシューマーを利用している場合に、読み込みリクエストが上限を超えると発生します。コンシューマーの処理が遅れている原因が、読み込み性能の不足にある可能性を示します。

GetRecords.IteratorAgeMilliseconds (イテレータの経過時間): ストリームに書き込まれたデータが、コンシューマーによって読み取られるまでの遅延時間(ミリ秒)です。この数値が増加し続けている場合、データの処理が追いついていないことを示しており、シャード数の不足やコンシューマー側の処理能力の問題が考えられます。

2. 定期的な見直しと手動でのスケーリング

メトリクスの監視に加え、四半期に一度など、定期的にピークタイムのデータ量を確認し、シャード数を再計算することをお勧めします。
もしシャード数の増減が必要になった場合は、マネジメントコンソールやAWS CLIから手動で変更(リシャーディング)できます。シャードの分割(データ容量とコストが増加)または結合(データ容量とコストが減少)によって、ストリームの容量を調整します。
Kinesis Data Streamsは、リシャーディング中もデータの読み書きを継続できるように設計されています

まとめ

今回はKinesis Data Streamsのコスト最適化について、シャード数の計算方法を中心に解説しました。最後に重要なポイントを振り返ります。

  • まずはトラフィックの特性を理解し、オンデマンドかプロビジョンドか最適なモードを選択することが第一歩。
  • プロビジョンドモードでは、CloudWatchメトリクスでピーク時のデータ量を正確に把握することが不可欠。
  • シャード数は「書き込み」と「読み込み」で必要な数をそれぞれ計算し、大きい方を採用する。
  • 計算値ピッタリではなく、20〜30%のバッファを持たせることで安定運用につながる。
  • 一度設定して終わりではなく、継続的にメトリクスを監視し、定期的に見直すことがコスト最適化の鍵。