スループット向上のために Azure Stream Analytics ジョブをスケーリングする

この記事では、Stream Analytics クエリをチューニングして、Streaming Analytics ジョブのスループットを向上させる方法について説明します。 次のガイドを使用して、高い負荷を処理し、より多くのシステム リソース (より多くの帯域幅、より多くの CPU リソース、より多くのメモリなど) を利用するようにジョブをスケーリングできます。

前提条件として、以下の記事に目を通してください。

ケース 1 - 複数の入力パーティションでクエリが本質的に完全並列化可能な場合

入力のパーティション間でクエリが本質的に完全並列化可能な場合は、次の手順に従うことができます。

  • PARTITION BY キーワードを使用して、クエリを驚異的並列として作成します。 詳細については、「Azure Stream Analytics でのクエリの並列処理の使用」を参照してください。
  • クエリで使用される出力の種類によっては、出力を並列化できなかったり、驚異的並列とするためには追加の構成が必要となる可能性があります。 たとえば、Power BI の出力は並列化できません。 出力は、出力シンクに送信する前に常にマージされます。 BLOB、テーブル、Azure Data Lake Storage、Service Bus、Azure 関数は自動的に並列化されます。 SQL と Azure Synapse Analytics の出力には、並列化のオプションがあります。 イベント ハブでは、PartitionKey 構成を PARTITION BY フィールド (通常は PartitionId) と一致するように設定する必要があります。 Event Hubs の場合は、パーティション間でのクロスオーバーを回避するために、すべての入力とすべての出力でパーティション数を一致させることにも注意してください。
  • 1 ストリーミング ユニット (SU) V2 (1 つのコンピューティング ノードの全容量) でクエリを実行して、達成可能な最大スループットを測定します。GROUP BY を使用する場合は、ジョブでいくつのグループを処理できるか (カーディナリティ) を測定します。 ジョブがシステム リソース制限に達した場合の一般的な症状は次のとおりです。
    • ストリーミング ユニット (SU) % 使用率メトリックが 80% を超えている。 これは、メモリ使用率が高いことを意味します。 このメトリックの増加に寄与する要因については、「Stream Analytics ストリーミング ユニットの理解と調整」で説明されています。
    • 出力タイムスタンプが実時間よりも遅れている。 クエリ ロジックによっては、出力タイムスタンプは、実際の時間から論理オフセットの分ずれている場合があります。 ただし、それらはほぼ同じ速度で進行します。 出力タイムスタンプの遅れが徐々に増加している場合は、システムが過負荷になっていることを示しています。 ダウンストリーム出力のシンク調整、または高 CPU 使用率の結果である可能性があります。 現時点では CPU 使用率のメトリックを提供していないため、2 つを区別するのは困難な可能性があります。
      • 問題の原因がシンク調整の場合は、出力パーティション数を増やす (ジョブを完全並列化できるようにするためには入力パーティション数も増やす) か、シンクのリソースの量 (たとえば、Cosmos DB の要求ユニット数など) を増やす必要があります。
    • ジョブ ダイアグラムには、各入力について、パーティションごとのバックログ イベント メトリックが存在します。 バックログ イベント メトリックが増加し続ける場合も、(出力シンクの調整または高い CPU 使用率が原因で) システム リソースが制約されていることを示しています。
  • 1 SU V2 のジョブが到達できる上限を確認したら、特定のパーティションを "ホット" にする何らかのデータ スキューがないことを前提として、SU を追加する際のジョブの処理容量を線形に外挿することによって推定できます。

Note

適切なストリーミング ユニット数の選択: Stream Analytics は、1 SU V2 が追加されるごとに処理ノードを作成するため、ノード数を入力パーティション数の約数にして、パーティションがノードに均等に分散されるようにすることが推奨されます。 たとえば、1 SU V2 ジョブが 4 MB/秒の処理速度を達成できることがわかっており、入力パーティション数は 4 であるとします。 約 8 MB/秒の処理速度を達成するには 2 SU V2 を、16 MB/秒を達成するには 4 SU V2 を選択しジョブを実行します。 入力速度の関数として、ジョブの SU 数をいつどのような値に増やすかを決定できます。

ケース 2 - クエリが驚異的並列でない場合。

