如何为即时通讯系统设计redis pub / sub?

时间:2012-04-13 13:59:35

标签: node.js redis publish-subscribe

我是redis pub / 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订户客户端。并且始终只存在三个连接并且解决了他们的问题,因为当发布者发布消息时,所有连接的客户端都应该获得它。但我在这里有一个约束。我想在两个用户之间打开聊天会话,只有这些用户应该是订阅者。上面的代码按照我的意愿工作,但我不知道redis是否可以为每个连接创建一个新的订阅者客户端。

听听你的建议会很棒。提前致谢。

1 个答案:

答案 0 :(得分:20)

与往常一样,您需要为自己的用例对此类事情进行基准测试 - 不可能提供一般性建议。您可能需要增加系统上打开文件的最大数量,无论是系统范围还是redis用户。当然,这也适用于运行Web服务器的用户。

也就是说,当用户离开时,您应确保监听redis订阅者的socket.on('disconnect')quit()。您可能也有兴趣知道socket.io有一个redis后端,它利用了redis pub / sub,它也有房间的概念,因此您可以通过使用它来节省一些麻烦,因为您已经依赖于socket .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个连接的客户端之后失败,这似乎与测试有关(我也有一个发布者的客户端) 。我建议您检查nofile限制(在我的系统上/etc/security/limits.{conf,d/*}和您的redis maxclients设置,然后检查基准,基准,基准!