256KBを超えるSQSメッセージを送受信する方法

はじめに

SQSのメッセージサイズ上限は256KBということを最近知りまして、
上限を超えた場合は諦めるしかないのか、それとも上限を回避する方法があるのか調査する機会がありました。

結論としましては上限を回避する方法がありましたので、記録に残すためにブログに調査結果を残そうと思います。

目次

Amazon SQSについて

Amazon SQSはAWSが提供するフルマネージド型のメッセージキューイングサービスです。
メッセージキューイングとはアプリケーション間でメッセージ(データ)を送受信する仕組みを指します。
送信されたメッセージは一時的にキューと呼ばれる領域に保存され、任意のタイミングで受信が可能です。
Amazon Simple Queue Service とは

メッセージサイズの上限について

しかし、下記クォータの通り、Amazon Simple Queue Service(SQS)のメッセージサイズの上限は256KBとなっています。
Amazon SQS メッセージクォータ

メッセージサイズ
最小メッセージサイズは1バイト(1文字) です。最大は 262,144 バイト (256 KiB) です。

上記リンクにも記載がありますが、256KBを超えるメッセージを送受信したい場合は拡張クライアントライブラリを使用します。
拡張クライアントライブラリと Amazon Simple Storage Service を使用した大規模な Amazon SQS メッセージの管理

Java用とPython用が用意されており、ライブラリをインポートするのみで256KB~最大2GBのメッセージを送受信できます。
この拡張クライアントライブラリがSQSのメッセージサイズ上限を回避する方法になります。
(他にもメッセージ自体を256KB以内に分割して送受信する方法もありますが、お手軽な方法は拡張クライアントライブラリと思われます)

実際にやってみた

下記AWS開発者ガイドにサンプルコードとpom.xmlの一部があります。
AWS SDK for Java 2.x 例: Amazon S3 を使用した大規模な Amazon SQS メッセージの管理

SQS送信

サンプルコードからSQS送信部分のみを抜き出して、Cloud9とMavenを使用してビルドを行い、Jarファイルを作成後、動作を確認してみます。
SQSsenderCloud9.png

SQSコンソールからメッセージをポーリングすると1件送信されていました!
SQSsenderSQSconsole.png

早速中身を確認すると…
SQSsenderContents.png
メッセージ本文はS3バケット名とオブジェクトキーが記載されていますね。

メッセージ属性はSQSLargePayloadSizeが格納されています。
SQSsenderAttributes.png
これはメッセージ本文がS3バケットにあるかどうかを判別するための値のようです。

参考) amazon-sns-extended-client 1.0.0 (PyPI)

予約済みメッセージ属性として SQSLargePayloadSize を使用する
Java SNS 拡張クライアントの初期バージョンでは、メッセージが S3 メッセージであることを判別するために、予約済みのメッセージ属性として「SQSLargePayloadSize」が使用されていました。

ではS3バケットはどうなっているかというと…
SQSsenderS3Console.png
同じオブジェクトキーで格納されていますね!
しかもファイルサイズが293KBなので、256KBを超えたメッセージがしっかりと格納されています。

SQS受信

こちらも、サンプルコードからSQS受信部分のみを抜き出して、Cloud9とMavenを使用してビルドを行い、Jarファイルを作成後、動作を確認してみます。
SQSreceiverCloud9.png
受信したMessage bodyがS3バケットに格納されたファイルを受信していることが分かります。
SQS本文を受信してしまった場合は["sofのような出力になりますので、しっかりとS3バケット内のメッセージを受信しているようです。

なお、受信後はSQSからもS3からもメッセージは削除されていました。SQSreceiverSQSconsole.png
SQSreceiverS3Console.png

注意点

  • 拡張クライアントライブラリを使用した場合でもメッセージサイズの上限は2GBとなります
  • 拡張クライアントライブラリを使用する場合はSQSだけでなく、S3への設定が必要です
    • メッセージ送信側(プロデューサー)にはS3への書き込み権限
    • メッセージ受信側(コンシューマー)にはS3への読み込み/削除権限
    • 必要に応じてS3のバケットポリシーなど
  • JavaやPython以外の実装について
    • AWSからライブラリが提供されていないので、自ら実装する必要があります
    • しかしかなり煩雑のため、まずはクォータ内に収まるようメッセージの分割をおススメします
    • 有志によるライブラリが提供されている場合がありますが、AWS公式のサポートは受けられないので注意が必要です

まとめ

  • 拡張クライアントライブラリを使用することで256KBを超えるSQSメッセージを送受信可能
    • ただし上限は2GB
    • 無制限ではないことに注意
  • JavaやPython以外の言語の場合はクォータ内に収まるようにメッセージを分割した方がよい場合がある

投稿者プロフィール

nagura
2021年4月からスカイアーチに中途入社しました。
AWSともっと仲良くなるべく日々勉強中です。