クエリが驚異的並列でない場合は、以下の手順に従うことができます。

  • まず PARTITION BY を指定しないでクエリを開始してパーティション分割の複雑さを回避し、次にケース 1 と同様に1 SU V2 でクエリを実行して最大負荷を測定します。
  • スループットについて予想される負荷を達成できていれば完了です。 または、同じジョブの実行を、2/3 SU V2 と 1/3 SU V2 という分数ノードで測定して、シナリオに合ったストリーミング ユニットの最小数を調べることもできます。
  • 目的のスループットを達成できない場合で、クエリがまだ複数ステップに分割されていない場合は、可能であればクエリを複数のステップに分割し、クエリの各ステップに最大 1 SU V2 を割り当てます。 たとえば、3 つのステップがある場合は、"スケール" オプションで 3 SU V2 を割り当てます。
  • このようなジョブを実行する場合、Stream Analytics は、各ステップを専用の 1 SU V2 リソースを持つ独自のノードに配置します。
  • 負荷ターゲットをまだ達成していない場合は、入力により近いステップから開始して PARTITION BY を使用してみます。 そのままではパーティション分割できない GROUP BY 演算子では、ローカル/グローバル集計パターンを使用して、パーティション分割された GROUP BY に続けてパーティション分割されていない GROUP BY を実行できます。 たとえば、3 分ごとに各料金所を通過する自動車の数をカウントしたい場合、そのデータ量は 1 SU V2 で処理できる量を超えます。

クエリ:

WITH Step1 AS (
SELECT COUNT(*) AS Count, TollBoothId, PartitionId
FROM Input1 Partition By PartitionId
GROUP BY TumblingWindow(minute, 3), TollBoothId, PartitionId
)
SELECT SUM(Count) AS Count, TollBoothId
FROM Step1
GROUP BY TumblingWindow(minute, 3), TollBoothId

このクエリでは、パーティションごとに各料金所の自動車をカウントしてから、すべてのパーティションのカウントを合計します。

パーティション分割されたら、ステップの各パーティションに 1 SU V2 を割り当てて、各パーティションを独自の処理ノードに配置できるようにします。

Note

クエリがパーティション分割できない場合は、複数ステップ クエリで SU を追加しても、常にスループットが向上するとは限りません。 パフォーマンスを向上させる 1 つの方法は、手順 5 で説明したようにローカル/グローバル集計パターンを使用して初期ステップでの量を削減することです。

ケース 3 - 単一ジョブで大量の独立したクエリを実行している場合。

1 つのジョブで複数のテナントのデータを処理する方がコスト効果が高い ISV ユース ケースでは、テナントごとに個別の入力と出力を使用すると、1 つのジョブ内で実行する独立したクエリがかなり多い数 (20 など) になってしまいます。 このような各サブクエリの負荷が比較的少ないことが前提です。

このような場合は、以下の手順を実行できます。

  • この場合、クエリでは PARTITION BY を使用しないでください
  • Event Hubs を使用している場合は、入力パーティション数を最小値の 2 に減らします。
  • 1 SU V2 でクエリを実行します。 各サブクエリで予想される負荷で、ジョブがシステム リソースの制限に達するまで、できるだけ多くのサブクエリを追加します。 この状況が発生した場合の症状については、「ケース 1」を参照してください。
  • 測定がサブクエリの上限に達したら、サブクエリを新しいジョブへ追加することを開始します。 負荷の傾斜がないと仮定した場合、独立したクエリの数の関数として実行するジョブの数は、かなり線形になります。 その後、サービスを提供したいテナントの数の関数として、実行する必要がある SU V2 ジョブの数を予測できます。
  • このようなクエリで参照データ結合を使用する場合は、同じ参照データで結合する前に入力を統合します。 そのうえで、必要に応じてイベントを分割してください。 そうしないと、各参照データ結合がメモリに参照データのコピーを保持し、メモリ使用量が不必要に増加する可能性があります。

注意

各ジョブにはいくつのテナントを配置しますか。 このクエリ パターンでは、多くの場合、サブクエリの数が多くなり、非常に大規模で複雑なトポロジになることがあります。 ジョブのコントローラーは、このような大規模トポロジを処理できないことがあります。 経験的には、1/3 SU V2 ジョブでは 40 テナント未満、2/3 および1 SU V2では 60 テナント未満にします。 コントローラーの容量を超過していると、ジョブは正常に開始しません。

ヘルプの参照

詳細については、Azure Stream Analytics に関する Microsoft Q&A 質問ページを参照してください。

次のステップ