優先キュー パターン

ワークロードが優先度の高い要求を優先順位の低い要求よりも迅速に処理できるように、サービスに送信される要求に優先順位を付けます。 この方法では、1 つ以上のキューに送信されるメッセージを使用します。これは、さまざまな要求の種類または顧客に対して異なるサービス レベルまたはサービス レベル アグリーメント (SLA) を提供するアプリケーションに役立ちます。

コンテキストと問題

ワークロードでは、さまざまなレベルの重要度と緊急度でタスクを管理および処理することが必要になる場合があります。 早急な対応が必要なタスクもあれば、後回しにできるタスクもあります。 優先度の高いタスクに対処できないと、ユーザー エクスペリエンスと違反 SLA に影響を与える可能性があります。

優先順位に基づいてタスクを効率的に処理するには、ワークロードに応じてタスクを処理して実行するメカニズムが必要です。 既定では、ほとんどのワークロードは、先入れ先出し (FIFO) キュー構造を使用して、到着順にタスクを処理します。 このアプローチでは、さまざまなタスクの重要度は考慮されません。

解決策

優先順位キューを使用すると、ワークロードは到着順序ではなく、優先順位に基づいてタスクを処理できます。 要求を送信するアプリケーションまたは プロデューサー は、メッセージに優先順位の値を割り当て、 コンシューマー は優先順位でメッセージを処理します。 優先順位キュー パターンは、次の要件に対応します。

  • さまざまな緊急性と重要度のタスクを処理します。 緊急度と重要度が異なるタスクがあり、重要度の低いタスクの前に、より重要なタスクを確実に処理する必要があります。

  • さまざまな SLA を処理します。 さまざまな顧客に異なる SLA を提供し、優先度の高い顧客がより優れたパフォーマンスと可用性を得られるようにする必要があります。

  • さまざまなワークロード管理ニーズに対応します。 緊急性の低いタスクが待機できる間、特定のタスクにすぐに対処する必要があるワークロードがあります。

プライオリティキュー パターンを実装するには、2 つの主な方法があります。

  • 単一キュー: 各メッセージには優先順位の値が割り当てられ、すべてのメッセージは同じキューを使用します。

  • 複数のキュー: 各メッセージには優先順位の値が割り当てられ、異なる優先順位のメッセージでは個別のキューが使用されます。

単一キュー

1 つのキューアプローチでは、アプリケーションは各メッセージに優先順位を割り当て、すべてのメッセージを 1 つのキューに送信します。 キューは優先度に基づいてメッセージを並べ替え、コンシューマーが高優先度のメッセージを低優先度のメッセージよりも先に処理するようにします。

メッセージの優先順位付けをサポートするキュー メカニズムを示す図。

複数のキュー

複数のキューが優先順位によってメッセージを分離します。 アプリケーションは各メッセージに優先順位を割り当て、その優先順位に対応するキューにメッセージを送り、コンシューマーがメッセージを処理します。 複数キュー ソリューションでは、1 つのコンシューマー プールまたは複数のコンシューマー プールを使用できます。

単一コンシューマー プール

1 つのプールセットアップでは、すべてのキューが同じコンシューマー プールを共有します。 コンシューマーは、優先順位の高いキューからのメッセージを最初に処理し、優先順位の低いキューからのメッセージを処理するのは、優先順位の高いメッセージがなくなった場合のみです。 その結果、単一コンシューマー プールは常に優先順位の高いメッセージの前に優先順位の高いメッセージを処理します。 このセットアップにより、優先順位の低いメッセージが継続的に遅延し、処理されない可能性があります。

すべての優先順位に対して 1 つのコンシューマー プールを使用する方法を示す図。

次の理由から、1 つのコンシューマー プールを使用します。

  • シンプルな管理。 簡単なセットアップとメンテナンスが優先される場合は、1 つのコンシューマー プールを使用します。 1 つのプールにより、構成と監視の複雑さが軽減されます。

  • 統合処理のニーズ。 受信タスクの種類が似ている場合は、1 つのコンシューマー プールを使用します。

複数コンシューマープール群

複数のコンシューマー プールでは、各キューに専用のコンシューマー プールがあります。 優先順位の高いキューでは、優先順位の低いキューよりも高速にメッセージを処理するために、より多くのコンシューマーまたは高いパフォーマンスレベルが使用されます。

優先順位ごとに個別のコンシューマー プールを使用する方法を示す図。

