動かしてみる
インストール&初期設定
Lazy Queuesの機能が追加されたのが3.6.0からなので、RabbitMQのコミュニティページから最新版のパッケージを取得します。今回はUbuntu 14.04環境で説明しますが、RabbitMQは他にもFedora、RHELそしてMac OS X、さらにWindows環境へのインストールもサポートしています。
ダウンロードしたパッケージを以下のようにインストールします。
user@host:~$ wget https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.0/rabbitmq-server_3.6.0-1_all.deb user@host:~$ sudo dpkg -i rabbitmq-server_3.6.0-1_all.deb
正常にインストールされるとデーモン「rabbitmq-server」が自動起動します。
次に、RabbitMQが消費するシステムリソースの状況や、各キューの状態を把握するためにマネジメントプラグインをインストールします。プラグインのインストールは、以下rabbitmq-pluginsコマンドから実施できます。
user@host:~$ sudo rabbitmq-plugins enable rabbitmq_management
続いてユーザ設定を行います。デフォルトで管理者権限のユーザ「guest」が作成されますが、ループバックアドレスからしかアクセスできないため、新たにtsuchinokoユーザを作成します。
user@host:~$ sudo rabbitmqctl add_user tsuchinoko passwd
パスワードには「passwd」を設定しています。次に、作成したユーザ「tsuchinoko」のアクセス権限の設定を行います。
user@host:~$ sudo rabbitmqctl set_permissions tsuchinoko ".*" ".*" ".*"
ユーザ「tsuchinoko」に対して、すべてのリソースに対する読み書き権限を与えています。最後に、当該ユーザに対して管理者権限を付与します。
user@host:~$ sudo rabbitmqctl set_user_tags tsuchinoko administrator
ここまでの作業でRabbitMQのインストールと初期設定が完了しました。ブラウザを立ち上げて以下のアドレスにアクセスし、RabbitMQの管理画面にアクセスできることを確認してください。
「Username:」と「Password:」は、それぞれ「tsuchinoko」と「passwd」で管理ページにログインできます。
動作確認
ではいよいよ先ほど作成した2つのプログラムを動かして、RabbitMQサーバのキューがどのように振る舞うかを確認してみます。ソースコードは次のようにダウンロードします。
user@host:~$ git clone git@github.com:userlocalhost2000/queue-examples.git
実行前に依存ライブラリをインストールするために、以下のコマンドを実行します。
user@host:~$ cd queue-examples user@host:~/queue-examples$ sudo gem install bundler user@host:~/queue-examples$ sudo bundle install
ではまず、通常のキューに対してメッセージを送る処理を実行します。以下のコマンドを実行してください
user@host:~/queue-examples$ ruby basic_queues/sender.rb
コマンド実行後にマネジメントプラグインの管理画面をブラウザで開き「Queues」のタブを開き、RabbitMQサーバで作成されているキューの状態を確認します。
赤線で囲った部分が示すように、受け取ったメッセージがメモリに格納されているのが分かります。また先述のとおり、RabbitMQではシステムで消費するメモリ容量が一定容量を超えると、メモリにたまっているキューメッセージをストレージに書き出します。具体的には、RabbitMQサーバはデフォルトで物理メモリの40%のメモリ領域をRabbitMQシステムの使用上限に設定し、その上限の半分を超えた場合にページアウト処理を走らせます。以下は、ページアウト処理が発生した際のメッセージのキューイング処理の様子を示しています。
上段のグラフ「Queued messages」は、キューに滞在しているメッセージの総量を表し、下段のグラフ「Message rates」は、キューに送信されるメッセージ(黄線)と、ページアウト処理によってディスクに書き出されるメッセージ(青線)の変化量を表します。
図において「Message rates」のグラフで「Disk write」が発生しているのが分かります。先述のとおり、ページアウト処理中はメッセージの転送処理ができないため、Disk writeが発生している間に「Publish」で示されるキューイングしているメッセージの数が0になり、またメッセージの総量もこの間だけ増えていないことが分かります。
また同じ様子をもう少し長いスパンで見た結果が以下の図になります。
ページアウト処理による「Disk write」が断続的に発生していることが分かります。これによって、全体的にはメッセージのキューイング処理が行われておりますが、スループットが安定していないことが分かります。
では続いて「Lazy Queues」が設定されたキューに対してメッセージを送る処理を実行します。今度はlazy_queuesのsender.rbを実行します。
user@host:~/queue-examples$ ruby lazy_queues/sender.rb
先ほどと同じ管理画面から、キューの状態を確認します。
通常のキュー「basic-queue」と比較して、Lazy Queuesを設定した「lazy-queue」ではメモリを消費していないことが分かります。
最後に、「lazy-queue」におけるキューに保存されるメッセージの総量と変化量を表すグラフを以下に示します。
「lazy-queue」ではページアウト処理が発生しないため、以下の示すように常に一定のスループットでメッセージの転送処理を行うことができます。
おわりに
今回は、RabbitMQ v3.6.0に組み込まれた新機能「Lazy Queues」について、どういうもので、どのように使い、どのような振る舞いをして、何がうれしいかについて解説してきました。なお、今回は「Lazy Queues」が設定されたキューにどのようにメッセージが「たまるか」の解説がメインだったため、キューに格納されたメッセージを取得する処理「receiver.rb」については解説しませんでしたが、興味があればこれの実行によってキューの中身がどのように変化するのかご自身の環境で試してみてください(おおむね、予想通りの結果になるとは思いますが)。
今回の内容によって、読者の皆さんが開発されている分散システムや、すでに運用されているMQシステムの改善に少しでもお役に立てたなら幸いです。
またDMMではツチノコブログでDMMのTechな話題を中心に紹介しておりますので、ぜひチェックしてみてください。