Azure Queue StorageとAzure Service Busを比較してみた
Azureで非同期処理を実装する必要があり、Queue StorageとService Busを比較しました。 メッセージの順序保証と消失回避をガチで追求するService Busは考慮すべき事項が大量にあり、 そういう要件がないのであればQueue Storageを使うと楽になることが分かりました。 [arst_toc tag=\"h4\"] 非同期要求-応答パターン アーキテクチャセンターという場所で、Azure全体で検討すべき設計パターンが公開されています。 その中に、非同期要求-応答パターンという項目があります。Azure Functionのドキュメントの中でも、 タイムアウトしそうな長時間処理を実装するならこのパターンにすると良いよ、と説明されています。 HTTPトリガによってキューイングサービスであるAzure Service Busにキュー登録し、 Azure Service Busトリガによって裏で非同期処理を実行する、というものですね。 非同期要求-応答パターン - アーキテクチャセンター シーケンス図がわかりやすいです。 シーケンス図 アプリケーションとジョブ実行機能を疎結合にしたい、という意図がチラチラ見えます。 実際、そこまで疎結合しないのであれば、アプリケーションに統合してしまう作りもあるかと思います。 密結合で良ければ、キュー登録もステータス監視もアプリケーションでやれますので大分シンプルです。 キュー登録、状態監視は非同期処理のコアではなく、コアは以下なのだろうと思います。 キューに積む側が即時応答できること 積まれたトリガで開始する重い処理を分離できること Service BusとQueue Service Azureにはキューを実現する仕組みが2つあります。 厳密にはキューイングサービスはService Busだけですが、ストレージアカウントの1機能である Queue Storageが\"キューそのもの\"であって、よりシンプルにキュー機能を作ることができます。 Azure Queue Storage Service Bus Service Busは、メッセージを決して消失させないガチのキューイングサービスで、 それを実現するために考慮すべき点が大量にあります。順序や消失の対応に命をかけるのでなければ 単なるストレージであるQueue Storageを使った方が気楽です。 両者の機能比較 Queue StorageとService Busの違いについて、公式ドキュメントから拾い集めて表にしました。 ちょっと理解が難しい部分があったので、だいぶ憶測と妄想で補足しています。 (下の方は読み取れず諦めたところがあります..) もともと全然違うサービスなのに比較しようとするから、表の対応が取れない、という問題があります。 公式を読んでもいまいち対応が取れないのは、そもそも機能が違うから、なのだろうと思います。 Storageキュー Service Busキュー 特徴 シンプル。ストレージ容量で課金。単一の送信先(非Pub/Sub)。トランザクション無し。メッセージ内容の更新可。重複検出無し。 多機能。トランザクション有り。1対1に加え多対多(Pub/Sub)が可。メッセージ内容の更新不可。重複検出あり。トピックフィルタあり。 順序の保証 なし一般にFIFOだが状況によって順序が変わる FIFO、セッションIDによるグルーピング(セッション)と同一セッション内の送信順序保持。 転送・ロック・解決 Peek & Lease受信者から「読み出す(Peek)」要求があった場合に他の受信者に該当のメッセージ読み取らせないようにする。(Lease) Peek/Lockモード送信者がブローカー(Service Bus)に送信し受信者の受信が成功/失敗分かって初めて解決とする。メッセージにロックがかかり競合受信者が触れなくなる。送りっぱなし・非同期にしてはいけない。Receive/Deleteモードブローカーが受信者に送信した時点で解決とする。受信者による受信の成功/失敗には関与しない。受信に失敗するとメッセージは失われる。 配信不能キュー(DLQ) 有害キュー。対応する記事がないが、受信に失敗すると特殊なキューが作られてそこに入った。 配信不能レタリング 配信保証 At-Least-Once少なくとも1回。つまり1回は確実に配信されるが、重複(2回以上同じメッセージ)がありうる。 At-Least-Once(PeekLockの場合)少なくとも1回。つまり1回は確実に配信されるが、重複(2回以上同じメッセージ)がありうる、損失なしAt-Most-Once(ReceiveAndDeleteの場合)最大1回。つまり0回=配信されないことがある。重複はない。 トランザクション 非対応 対応 重複検出 非対応 対応 プロトコル HTTP/HTTPS (RESTベース) HTTPS (RESTベース) メッセージサイズ 最大64KB 256 KB または 100 MB メッセージの最大TTL 無限 有限(TimeSpan.MaxValue??) 処理数 最大2000メッセージ/秒 (1KBの場合) (省略) キューサイズ 最大500TB 1 GB ~ 80 GB キューの最大数 無限 10,000 メッセージ保存期間 最大7日 (省略) どちらを使うべきか 公式では、以下が必要な場合はService Busを使うべしとされています。 不要ならStorage Queueとなります。だいたい、あるなら使いたいとなりがちな気がしますが、 そうするとService Busになってしまいます。 扱いやすいStorage Queueを使うなら「必要ではない」を判断する必要があります。 メッセージセッション(FIFO) トランザクション 重複検出 自動的な配信不能レタリング Pub/Sub azure-storage-queueの動作確認 Azure Storage Queueを操作するパッケージは、azure-storage-queueです。 クイックリファレンスによると、以下の機能をサポートしています。 キューを作成する メッセージをキューに追加する キュー内のメッセージを表示する キュー内のメッセージを更新する キューの長さを取得する キューからメッセージを受信する キューからメッセージを削除する キューを削除する 対して、Service Busを操作するパッケージは、azure-servicebusです。 azure-storage-queueのように簡単に機能リストをまとめることはできないため省略。 抽象化のレベルが違うので、これだけでも面倒さが分かります。 まとめ Storage QueueとService Busを比較し、まとめてみました。 次回はFunctionsのStorage Queueトリガ/バインドを使って非同期処理を書いてみます。