Priority Queue パターンにより、ワークロードは低優先度のタスクよりも高優先度のタスクをより迅速に処理できます。 このパターンは、1 つ以上のキューに送信されるメッセージを使用し、クライアント別に異なるサービス レベルを担保するアプリケーションで役立ちます。
コンテキストと問題
ワークロードは、多くの場合、さまざまな重要度と緊急度のタスクを管理および処理する必要があります。 早急な対応が必要なタスクもあれば、後回しにできるタスクもあります。 高優先度のタスクに対処できないと、ユーザー エクスペリエンスに影響し、サービス レベル アグリーメント (SLA) に違反する可能性があります。
優先度に基づいてタスクを効率的に処理するために、ワークロードにはタスクを優先度付けし、それに応じて実行するメカニズムが必要です。 通常、ワークロードは先入れ先出し (FIFO) キュー構造を使用して、タスクを到着順に処理します。 この方法では、タスクの重要性の違いが考慮されません。
解決策
Priority Queue により、ワークロードは到着順ではなく優先度に基づいてタスクを処理できます。 キューにメッセージを送信するアプリケーションがメッセージに優先度を割り当て、コンシューマーは優先度順にメッセージを処理します。 Priority Queue パターンを使用するのは、次のような要件がある場合です。
さまざまな重要度と緊急度のタスクを管理および処理する。 さまざまな緊急度や重要度のタスクがあり、重要度の低いタスクよりも重要度の高いタスクを優先して処理する必要がある場合です。
さまざまなサービス レベル アグリーメントを処理する。 クライアントごとに異なるサービス レベルを担保することで、高優先度のクライアントがより良いパフォーマンスと可用性を受けられるようにする必要がある場合です。
さまざまなワークロード管理のニーズに対応する。 特定のタスクにすぐに対応する必要があり、緊急度の低いタスクは後回しにできるワークロードがある場合です。
Priority Queue キュー パターンを実装するには、主に 2 つの方法があります。
単一キュー: すべてのメッセージが 1 つのキューに送信され、各メッセージに優先度が割り当てられます。
複数のキュー: メッセージの優先度ごとに個別のキューが使用されます。
単一キュー
単一キューでは、アプリケーション (プロデューサー) が各メッセージに優先度を割り当て、メッセージをキューに送信します。 キューは優先度に基づいてメッセージを並べ替え、コンシューマーが高優先度のメッセージを低優先度のメッセージよりも先に処理するようにします。
図 1. 単一キューと単一コンシューマー プールのアーキテクチャ
複数のキュー
複数のキューを使用すると、優先度に基づいてメッセージを分けることができます。 アプリケーションは各メッセージに優先度を割り当て、その優先度に対応するキューにメッセージを振り分けます。 コンシューマーはメッセージを処理します。 複数キュー ソリューションは単一コンシューマー プールまたは複数コンシューマー プールを使用します。
複数コンシューマー プール
複数コンシューマー プールでは、各キューに専用のコンシューマー リソースがあります。 高優先度のキューは、低優先度のキューよりも迅速にメッセージを処理するために、より多くのコンシューマーや高いパフォーマンス レベルを使用する必要があります。
複数コンシューマー プールを使用するのは、次のような場合です。
- パフォーマンス要件が厳格: タスクの優先度ごとのパフォーマンス要件が厳格な場合は、複数コンシューマー プールが必要です。
- 高信頼性が必要: 信頼性と障害の分離が重要なアプリケーションでは、複数コンシューマー プールが必要です。 1 つのキューの問題が他のキューに影響を与えてはならない。
- アプリケーションが複雑: タスクごとに異なる処理特性やパフォーマンス担保を必要とする複雑なアプリケーションに役立ちます。
図 2. 複数キューと複数コンシューマー プールのアーキテクチャ。
単一コンシューマー プール
単一コンシューマー プールでは、すべてのキューが 1 つのコンシューマー プールを共有します。 コンシューマーは、最高優先度のキューからのメッセージを最初に処理し、低優先度のキューからのメッセージは、高優先度のメッセージがない場合にのみ処理します。 その結果、単一コンシューマー プールは常に、低優先度のメッセージよりも高優先度のメッセージを先に処理します。 この設定により、低優先度のメッセージが継続的に遅延し、場合によっては処理されない可能性があります。
単一コンシューマー プールを使用するのは、次のような場合です。
- 管理がシンプル: 単一コンシューマー プールは、設定とメンテナンスの容易さが優先されるアプリケーションに適しています。 構成と監視の複雑さが軽減されます。
- 統一された処理が必要: 単一コンシューマー プールは、受信タスクの性質が似ている場合に役立ちます。
図 3。 複数キューと単一コンシューマー プールのアーキテクチャ。
Priority Queue キュー パターンの推奨事項
Priority Queue キュー パターンの実装方法を決定する際は、以下の推奨事項を考慮してください。
一般的な推奨事項
優先度を明確に定義する。 ソリューションに関連する明確で区別された優先度を設定する。 たとえば、高優先度のメッセージは 10 秒以内に処理することが必要になる場合があります。 高優先度の項目を処理するための要件を特定し、それに応じて必要なリソースを割り当てる。
コンシューマー プールを動的に調整する。 サービスするキューの長さに基づいてコンシューマー プールのサイズをスケールする。
サービス レベルに優先度を付ける。 可用性やパフォーマンスの優先度付けが求められるビジネス ニーズを満たすように Priority Queue を実装する。 たとえば、顧客グループごとに異なるレベルのサービスを提供することで、高優先度の顧客がより良いパフォーマンスと可用性を受けられるようにします。
低優先度の処理が確実に行われるようにする。 メッセージの優先度付けをサポートするキューでは、システムで許可されていれば、古いメッセージの優先度を動的に上げて、最終的に低優先度のメッセージが処理されるようにします。
キューのコストを考慮する。 キューの確認に関連する金銭的コストと処理コストを認識してください。 一部のキュー サービスでは、メッセージの投稿、取得、クエリに料金がかかり、キューの数が増えるとコストが増加する可能性があります。
複数のキューの推奨事項
処理速度を監視する。 メッセージが期待どおりの速度で処理されることを確認するために、高優先度と低優先度のキューの処理速度を継続的に監視します。
コストを最小限に抑える。 利用可能なコンシューマーで重要なタスクをすぐに処理する。 低重要度のバックグラウンド タスクはあまり忙しくない時間帯にスケジュールします。
単一コンシューマー プールの推奨事項
先取りと中断を実装する。 高優先度の項目から順番に処理していく必要があるかどうかを決定します。 複数のキューが 1 つのコンシューマー プールを使用する場合、高優先度のキューが常に低優先度のキューよりも先にサービスされるようなアルゴリズムを使用します。
コストの最適化。 単一キューによる方法を使用する場合は、コンシューマーの数を減らして運用コストを最適化します。 高優先度のメッセージは、処理速度が遅くなる可能性がありますが、先に処理されます。一方、低優先度のメッセージは、さらに遅延する可能性があります。
ワークロード設計
設計者は、Azure Well-Architected Framework の柱で説明されている目標と原則に Priority Queue パターンがどのように対応できるかを評価する必要があります。 次に例を示します。
重要な要素 | このパターンが柱の目標をサポートする方法 |
---|---|
信頼性 設計の決定により、ワークロードが 誤動作 に対して 復元力 を持ち、障害発生後も完全に機能する状態に 回復 することができます。 | ビジネスの優先順位に基づいて項目が分離されるため、信頼性への取り組みを最も重要な作業に集中させることができます。 - RE:02 クリティカルフロー - Re: 07バックグラウンドジョブ |
パフォーマンスの効率化 は、スケーリング、データ、コードを最適化することによって、ワークロードが 効率的にニーズを満たす のに役立ちます。 | ビジネスの優先順位に基づいて項目が分離されるため、パフォーマンスへの取り組みを、時間的制約が最も厳しい作業に集中させることができます。 - PE:09 クリティカルフロー |
設計決定と同様に、このパターンで導入される可能性のある他の柱の目標とのトレードオフを考慮してください。
Priority Queue パターンの例
GitHub の次の例では、Azure Service Bus を使用した Priority Queue パターンの実装を示しています。
図 4 GitHub の PriorityQueue 例のアーキテクチャ
アーキテクチャの概要を次に示します。
アプリケーション (プロデューサー): この例では、メッセージを作成し、各メッセージに
Priority
という名前のカスタム プロパティを割り当てるアプリケーション (PriorityQueueSender
) があります。Priority
の値は、High
またはLow
です。メッセージ ブローカーとキュー: この例では、Azure Service Bus をメッセージ ブローカーとして使用しています。 メッセージの優先度 (
High
とLow
) ごとに 2 つの Azure Service Bus キューを使用します。 アプリケーション (プロデューサー) は、メッセージの優先度に基づいて適切なキューにメッセージPriority
を送信します。複数コンシューマー プール: この例では、各キューからメッセージを読み取る専用の複数コンシューマー プール (
PriorityQueueConsumerHigh
とPriorityQueueConsumerLow
) を使用しています。
アーキテクチャの例における役割 | 例における Azure サービス | 例における名前 |
---|---|---|
アプリケーション | Azure Functions アプリ | PriorityQueueSender |
メッセージ キュー ブローカー | Azure Service Bus | <実際の Service Bus 名前空間> |
メッセージ キュー | Azure Service Bus キュー | <実際のキュー名> |
使用者 | Azure Functions アプリ | PriorityQueueConsumerHigh PriorityQueueConsumerLow |
関連リソース
このパターンを実装する場合、次のパターンが役立つ可能性があります。
競合コンシューマー パターン: このパターンでは、同じキューをリッスンする複数のコンシューマーを実装し、スループットを向上させるために並行してタスクを処理します。 各メッセージは 1 つのコンシューマーのみが処理します。 この記事では、この方法の利点と欠点について詳しく説明しています。
調整パターン: このパターンは、要求の処理速度を管理するためにキューを使用して実装できます。 優先度によるメッセージングを利用することで、重要なアプリケーションや高価値の顧客からの要求を低重要度の要求よりも優先させることができます。