クラウド メッセージング/キュー比較解説まとめ

  • このエントリーをはてなブックマークに追加

本ページでは、Amazon・Microsoft・Google の提供するメッセージング・キューサービスの機能・料金等について比較します。具体的には下記サービスを対象とします。

  • Amazon Simple Queue Service (SQS)
  • Amazon Simple Notification Service (SNS)
  • Amazon MQ
  • Azure Queue Storage
  • Azure Service Bus
  • Google Cloud Pub/Sub
  • Google Task Queue

※Amazon Kinesis を含めていないですが、そのうち追加したいと思っています。

目次

メッセージング・キューサービスの使い所

メッセージング・キューサービスは、使っていない人にとっては必要性がわかりづらい概念だと思います。まずはどこで使うのか、何がうれしいのかを説明します。

端的に言うと「あるプログラムがキューにメッセージを送信し、それを別のプログラムで受信することができるもの」です。 プログラム視点で言うと、「処理Aの後に処理Bを実行する」という場合に、間にメッセージング・キューサービスを挟むわけです。

典型的な使い所としては、処理A の後に処理B が動くという前提で、

  • 処理A と処理B のつながりを疎結合にしたい場合
    • 処理A と 処理B が別サーバで行われるため、疎結合にならざるをえない場合
    • 仕様変更やトラブル時のリカバリ等で、処理B だけを実行したいことがある場合
    • 処理B が異常終了した場合のリトライを自動的に行わせるため
    • 処理B があるサーバが障害やメンテでダウンしていても、復旧次第処理を行わせるため
  • 処理B を非同期にしたい場合
    • 処理B の時間がかかるため、終了を待てない場合 (処理A が Web アプリ、処理B が実行に10分かかるバッチなど)
    • 処理B を並列実行してスケールするようにしたい場合
    • 処理B はスケールしてほしいが、多重度が増えすぎないようコントロールしたい場合

などが考えられます。 さらに具体的な事例は下記です。

  • 画像をアップロードすると、画像種類別 (gif, png, WebP など) × サイズ別のサムネイル画像を生成する。
  • 注文受付後、PDF ファイルを生成する
  • ある処理後に、お知らせとしてメールや PUSH 通知を送信する
  • ランキング情報や統計情報の更新
  • サービス退会後の、会員情報・購入情報・履歴のマスキングや削除

分類

キュー・メッセージングについて、下記の分類があります。

  • PTP (Peer To Peer) モデル または キューモデルPTP モデルは、1本のキューがあり、送信側と受信側が 1対1 の形になっているものです。
  • Pub/Sub (パブ・サブ) モデルPub/Sub モデルは、Publish/Subscribe のことで、 送信側と受信側のレイヤがわかれており、1対1 もできますし、1対多 にすることもできます。 「出版-購読型モデル」と言うこともあるようです。

さらに別の切り口として、PULL・PUSH があります。

  • PULL受信側が、新しいメッセージを取りに来るタイプ。 例えば1秒に1回とか、1分に1回などの頻度でメッセージを取りに来るので、その分のタイムラグが発生します。
  • PUSH新しいメッセージがあると (比較的) すぐに受信側に送りつけるタイプです。

例えば Amazon SQS は、PTP モデルであり、PULL のみです。 Google Pub/Sub は、Pub/Sub モデルであり、PULL と PUSH 両方が可能です。

疑似コマンドで説明 - PTP モデル編

わかりにくいと思いますので、メッセージ・キューに関する作業を擬似コマンドで示します (create-queue というコマンドは実際は存在しません)。

まずは PTP モデルから。キュー myqueue を作成します。

% create-queue myqueue

キューに対し、メッセージを送信します。下記例では JSON フォーマットで送信していますが、 お互いの合意があれば CSV でもなんでも OK です。

% send-message myqueue '{"hoge":"fuga", "num":1}'

get-message コマンドでキューからメッセージを取得します。さきほど送信したメッセージが取得できました。

% get-message myqueye
ID: 12345 {"hoge":"fuga", "num":1}

言ってみればこれだけです。Amazon SQS や Azure Queue Storage はこんな感じです。 さらに続けます。

再度メッセージを取得すると以下のようにメッセージがないと言われます。 さきほどキューから取得したからですね。

% get-message myqueye No message 

しかしながら数分待ってもう一度メッセージ取得をすると、さきほど取得したメッセージを再度取得してしまいます。

% get-message myqueye ID: 12345 {"hoge":"fuga", "num":1} 

これはどういうことかというと、一度受信したメッセージは削除しないとキューに残り続けるのです。 取得したメッセージは一旦見えなくなり、数分待つと再度見えるようになります。 下記のようにメッセージを削除してしまうと、二度と見えなくなります。

% delete-message myqueye --id=12345 ID: 12345 was deleted. 

