14

私はredispub/subを初めて使用します。システムにIMのようなチャット機能があります。そこで、redis pub/subを使用したいと思います。私がサンプルを調べたので、それらのほとんどはチャットルームに基づいて設計されています。私のシステムでは、次のようなユーザー間に複数のチャットルームがあります。

A:B
A:C
D:C
E:F

つまり、上の行は部屋です。そして、私は以下のようにnode.jsでサーバーを実装しました。

var store = redis.createClient();
var pub = redis.createClient();
io.sockets.on('connection', function (socket) {
    var sub = redis.createClient();

    sub.on("message", function(pattern, data){
            data = JSON.parse(data);
        socket.send(JSON.stringify({ type: "chat", key: pattern, nick: data.nickname, message: data.text }))
        }
    });

    socket.on('message', function (messageData) {
        store.incr("messageNextId", function(e, messageId) {
        var room = ""
        var from = messageData.clientId > socket.nickname ? socket.nickname : messageData.clientId;
        var to = messageData.clientId < socket.nickname ? socket.nickname : messageData.clientId;   
            room = from + ":" + to;

        var message = { id: messageId, nickname: socket.nickname, text: messageData.text };
        store.rpush("rooms:" + room, JSON.stringify(message), function(e, r) {  
             pub.publish(room, JSON.stringify(message))
        });
    });
});

ご覧のとおり、接続ごとに新しいredisサブスクライバーを作成しています。他のチャットルームのサンプルでは、​​redisサブスクライバークライアントがグローバルに作成されます。また、接続は常に3つしかないため、発行者がメッセージを公開すると、接続されているすべてのクライアントがメッセージを取得する必要があるため、問題が解決します。しかし、ここには制約があります。2人のユーザー間でチャットセッションを開きたいのですが、これらのユーザーだけがサブスクライバーになる必要があります。上記のコードは私が望むように機能しますが、redisが接続ごとに新しいサブスクライバークライアントを作成してもよいかどうかはわかりません。

あなたの提案を聞くのは素晴らしいことです。前もって感謝します。

4

1 に答える 1

20

いつものように、あなたはあなた自身のユースケースのためにこのようなものをベンチマークする必要があります-一般的なアドバイスを与えることは不可能です。システム全体またはredisユーザーのいずれかで、システムで開いているファイルの最大数を増やす必要がある場合があります。もちろん、これはWebサーバーを実行しているユーザーにも当てはまります。

とは言うものの、ユーザーが離れるときは、必ずリッスンしsocket.on('disconnect')quit()、redisサブスクライバーを確認する必要があります。また、socket.ioにはredis pub / subを活用するredisバックエンドがあり、部屋の概念もあるため、すでにソケットに依存しているため、これを使用することで問題を回避できる可能性があります。 .io。

編集:簡単なチェックの後、991人のサブスクライバーの後にRedisから次のエラーメッセージが表示されます:

Ready check failed: Error: Error: ERR max number of clients reached

これがデフォルトからですredis.conf

# Set the max number of connected clients at the same time. By default
# this limit is set to 10000 clients, however if the Redis server is not
# able ot configure the process file limit to allow for the specified limit
# the max number of allowed clients is set to the current file limit
# minus 32 (as Redis reserves a few file descriptors for internal uses).
#
# Once the limit is reached Redis will close all the new connections sending
# an error 'max number of clients reached'.
#
# maxclients 10000

私のシステム(Ubuntu 11.11)のデフォルトnofileの制限は1024であるため、992の接続されたクライアントの後でクイックテストが失敗するはずです。これは、テストからほぼ正しいようです(パブリッシャー用のクライアントも1つあります)。あなたへの私の提案はあなたのnofile限界を調べることです(私のシステムではそれが入ってい/etc/security/limits.{conf,d/*}てあなたのredismaxclients設定、そしてベンチマーク、ベンチマーク、ベンチマークです!

于 2012-04-13T14:51:32.257 に答える