如何为即时消息系统设计 redis pub/sub?

     2023-03-25     36

关键词:

【中文标题】如何为即时消息系统设计 redis pub/sub?【英文标题】:How to design redis pub/sub for an instant messaging system? 【发布时间】:2012-04-25 21:37:42 【问题描述】:

我是 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】:

与往常一样,您需要针对自己的用例对此类事物进行基准测试——不可能给出一般性建议。您可能需要增加系统上打开文件的最大数量,无论是系统范围还是 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 设置中,然后进行基准测试、基准测试、基准测试!

【讨论】:

感谢您的详细回答。我知道 socket.io 有房间的概念,但我不知道它在幕后使用 pub/sub。我会尝试一下。当然,我将开始基准测试,目前我只是想找到一个好的起点。感谢您的建议。 @AliErsöz:太好了。如果您发现我的回答令人满意,请考虑点击左上角的大勾号将其作为正确答案。

如何为测试、暂存和生产配置 Google Cloud Pub/Sub?

】如何为测试、暂存和生产配置GoogleCloudPub/Sub?【英文标题】:HowtoconfigureGoogleCloudPub/Subfortest,staging,andproduction?【发布时间】:2019-11-1201:02:52【问题描述】:我看到了这份文件。(https://cloud.google.com/pubsub/architecture#environments)维护... 查看详情

gcp 云函数 pub/sub 主题死信

...时出现错误,则将消息放入相应的死信队列。我不确定如何为还包含死信策略的云功能创建订阅。目前我正在为云功能做以下事情,res 查看详情

使用redis的pub/sub来实现类似于jms的消息持久化

...到了关于如何避免Redis的Pub/Sub的一个最大的缺陷的思路—消息的持久化(http://blog.csdn.net/canot/article/details/51975566)。这篇文章主要是关于其思 查看详情

redis pub sub 会在频道中保留历史消息吗?

】redispubsub会在频道中保留历史消息吗?【英文标题】:doesredispubsubpersisthistoricalmessagesinachannel?【发布时间】:2013-08-0710:42:38【问题描述】:我无法在文档中找到有关通道中的消息如何存储在redis发布/订阅中的文档。当您发布到r... 查看详情

redis学习笔记8:redis发布订阅(pub/sub)(代码片段)

...Redis发布订阅?Redis发布订阅(pub/sub)是一种消息通信模式:发送者pub发送消息,订阅者sub接收消息。Redis客户端可以订阅任意数量的频道。二、发布订阅原理        Redis是使用C实现的,通过分析Redis... 查看详情

如何为两个不同实体之间的复杂消息系统设计表?

】如何为两个不同实体之间的复杂消息系统设计表?【英文标题】:Howtodesigntablesforacomplicatedmessagingsystembetweentwodifferententities?【发布时间】:2019-08-2623:27:50【问题描述】:我正在开发一个包含消息传递系统的Web应用程序。Web应用... 查看详情

redis源码阅读-发布与订阅pub/sub(代码片段)

redis的发布订阅(pub/sub)是一种消息通信模式,由发布者(pub)发布消息,订阅者订阅(sub)消息。redis通过publish和subscribe等命令实现了发布与订阅模式。我们先通过一张图了解下工作机制:我们看下案... 查看详情

Redis Cluster 与 ZeroMQ 在 Pub/Sub 中,用于水平扩展的分布式系统

】RedisCluster与ZeroMQ在Pub/Sub中,用于水平扩展的分布式系统【英文标题】:RedisClustervsZeroMQinPub/Sub,forhorizontallyscaleddistributedsystems【发布时间】:2012-11-2519:14:10【问题描述】:如果我要设计一个庞大的分布式系统,其吞吐量应该与... 查看详情

redis_05_redis发布订阅(pub/sub)(代码片段)

...配订阅频道四、尾声一、前言本文介绍Redis自带的简单的消息队列。MySQL自己有缓存层,但是缓存层实现的不是很好,所以才有了Redis这种专门的缓存层;Redis自己有简单的消息队列,但是消息队列很简单 查看详情

redis学习笔记8:redis发布订阅(pub/sub)(代码片段)

...Redis发布订阅?Redis发布订阅(pub/sub)是一种消息通信模式:发送者pub发送消息,订阅者sub接收消息。Redis客户端可以订阅任意数量的频道。二、发布订阅原理        Redis是使用C实现的,通过分析Redis... 查看详情

redispub/sub发布订阅模式的深度解析与实现消息队列(代码片段)

...dis的Pub/Sub的相关命令和优缺点,以及如何实现简单的消息队列。文章目录1Pub/Sub的概述2订阅3取消订阅4模式匹配5发布6Pub/Sub原理6.1pubsub_channels6.2pubsub_patterns7Pub/Sub缺点1Pub/Sub的概述我们可以利用Redis的List数据结构实现一个简单... 查看详情

redis源码阅读-发布与订阅pub/sub(代码片段)

redis的发布订阅(pub/sub)是一种消息通信模式,由发布者(pub)发布消息,订阅者订阅(sub)消息。redis通过publish和subscribe等命令实现了发布与订阅模式。我们先通过一张图了解下工作机制:我们看下案... 查看详情

redis学习(代码片段)

一、Redis发布订阅1、Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。2、Redis客户端可以订阅任意数量的频道。比如你订阅了银行的频道,当你的资金发生变动时,银行就会通过它的频道给你... 查看详情

我在集群 node.js/socket.io/redis pub/sub 应用程序中收到重复消息

】我在集群node.js/socket.io/redispub/sub应用程序中收到重复消息【英文标题】:I\'mreceivingduplicatemessagesinmyclusterednode.js/socket.io/redispub/subapplication【发布时间】:2012-01-1121:22:22【问题描述】:我正在使用Node.js、带有Redisstore的Socket.io、... 查看详情

消息队列和缓存的区别

参考技术Aredis消息推送(基于分布式pub/sub)多用于实时性较高的消息推送,并不保证可靠。其他的mq和kafka保证可靠但有一些延迟(非实时系统没有保证延迟)。redis-pub/sub断电就清空,而使用redis-list作为消息推送虽然有持久化... 查看详情

如何使用当前的 pubsub 订阅者从 google Pub/Sub 系统获取消息

】如何使用当前的pubsub订阅者从googlePub/Sub系统获取消息【英文标题】:HowtogetmessagesfromgooglesPub/Subsytsembyusingthecurrentpubsubsubsciber【发布时间】:2019-06-0909:09:58【问题描述】:我需要使用基于python的订阅者从googlesPub/Sub系统接收已发... 查看详情

redis pub/sub 订阅返回连接错误

...简单的socket.io服务器,并在客户端向我的频道发送了一条消息,socket.io服务器能够 查看详情

Redis Pub/Sub 聊天室

...发布到频道x时,被订阅频道y的客户仍然得到相同的结果消息..我正在使用r 查看详情