次の理由から、複数のコンシューマー プールを使用します。

  • 厳密なパフォーマンス要件。 異なるタスクの優先順位に個別に満たす必要がある厳密なパフォーマンス要件がある場合は、複数のコンシューマー プールを使用します。

  • 信頼性の高いニーズ。 信頼性と障害の分離が重要であり、1 つのキューの問題が他のキューに影響を与えてはならない場合は、アプリケーションに複数のコンシューマー プールを使用します。

  • 複雑なアプリケーション。 さまざまなタスクで異なる処理特性とパフォーマンスの保証が必要な複雑なアプリケーションには、複数のコンシューマー プールを使用します。

問題と考慮事項

このパターンの実装方法を決めるときには、以下の点に注意してください。

一般的な推奨事項

  • 優先度を明確に定義する。 ソリューションに関連する明確で明確な優先度レベルを確立します。 たとえば、優先度の高いメッセージを、10 秒以内に処理を必要とするメッセージとして定義できます。 優先度の高い項目を処理するためのコンシューマー要件を特定し、それに応じて必要なリソースを割り当てます。

  • コンシューマー プールを動的に調整する。 コンシューマー プールのサイズを、処理しているキューの長さに応じて調整します。

  • キューの正常性を監視します。 キューの深さ、処理待ち時間、配信数、スループットを追跡して、バックログと速度低下を検出してから作業に影響を与えることができます。

  • デッドレター キューを使用してください。 1 つの不適切なメッセージが優先度パスをブロックしないように、構成可能な数の配信試行の後に 有害 メッセージを配信不能キューに移動します。

  • サービス レベルに優先度を付ける。 可用性やパフォーマンスの優先度付けが求められるビジネス ニーズを満たすように Priority Queue を実装する。 たとえば、優先度の高い顧客は、より高いサービス レベルを受け取ることができ、パフォーマンスと可用性が向上します。

  • 優先順位の低い処理を検討してください。 優先度の低い項目の前にすべての優先度の高い項目を処理する必要があるかどうかを決定します。 可能であれば、古いメッセージの優先順位を動的に上げて、優先順位の低いメッセージが最終的に処理されるようにします。

  • コストを最適化して最小限に抑えます。 利用可能なコンシューマーで重要なタスクをすぐに処理する。 低重要度のバックグラウンド タスクはあまり忙しくない時間帯にスケジュールします。

    1 つのキューを使用する場合は、コンシューマーの数をスケールバックしてコストを最適化します。 優先度の高いメッセージは最初に処理されますが、処理速度が遅くなる可能性がありますが、優先順位の低いメッセージは長い遅延に直面する可能性があります。

  • 需要のピークからプロセッサを保護します。 プロデューサー到着率がコンシューマーの処理能力を超える可能性がある場合は、このパターンを Queue-Based 負荷平準化パターンと組み合わせます。 このアプローチは、トラフィック バーストをバッファーに入れ、ダウンストリーム処理リソースの過負荷を防ぐのに役立ちます。

複数のキューに関する推奨事項

  • 処理速度を監視する。 メッセージが予想される速度で確実に処理されるようにするには、優先度の高いキューと優先順位の低いキューの処理速度を継続的に監視します。

  • 先取りと中断を実装する。 1 つのコンシューマー プールで複数のキューを使用する場合は、優先順位の高いキューが優先順位の低いキューより前に常に処理されるようにするアルゴリズムを実装します。

  • キューのコストを考慮する。 キューのチェックと処理に関連する財務コストに注意してください。 一部のキュー サービスでは、メッセージの投稿、取得、クエリに対する料金が課金されます。 これらの料金は、キューの数に応じて増加する可能性があります。

このパターンを使用する場合

このパターンは次の状況で使用します。

  • Premium と Standard のお客様の要求など、さまざまな作業クラスに対して異なる待機時間またはサービス レベルの目標を満たす必要があります。

  • 作業はバーストで到着します。優先順位の低い作業を延期しながら、優先度の高いメッセージを最初に処理して重要な操作を保護する必要があります。

このパターンは、次の場合に適さない場合があります。

  • すべての作業項目のビジネス上の重要度は似ていますが、厳密な FIFO 処理は優先度ベースのスケジューリングよりも重要です。

  • タスクには優先度レベル間で強い順序付け依存関係があり、優先順位に従って作業を並べ替えると、結果が矛盾したり、複雑な調整ロジックが必要になる可能性があります。

ワークロード設計

