メッセージはMySQLに保存するようにしてます。
JavaScriptの使用できないガラケーからも投稿できるようにする必要があったので、
ガラケーからの投稿は、テンポラリのMySQLテーブルに保存し、
node.jsのサーバーサイド側で、そのテーブルを1秒ごとにチェックし、
メッセージがあれば、socket.ioに接続しているユーザーにemitするようにしました。
しかし、socket.ioの接続人数や、ガラケーからの投稿数が多くなると、
1秒毎にチェックしている処理が遅延してしまいます。
ガラケーからの投稿をスマートに投稿できる良い方法があれば教えてください。
それではよろしくお願いします。
---------
node.js
v0.6.8
socket.io
0.8.7
Centos
5.7
Apache
2.2.3
MySQL
5.5.20
PHP
5.3.3
ガラケーからの投稿も同じNodeプロセスで受けてるんでしょうか?であればMySQLを定期チェックするのではなく投稿タイミングでio.socketsにemitしてやれば良いんじゃないですか?
もしくはガラケーは別システム(例えばPHP等)で受けているのであれば、Node側に以下のような受け口APIを作っておいて、PHPからローカルで叩いてやれば定期チェックは不要だと思います。
Node側
//新着メッセージの通知を受ける app.get("/emitMessage", function(req, res) //socket.io接続中のユーザ全員に新着メッセージを配信 io.sockets.emit("message", getNewMessagesFromMySQL()); });
PHP側
<?php /* ガラケーからの投稿処理(略) */ //ガラケーから投稿があったことをNodeへも通知 file_get_contents("http://localhost:3000/emitMessage");
全体構成を変えない方向で考えてみました・・・。
まず考えたのが、
もしもデータベースエンジンがMyISAMであればInnoDBに替えてみること。
移行作業はもっとも簡単でレンタルサーバーでも問題は無く移行できるはずです。
(別な手段としてSQLite3を併用するということも考えられますが、
MySQLのような柔軟性はないので微妙で避けたいですね)
効果的(こっちが本命)だと思われるのは、キャッシュにmemcachedを利用すること。
phpからのmemcached利用はかなり簡単になっていますし、
携帯からの入力キャッシュ程度であれば、
メモリが満杯になるような心配も多分ですがないでしょう。
(メモリが心配になるほどのアクセス数だと、
サーバーのハードウェア増強を考えないといけないでしょうから・・・)
http://php.net/manual/ja/book.memcached.php
ご回答ありがとうございます!
memcachedは使ったことなかったのですが、ガラケーサイトの重いライブラリがあったので、
memcachedを使ってみると早くなった気がします!
PHPからは簡単に使えたんですが、node側から使うのはまた調べる必要がありそうでした。
まずはどこがネック担ってるかを調査することです。
1.ソケットの同時接続コネクション数などの制限にひかっかっている
2.DB側の問題
接続人数がどの程度になったときから
遅延が起こるかってことです。
その遅延がどの程度の遅延かというのも重要です。
遅延程度によって、どこがネックになってるかが予想できるからです。
ソケット関係の制限で、
接続数が多くなると待ち状態になってるだけではないか?と
思うのですが・・。
MYSQLがいくら重めと言っても、その程度の検索、更新処理で
大きな遅延が起こるまでには至らないと思いますが。
更新と言ってもINSERTしかないと思いますしね・・。
ご回答ありがとうございます!
ネックになってるところを調べようと、
ソケット接続数をカウントするようにしてみました。
最大同時接続は100人ぐらいでした。
つぎにトラフィックツールのMUNINを見てみるとHDDのIOのグラフが高くなってる時がありました。
IOをあまり使った覚えがなく、VPSだったので他のユーザーの影響を受けているのかもしれないということで
VPSの調査依頼を行うと他のユーザーの影響を受けており、他のユーザーを制限してくれるようになり、
負荷については解决できたと思います!
ガラケーからの投稿も同じNodeプロセスで受けてるんでしょうか?であればMySQLを定期チェックするのではなく投稿タイミングでio.socketsにemitしてやれば良いんじゃないですか?
もしくはガラケーは別システム(例えばPHP等)で受けているのであれば、Node側に以下のような受け口APIを作っておいて、PHPからローカルで叩いてやれば定期チェックは不要だと思います。
Node側
//新着メッセージの通知を受ける app.get("/emitMessage", function(req, res) //socket.io接続中のユーザ全員に新着メッセージを配信 io.sockets.emit("message", getNewMessagesFromMySQL()); });
PHP側
<?php /* ガラケーからの投稿処理(略) */ //ガラケーから投稿があったことをNodeへも通知 file_get_contents("http://localhost:3000/emitMessage");
ご解答ありがとうございます!
PHPから叩けるならサーバーサイドの定期チェックが不要になりますので助かります。
ちょうどexpressを使っていたんですが、socket関係の処理とexpressのリクエストをさばく処理を混合して書ける事に気づきませんでした。
ファンタスティックです!
ご解答ありがとうございます!
2012/04/20 15:06:22PHPから叩けるならサーバーサイドの定期チェックが不要になりますので助かります。
ちょうどexpressを使っていたんですが、socket関係の処理とexpressのリクエストをさばく処理を混合して書ける事に気づきませんでした。
ファンタスティックです!