カテゴリ: RabbitMQ
記事投稿日: 2017年5月25日
※ この記事に来られた方は、Heroku や 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 自体を増やせば、処理の並列化としては、同様のメリットを得られます。
コメントを残す