ワークロードの設計で Priority Queue パターンを使用して、Azure Well-Architected Framework の柱で説明されている目標と原則に対処する方法を評価します。 次の表は、このパターンが各柱の目標をサポートする方法に関するガイダンスを示しています。

このパターンが柱の目標をサポートする方法
信頼性 設計の決定により、ワークロードが 誤動作 に対して復元力を持ち、障害発生後も完全に機能する状態に 回復 することができます。 ビジネスの優先順位に基づいて項目が分離されるため、信頼性への取り組みを最も重要な作業に集中させることができます。

- RE:02 重要な流れ
パフォーマンス効率 は、スケーリング、データ、およびコードの最適化を通じて、ワークロード の需要を効率的に満たすのに役立ちます。 ビジネスの優先順位に基づいて項目が分離されるため、パフォーマンスへの取り組みを、時間的制約が最も厳しい作業に集中させることができます。

- PE:09 クリティカルフロー

このパターンによって柱内にトレードオフが生じる場合は、他の柱の目標に照らして検討してください。

GitHubの Priority Queue パターンの例は、Azure Service Busトピックとサブスクリプションを使用する Priority Queue パターンの実装を示しています。 この例では、セキュリティで保護されたストレージ アカウント、監視用の Application Insights リソース、および送信者とコンシューマー関数の間の通信を可能にするService Bus名前空間をデプロイします。

デプロイには、送信者 1 つとコンシューマー 2 つで構成される 3 つの関数アプリが含まれています。 コンシューマー アプリでは、メッセージの優先順位付けをシミュレートするために、異なる最大インスタンス数が使用されます。 funcPriorityQueueConsumerHigh関数は 200 インスタンスにスケールアウトできますが、funcPriorityQueueConsumerLow関数は 40 インスタンスに制限されています。 すべての関数アプリは Flex 従量課金プランを使用し、診断と監視のために Application Insights に接続されます。

ロールの割り当てにより、マネージド ID を使用してService Busとストレージへのセキュリティで保護されたアクセス権が付与されます。 すべての関数アプリは、同じストレージ アカウントと Application Insights リソースを共有します。 この構成により、可観測性とログ記録が一元化されます。

次の図は、優先順位キューのアーキテクチャを示しています。

Service Busを使用して優先順位キューを実装する方法を示す図。

前の図で:

  1. アプリケーション(生成元) PriorityQueueSender アプリケーションは、メッセージを作成し、各メッセージに Priority という名前のカスタム アプリケーション プロパティを割り当て、Priority値をHighまたはLowに設定します。

  2. メッセージブローカーとトピック。 Service Bus メッセージ ブローカーは、messagesという名前の 1 つのService Bus トピックにメッセージを送信します。 Service Busでは、SQL フィルターを使用して、Priority値に基づいて、各メッセージを優先度の高いサブスクリプションまたは優先順位の低いサブスクリプションにルーティングします。

  3. 複数のコンシューマー群。 PriorityQueueConsumerHighおよびPriorityQueueConsumerLowコンシューマー プールは、Azure Functions Service Bus トリガーを使用して、優先度の高いサブスクリプションまたは優先順位の低いサブスクリプションからのメッセージに応答します

例における役割 Azureサービスの例 例における名前
アプリケーション (プロデューサー) Azure Functions アプリ PriorityQueueSender (優先度キュー送信者)
メッセージ ブローカー Azure Service Bus <お客様の Service Bus 名前空間>
メッセージ トピック Azure Service Bus トピック messages
メッセージ サブスクリプション Azure Service Bus サブスクリプション highPriority
lowPriority
コンシューマー Azure Functions アプリ プライオリティキューコンシューマハイ
プライオリティ キュー コンシューマロー

次のステップ

このパターンを実装する場合は、次のパターンが役立つ場合があります。

  • Queue-Based 負荷平準化パターン: 要求の取り込みと処理の間のバッファーとしてキューを使用します。 バースト保護と区別された処理の両方が必要な場合は、優先度キュー パターンと共に使用します。

  • 競合コンシューマー パターン: スループットを向上させるために、同じキューとプロセス タスクを並列でリッスンする複数のコンシューマーを実装します。 各メッセージは 1 つのコンシューマーのみが処理します。

  • 調整パターン: キューを使用して要求レートを管理することで調整を実装します。 優先度の高いメッセージングを使用して、重要度の低いアプリケーションや価値の高い顧客からの要求に優先順位を付けます。