複数のサーバーでの変数の共有方法

884 views
Skip to first unread message

3.14P

unread,
May 29, 2013, 4:53:06 AM5/29/13
to Node.js 日本ユーザグループ
こんにちは。3.14Pです。
いま、socket.ioでチャットを作っていて、
ユーザリストを変数に入れてるのですが、
複数のサーバーで共有する時は、どうやってすれば良いですか?
それと、socket.ioサーバーを9000でリッスンしてますが、
スケールアウト時の注意点等はありますか?

Hirano Masaaki

unread,
May 29, 2013, 5:30:40 AM5/29/13
to node...@googlegroups.com
こんにちは。平野です。

自分が似たような事をした際は、memcachedやredisのようなキャッシュ用のサーバを用意して
複数のwebsocketサーバの情報を集約させていました。
仕様や実装にもよりますが、数台〜十数台のwebsocketサーバに対して、
memcachedサーバ1台でリクエストをさばく事が出来ると思います。
それ以上にスケールする場合はまた別のアーキテクチャを考える必要が出てきます。

あまり大きくスケールアウトさせたような事はありませんが、
目立たないblockableな処理が全体のパフォーマンスを落とすという現象は何度も目にしていますので、
注意して処理を書いていく必要があるかなと感じています。



2013年5月29日 17:53 3.14P <3.14pr...@gmail.com>:

--

---
このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
このグループから退会し、メールの受信を停止するには、nodejs_jp+...@googlegroups.com にメールを送信します。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。



Hiroshi Kuwabara

unread,
May 30, 2013, 8:24:15 PM5/30/13
to node...@googlegroups.com
はじめまして、桑原と申します。

Stack Overflowのこの投稿が参考になるかもしれません。

質問文中で引用されていますが、
複数サーバー間でsocket.ioの接続を共有する方法としてRedisStoreを使用した例が
こちらのブログに載っています。

ご参考まで。

遠州律夫

unread,
Jul 25, 2013, 6:48:15 AM7/25/13
to node...@googlegroups.com


2013年5月31日金曜日 9時24分15秒 UTC+9 Hiroshi Kuwabara:
返信すごく遅れてスイマセン。
これって、RedisStoreで、スケールアウトするためのものですか?
あまり英語はよくわからないんですけど、

var pub = redis.createClient();
 pub.publish("messages", JSON.stringify({type: "foo", content: "bar"})); 
 io.sockets.on("connection", function(socket) { 
var sub = redis.createClient();
 sub.subscribe("messages");
 sub.on("message", function(channel, message) { 
socket.send(message); 
}); socket.on("disconnect", function() {
 sub.unsubscribe("messages"); sub.quit();
 }); 
});

このようなPub・Subを使ったものと何が違うんですか?

Hiroshi Kuwabara

unread,
Jul 30, 2013, 8:28:12 AM7/30/13
to node...@googlegroups.com
Socket.ioの機能で、
接続を共有するためのバックエンドを差し替えられるようになっていて、
その実装の一つとしてRedisのPub/Sub機能を利用することができるようです。
(デフォルトはMemoryStoreになっているので、同一のプロセス内でしか接続を共有できない)

これを利用すると、接続を共有するためのコードを
ビジネスロジックに直接記述せずに、
設定コードとして分離できるという利点があるでしょうか。

var RedisStore = require('socket.io/lib/stores/redis')
  , redis  = require('socket.io/node_modules/redis')
  , pub    = redis.createClient()
  , sub    = redis.createClient()
  , client = redis.createClient();

// 接続を共有するためのコードは
// ここに記述(socket.ioの設定)
io.set('store', new RedisStore({
    redisPub: pub
  , redisSub: sub
  , redisClient: client
}));

io.sockets.on('connection', function(socket) {
  // ここにアプリにとって主要なビジネスロジックを
  // 記述することになると思いますが、
  // 複数サーバーでメッセージを共有するための
  // コードはここでは書かなくてすむようになっています。
  //
  // 「メッセージをどうやって共有するか」は意識せずに、
  // 「メッセージを受け取ったときに何をするか」
  // にフォーカスしたコードになると思います。
  socket.on('message', function(message) {
    socket.broadcast.send('foo');
  });
});



質問の意図には合ってましたでしょうか?
RedisのPub/Subを利用することには変わりありませんが、
・自分で接続を共有する仕組みを書くか
・Socket.ioの設定を利用してアプリではビジネスロジックにフォーカスするか
の違いになるのではないでしょうか。


※あと、紹介したブログの記事のURLが今見たら変更されてましたね。
現在は下記URLで見れるようです。
Reply all
Reply to author
Forward
0 new messages