Heroku: worker のプロセスを増やす(分散)する方法(for RabbitMQ)

カテゴリ: RabbitMQ

記事投稿日: 2017年5月25日



※ この記事に来られた方は、Heroku や RabbitMQ のことはご存知かと思いますので、その辺りは省略させて頂きます。

RabbitMQ の処理を「並列化」するために

先に結論です。

並列化は、「Procfile で worker を複数のプロセスとして起動します」

PHP なら以下で、複数プロセスを起動できます。


worker: php worker.php | php worker.php | php worker.php

さらに、RabbitMQ では、「各Consumer の処理の数を1件にする」ことで、あふれたタスクは、起動中の別プロセスに割り振られていきます。

結論に至るまで…

そもそもは、RabbitMQ で「並列化」するにはどうしたらいいのか、という業務上の問題でした。

コードをいくら漁っても分からず、また、RabbitMQ のドキュメントが英語なので、情報もなかなか見付かりませんでした。

そこで、RabbitMQ のチュートリアルを訳しながら見直していたら、以下の文章に突き当たりました。

『タスクキューを使用する利点の1つは、作業を簡単に並列化できることです。
仕事のバックログを構築しているなら、簡単にもっと worker を追加して、拡大できるのです。』

並列化をいとも簡単に出来るようなことが書いてありますね。。
これはおかしい。「コード上」には、そんなことはどこにも書いていないのに…。

公式ドキュメント: 「2 Work queues」を詳細に読んだところ、同じ worker.php を複数のシェルから起動し、「プロセス」として立ち上げることで実現していました。

これしか方法がないから、説明(ドキュメント)がないと、ようやく分かりました…。

詳しい解説

今回の案件で、RabbitMQ を動かしているのは、Heroku です。
Procfile での設定は、通常、以下になります。


worker: php worker.php

上記を複数行書いたり、スクリプト名をスペースやカンマで区切ったり、色々しましたが、本家のチュートリアルをよく読んだら、php のコマンドで実行しているだけ。
真似してたどりついたのが、下記の記述です。


worker: php worker.php | php worker.php | php worker.php

「| 」で区切り、php コマンドで、複数のスクリプトを起動させるイメージです。
これで、常時3つのプロセスが起動しました。

Heroku のダッシュボードで確認すると、Worker はひとつですが
RabbitMQ としては、「Unacknowledged」(未処理)が常に最大3件となりました。
ほぼ同時にリクエストを投げれば、3件ずつ処理が終わっていくのを確認できました。

最後に

worker-Dyno のプロセスを増やす方法くらい、Heroku のドキュメントに載せてくれてもいいようなものですが、ありません…。
このあたりは、サーバ・エンジニアの知識があれば当然のことかも知れませんが、Paas を使う開発者にとっては、そのあたり、ドキュメントがないと非常に不利と思いました。

RabbitMQ はメッセージキューイングのサービスとしてはスタンダードのようですが、PHP での用例はほとんど見かけません(2017年5月現在)。
だいたい、Java か Python での実例がほとんど。

同じような需要にかられ、困っている方の一助になれば幸いです。
RabbitMQ の記事(特にPHPでの活用)がもっと増えるといいなと思います。

※ 「プロセス」なので、あまり増やして、処理に時間がかかる処理をやらせると、負荷がかかり過ぎることが予想されます。実運用では、処理とのバランス(とコスト面)を充分考慮されることをオススメします。
また、予算に余裕があれば、Worker-Dyno 自体を増やせば、処理の並列化としては、同様のメリットを得られます。








コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA




トップに戻る