わざわざ削除しなければいけないなんてめんどくさいと思うかもしれませんが、 これがあることで、「後続処理が途中でエラーとなった場合でも一定時間後に再実行される」 とすることができるのです。

疑似コマンドで説明 - Pub/Sub モデル編

次は Pub/Sub モデルについて疑似コマンドで説明します。 下記は、「トピック」として mytopic を作成し、mytopic に届いたメッセージを取得するための 「サブスクリプション」として mysubscription を作成します。

% create-topic mytopic % create-subscription mysubscription --from-mytopic 

send-message コマンドで、トピックに対してメッセージを送信します。

% send-message mytopic '{"hoge":"fuga", "num":1}' 

get-message コマンドでサブスクリプションからメッセージを取得します。

% get-message mysubscription
ID: 12345 {"hoge":"fuga", "num":1}

できることは、PTP モデルと同じです。メッセージを送って受信するだけです。

では、せっかくの Pub/Sub モデルなので、1対多のメッセージ送信をやってみましょう。 注文をしたときにメッセージを投げる「トピック」と、 そのトピックからメッセージを受信できる「サブスクリプション」を 2つ作成します。 1つのトピックから、2つのサブスクリプションに同じデータが流れるようにします。

% create-topic order-topic
% create-subscription order-shipment-subscription --from-topic=order-topic
% create-subscription order-email-subscription --from-topic=order-topic

トピックに対し、メッセージを送信します。 注文処理なので「この customer が、この item を、何個買った」という情報です。

% send-message order-topic '{"customerId":88888, "itemId": 99999, "itemNum": 3}'

メール送信バッチは、注文受付メールを即時に送信します。

% get-message order-email-subscription
ID: 22222, {"customerId":88888, "itemId": 99999, "itemNum": 3}

一方、出荷処理バッチは 1日数回動き、order-shipment からメッセージを取得し、 出荷処理を行います。

% get-message order-shipment-subscription
ID: 22222, {"customerId":88888, "itemId": 99999, "itemNum": 3}

このように、1対多の関係を作っておくと、 メール送信と出荷処理に一切の関係性がなくなり、疎結合が実現できるということです。 Amazon SNS や Google Pub/Sub は、このように「トピック」「サブスクリプション」という二段構えになっており、 一対多関係を実現できます。

上記の説明は、いずれも「get-message コマンドを叩くとはじめてメッセージ取りに行く」ものなので、 PULL 型です。PULL しないとずっとメッセージは残ります。

PUSH 型の例も示しておきます。メッセージを投げると (ほぼ) 即時で実行されるというものです。 疑似コマンドで書くと下記のような感じです。

% create-subscription order-email-subscription --from-topic=order-topic --to-url='https://foo.bar/api/email'

上記により、order-topic にメッセージが届くと (ほぼ) 即時で登録した URL を叩きます。この URL が 200 OK を返さない場合は失敗とみなし、 一定時間待ってリトライします。URL 以外にも、別のトピックに投げたり、 AWS Lambda や Azure Functions のようなサーバレスの関数型サービスを呼び出したりもできます。

各サービス紹介

概念を抑えたところで、各クラウドサービスにおけるキュー・メッセージングサービス概要を説明します。

  • Amazon Simple Queue Service (SQS)PTP モデル。PULL のみ (PUSH なし)。 2004年サービスイン。Simple というだけあって、1対1のキュータイプのみで、 1対多はできない。2016年、順序性を維持する FIFO キューが追加された。
  • Amazon Simple Notification Service (SNS)Pub/Sub モデル。PUSH のみ (PULL なし)。 本来は SMS・プッシュ通知・http/https・メール・Lambda 等への汎用通知サービスであるが、 SNS から SQS につなげることができる。さらに、SNS 自体は Pub/Sub モデルなので 1対多の設定ができるので、SNS → SQS とすることで、1対多の Pub/Sub が実現できる。
  • Amazon MQ2017年11月サービスイン。 Apache ActiveMQ というオープンソースのメッセージングサーバを、 AWS によりフルマネージドサービスとして提供しているもの。 多分、とっても高機能。 現在オンプレミスで ActiveMQ を使っている場合、Amazon MQ を移行対象として検討してみるとよいでしょう。
  • Azure Queue StorageAzure Storage 上のキューサービス。 PTP モデル。PULL のみ (PUSH なし)。
  • Azure Service BusAzure 上のより高機能と思われるメッセージングサービス。 Pub/Sub モデル。PULL・PUSH 可能。
  • Google Cloud Pub/SubGCP でのメッセージングと言えば基本これ。 Pub/Sub モデル。PULL・PUSH 可能。
  • Google Task QueueGAE 内のサービス。 Google Cloud Pub/Sub リリース当初は、Task Queue はなくなる予定だったそうだが、 Pub/Sub では吸収しきれない要望がたくさんあったため、存続決定とのこと。

