如何为即时通讯系统设计redis pub/sub? [英] How to design redis pub/sub for an instant messaging system?

查看:46
本文介绍了如何为即时通讯系统设计redis pub/sub?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 redis pub/sub 的新手.我在系统中有一个类似于 IM 的聊天工具.所以我想使用redis pub/sub.正如我检查过的样本,其中大部分是基于聊天室设计的.在我的系统中,我将有多个用户之间的聊天室;

I am new to redis pub/sub. I have a chat facility in the system which is like IM. So I would like to use redis pub/sub. As I have examined the samples most of them are designed based on a chat room. In my system I will have multiple chat rooms between users like;

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

所以,上面的线条是房间.我已经使用 node.js 实现了服务器,如下所示;

So, the lines above are the rooms. And I have implemented the server with node.js like below;

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 是否可以为每个连接创建一个新的订阅者客户端.

As you can see I am creating a new redis subscriber for each connection. In other chat room samples redis subscriber client is created globally. And there exists only three connections all the time and that solves their problem because when a publisher publishes a message all connected clients should get it. But I have a constraint here. I want to open a chat session between two users and only these users should be the subscribers. The code above works as I would like to but I do not know if it is OK for redis to create a new subscriber client for each connection.

很高兴听到您的建议.提前致谢.

It would be great to hear your suggestions. Thanks in advance.

推荐答案

与往常一样,您需要针对您自己的用例对这样的事情进行基准测试——不可能给出一般性建议.您可能需要在系统范围内或为 redis 用户增加系统上打开文件的最大数量.当然,这也适用于运行您的网络服务器的用户.

As always, you need to benchmark things like this for your own use-case -- it's not possible to give general advice. You might need to increase the maximum number of open files on your system, either system-wide or for the redis user. This also applies to the user running your web server, of course.

也就是说,您应该确保在用户离开时监听 redis 订阅者的 socket.on('disconnect')quit().您可能还想知道 socket.io 有一个 redis 后端,它利用了 redis pub/sub,并且它还具有房间的概念,因此您可以通过使用它来为自己省去一些麻烦,因为您已经依赖于 socket.io.

That said, you should make sure to listen for socket.on('disconnect') and quit() the redis subscriber when a user leaves. You might also be interested to know that socket.io has a redis backend, which leverages redis pub/sub, and it also has the concept of rooms, so you might save yourself some trouble by using that since you're already depending on socket.io.

快速检查后,我在 991 个订阅者之后从 Redis 收到此错误消息:

After a quick check, I get this error message from Redis after 991 subscribers:

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 设置,然后基准,基准,基准!

My system (Ubuntu 11.11) comes with a default nofile limit of 1024, so my quick test should fail after 992 connected clients, which seems about right from the test (I also have one client for the publisher). My suggestion to you is to inspect your nofile limit (on my system it's in /etc/security/limits.{conf,d/*} and your redis maxclients setting, and then benchmark, benchmark, benchmark!

这篇关于如何为即时通讯系统设计redis pub/sub?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