結局どれを使えばよいのかについて、AWS であれば、「オンプレで Active MQ を使っている」なら Amazon MQ を、 それ以外であれば Amazon SQS+SNS を選択すればよいでしょう。

Azure であれば、Azure Queue Storage よりも高機能な Service Bus がよいと思います。

GCP であれば、AppEngine のみでの利用で外部接続をしないなら Google Task Queue、 それ以外は Cloud Pub/Sub を使うべきでしょう。

メッセージング・キュー比較表

機能比較表をまとめてみました。 詳細は後述。

Amazon SQS+SNSAmazon MQAzure Queue StorageAzure Service BusGoogle Cloud Pub/SubGoogle Task Queue
モデルPTP (SQS), Pub/Sub (SNS)PTP, Pub/Sub 両方PTPPub/SubPub/SubPTP?
PULL○ (SQS のみ)
PUSH◯ (SNS のみ)?×
PEEK×○?×?
順序保証標準キューは×、FIFOキューは○××?
重複受信排除標準キューは×。FIFOキューは◯××?
デッドレター・有害メッセージ×?
遅延送信 (キュー単位)最大15分×....
遅延送信 (メッセージ単位)最大15分..◯?.
優先度指定××?×?
管理画面からキュー内容の確認....×.
管理画面からのメッセージ送信....
滞留数カウント???×??
滞留数によるオートスケール○ (SQS + CloudWatch)???×?
一括送信10メッセージまで.×○ (上限不明)○ (上限10MB?).
一括受信10メッセージまで.32メッセージまで○ (上限不明)○ (上限10MB?).
受信時のセレクタ設定×○???×?
Pub→Subsの条件設定◯ (SNS)?(概念なし)?×?
メッセージ最大保持期間14日間.7日間29,247年? (TimeSpan .Max)7日間.
最大メッセージサイズ256KB.64KB256KB (プレミアムなら1MB)10MB.
リージョン依存ありありありありなしあり
実行時間制限.....10分
送信手段AWS CLI, SDK.SDK, RESTSDK, RESTgcloud, SDK, REST, gRPCGAE
受信手段AWS CLI, SDK, Lambda, EC2等.SDK, REST, Azure Functions, WebJob, WorkerRoleSDK, REST, Azure Functions, WebJob, WorkerRolegcloud, SDK, REST, gRPCGAE、外部(pullのみ)
メッセージ永続化×?◯?×?×?×?×?

モデル・PULL・PUSH について

Amazon SQS+SNSAmazon MQAzure Queue StorageAzure Service BusGoogle Cloud Pub/SubGoogle Task Queue
モデルPTP (SQS), Pub/Sub (SNS)PTP, Pub/Sub 両方PTPPub/SubPub/SubPTP?
PULL○ (SQS のみ)
PUSH◯ (SNS のみ)?×
Amazon SQS+SNSAmazon MQAzure Queue StorageAzure Service BusGoogle Cloud Pub/SubGoogle Task Queue
PEEK×○?×?

PULL はしないまでも中身をチラと見てみたい。そのような場合に PEEK できるサービスもあります (peek はちらっと見る、そっと覗くという意味の英単語)。

順序保証について

順序保証とは、先に受け取ったもの (古い) メッセージを先にください、ということです。ある意味当然ではありますが、これがなかなか難しい。どこか一ヶ所でメッセージを受けとるなら簡単な話なのですが、可用性・性能のために複数のインスタンスがあるため、順序を維持するためには性能が犠牲となります。

一般的には順序の保証がないものと考えましょう。

「重複受信排除」について

デッドレター・有害メッセージについて

メッセージを受信して後続処理を行うとします。しかし後続処理がエラーとなったらどうするか。再実行されるのですが、5回や10回実行しても失敗したなら、いさぎよくあきらめてほしい場合があります。そのようなときに処理できなかったメッセージをデッドレターや有害メッセージと呼びます。

「遅延送信」について

「優先度指定」について

「管理画面からキュー内容の確認」について

「管理画面からのメッセージ送信 」 について

「 滞留数カウント」について


「滞留数によるオートスケール」について


「一括送信」「一括受信」について


「 受信時のセレクタ設定 」について


「 Pub→Subの条件設定」について


「メッセージ最大保持期間」について

「最大メッセージサイズ」について

「 リージョン依存」について

「受信手段 」 について

「 メッセージ永続化」について

メモ

Cloud PubSub のサブスクを使わないと 31日で消えてしまう件。有効期限ポリシー設定(beta)で、消えないようにできるかもしれない件。

  • このエントリーをはてなブックマークに追加

SNSでもご購読できます。

Leave a Reply

*

CAPTCHA