MongoDB 架构设计 - 实时聊天

2024-04-08

我正在启动一个项目,我认为该项目特别适合 MongoDB,因为它提供的速度和可扩展性。

我目前感兴趣的模块是与实时聊天有关的。如果我要在传统的 RDBMS 中执行此操作,我会将其分为:

  • 频道(一个频道有很多用户)
  • 用户(一个用户有一个频道但有多条消息)
  • 消息(一条消息有一个用户)

出于此用例的目的,我假设通常有 5 个通道同时处于活动状态,每个通道每秒最多处理 5 条消息。

需要快速的特定查询:

  • 获取新消息(基于书签、时间戳,或者递增计数器?)
  • 将消息发布到频道
  • 验证用户是否可以在频道中发帖

请记住,MongoDB 的文档限制为 4mb,您将如何设计架构?你的会是什么样子?有什么我应该注意的问题吗?


I used Redis http://code.google.com/p/redis/、NGINX 和 PHP-FPM 用于我的聊天项目。不是超级优雅,但它确实有效。这个谜题有几个部分。

  1. 有一个非常简单的 PHP 脚本,它接收客户端命令并将它们放入一个庞大的列表中。它还检查所有房间列表和用户私有列表,以查看是否有必须传递的消息。这是由用 jQuery 编写的客户端进行轮询的,每隔几秒就会完成一次。

  2. 有一个命令行 PHP 脚本以每秒 20 次的无限循环操作服务器端,检查此列表,然后处理这些命令。脚本在脚本内存中处理谁在哪个房间以及权限,此信息不存储在 Redis 中。

  3. Redis 为每个房间都有一个 LIST,为每个用户提供一个 LIST,作为私有队列运行。它还为用户所在的每个房间提供多个计数器。如果用户计数器小于房间中的消息总数,则它会获取差值并将其发送给用户。

我无法对这个解决方案进行压力测试,但至少从我的基本基准测试来看,它可能每秒可以处理数千条消息。还有机会将其移植到 Node.js 之类的东西以提高性能。 Redis 也正在成熟,并且具有一些有趣的功能,例如发布/订阅命令,这些功能可能会令人感兴趣,这可能会消除服务器端的轮询。

我研究了基于 Comet 的解决方案,但其中许多都很复杂,文档记录很差,或者需要我学习一种全新的语言(例如 Jetty->Java、APE->C)等...此外,交付和通过代理有时也可以是彗星的一个问题。这就是我坚持民意调查的原因。

我想你可以用 MongoDB 做类似的事情。每个房间一个集合,每个用户一个集合,然后是一个维护计数器的集合。您仍然需要编写后端守护程序或脚本来处理这些消息的去向。您还可以使用 MongoDB 的“有限集合”,它可以保持文档排序并自动清除旧消息,但这在维护适当的计数器方面可能会很复杂。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MongoDB 架构设计 - 实时聊天 的相关文章

  • 在 Morphia 中,我如何更新 ArrayList 中的一个嵌入对象

    使用 Mongodb 与 Morphia 确实很陌生 并且看到了许多如何执行此操作的高级答案 如果可能的话我想做简单的并且我有这个 Embedded对象称为 fileObjects其中包含Files对象 我无法更新里面的字段Files 我只
  • 使用 sidekiq 只执行众多重复作业之一?

    我有一个后台作业 在 MongoDB 上执行映射 归约作业 当用户向文档发送更多数据时 它会启动在文档上运行的后台作业 如果用户发送多个请求 它将启动同一文档的多个后台作业 但实际上只有一个需要运行 有没有办法可以防止多个重复实例 我正在考
  • Mongoose 使用 GeoJSON 点作为查询参数调用 geoNear 不起作用

    给定一个为包含 GeoJSON 位置的文档定义的模式 var BranchSchema new Schema location type type String required true enum Point LineString Pol
  • RabbitMQ 管理插件窗口呈现为空白页面

    I have installed Erlang RabbitMQ and configured the management plugin as per the instructions on the website https www r
  • 使用 Morphia 配置 Spring Boot?

    我不想利用 Spring DATA MongoDB 支持 我想利用名为 Morphia 的 MongoDB ORM https github com mongodb morphia https github com mongodb morp
  • 如何:SQL 还是 NOSQL?

    我还没有遇到过这个问题 但这就是我的想法 非常肤浅和简单化恕我直言 如果您有键值类型的存储 并且所有访问都是键查找 请使用 NOSQL 解决方案 如果您想要基于值 和子值 进行查找或者有一些更复杂的东西 例如联接 您会选择关系解决方案 事务
  • ScyllaDB 是否支持 OR 运算符?

    scyladb 中 SELECT 语句的 WHERE 子句中的 OR 条件如何工作 我已经在电子邮件上创建了二级索引 下面的查询工作正常并返回结果 cqlsh gt select from test d emp where email em
  • 基于多线程的 RabbitMQ 消费者

    我们有一个 Windows 服务 它监听单个 RabbitMQ 队列并处理消息 我们希望扩展相同的 Windows 服务 以便它可以监听 RabbitMQ 的多个队列并处理消息 不确定使用多线程是否可以实现这一点 因为每个线程都必须侦听 阻
  • 我可以按日期查询 MongoDB ObjectId 吗?

    我知道 ObjectId 包含它们的创建日期 有没有办法查询ObjectId的这方面 将时间戳弹出到 ObjectId 中 http www kchodorow com blog 2011 12 20 querying for timest
  • MongoDB 查询返回空数组

    有一个基本的 Express 应用程序连接到几乎 0 5 GB 的 MongoDB 数据库 当我运行时 router get function req res next medical data find State CT function
  • 如何使用c#从数据桶中获取所有文档?

    如何获取数据桶中的所有文档 我尝试过一个示例 但我只能获得一个特定的文档 这是我的代码 CouchbaseClient oclient oclient new CouchbaseClient vwspace data bucket name
  • Inno Setup安装先决条件[重复]

    这个问题在这里已经有答案了 我正在通过 Inno Setup 创建一个安装程序 我看到很多关于如何检测先决条件是否存在的代码示例 但没有任何关于当我找不到先决条件时如何实际安装先决条件的代码示例 我确信它非常简单 但是我该如何安装先决条件呢
  • 重命名 MongoDB 数组中嵌入文档中的字段不起作用

    Step One gt db myCollection find id ObjectId 2358523892345 field1 value 1 field2 subfield1 value 2 Subfield2 value 3 fie
  • 使用 Javascript 和 Mongodb 对时间序列数据重新采样

    时间序列数据的数据集需要从具有不规则时间间隔的数据集转换为规则时间序列 可能使用插值和重采样 蟒蛇的pandas Dataframe resample http pandas pydata org pandas docs stable ge
  • ActiveMQ发送ObjectMessage

    我正在使用 ActiveMQ 在我当前的项目中实现消息系统 我需要发送和接收 Java 对象 而不是简单的文本或二进制消息 Java 对象 我的消息对象 根据需要实现了 Serialized 接口 ActiveMQ 的最新版本添加了一些安全
  • 如何使用 Sails.js 和 Waterline 更新 MongoDB 子文档中的特定键?

    当尝试使用 Sails js 和 Waterline ORM 更新 MongoDB 子文档中的单个键时 我遇到了问题 这就是我的person js模型看起来像 module exports attributes name type stri
  • 在 MongoDB 中,如何根据嵌入对象中的属性对文档进行排序?

    在我的产品集合中 我可以找到已在 GB 地区发布的所有产品 gt db products find release region GB pretty id foo release region GB date ISODate 2012 03
  • 在 MongoDb 上序列化仅获取属性

    使用 C 6 我可以写 public class Person public Guid Id get public string Name get public Person Guid id string name Id id Name n
  • 嵌入文档中的mongodb限制

    我需要创建一个消息系统 一个人可以在其中与许多用户进行对话 例如 我开始与 user2 user3 和 user4 交谈 因此他们中的任何人都可以看到整个对话 并且如果对话在任何时候都不是私密的 则任何参与者都可以将任何其他人添加到对话中
  • Spring Data MongoDB 和批量更新

    我正在使用 Spring Data MongoDB 并且想要执行批量更新 就像此处描述的那样 http docs mongodb org manual reference method Bulk find update Bulk find

随机推荐

  • 用于旋转 QWidget 的 QPropertyAnimation

    我是 Qt 新手 遇到一些问题QWidget回转 我在 QLabel 中有一个 QPixmap 我想要的是让它连续旋转 90 度 I know QPropertyAnimation我知道如何使用它 但我正在努力解决如何使用它来旋转QWidg
  • 向下滑动动画Angular 4

    我正在尝试为我的页面添加动画效果 但遇到以下问题 我的页面上有内容 div 以及一个可在内容上方打开另一个 div 的按钮 我希望该 div 淡出并滑入 并且下面的 div 也向下 向上滑动 我为上面的 div 创建了我想要的动画 该动画在
  • 如何删除 JavaScript 数组元素并重置键

    我有一个如下所示的数组 var fields name mark age 23 name smith age 28 name kelvin age 25 name micheal age 22 我知道字段现在将具有索引 键 0 1 2 3
  • 找出哪些超类包含属性或方法实现

    如果我已经正确记录了方法或属性 我可以通过键入找到它的定义位置help class method 这会告诉我Help for class method is inherited from superclass otherclass 通常 这
  • 为什么 Android 中的 Loader 很糟糕

    我读过几条推文和评论 说装载机很糟糕 使用它们是 朝自己脸上开枪 的好方法 还普通人宣布他将停止他的图书馆的任何工作 Loaderex 平民还说 加载器是一个失败的抽象 我显然在这里遗漏了一些东西 我想了解更多信息并了解为什么装载机不好以及
  • 如何删除具有相同imageID的多个docker镜像?

    我创建了一个本地 Docker 注册表 https docs docker com registry deploying 然后从 docker hub 中提取一些 docker 镜像 然后将它们推送到本地注册表 现在我想删除我的本地图像 但
  • QT - 将按钮放在右下角

    我正在尝试放置一组按钮 以便它们固定在屏幕的右下角 我的问题是 每当我调整屏幕大小时 按钮都不会固定在右下角 而是保留在当前位置 我在水平布局中放置了两个按钮 然后 我将此布局放置在网格布局内 其中包含水平和垂直间隔符 我已将网格布局的la
  • AVAudioCompressedBuffer 到 UInt8 数组,反之亦然

    我想知道如何获取 AVAudioCompressedBuffer 的字节 然后 从字节重建 AVAudioCompressedBuffer 下面的代码采用 AVAudioPCMBuffer 使用 AVAudioConverter 将其压缩为
  • 了解 Firebug 探查器输出

    我一直在尝试使用 Firebug 的分析器来更好地理解我们所看到的一些 JavaScript 性能问题的根源 但我对输出有点困惑 当我分析一些代码时 分析器会报告配置文件 464 323 毫秒 26 412 次调用 我怀疑 464 323
  • 操作员 '??'不能应用于子类类型的操作数

    以下代码给出了 Main 函数第二行标题中的错误 public class P public class B P public class A P void Main P p GetA GetB public A GetA return n
  • iOS 11 AVPlayer 在 KVO 时崩溃

    我在使用时遇到了奇怪的崩溃AVPlayer播放远程视频 从崩溃登录Fabric 应用程序在系统线程上崩溃 com apple avfoundation playerlayer configuration 崩溃日志如下 Crashed com
  • perl:一个父母,许多孩子 - 父母中的单管道阅读器?

    在perl中是否可以以这样一种方式建立一个管道 即父管道只有一个READER管道 并且许多子管道在它们启动 退出时写入它 典型的食谱代码是 usr bin perl w pipe2 use pipe and fork so child ca
  • 检索 iOS 中所有联系人的电话号码

    到目前为止 我看到了如果我显示一个选择器 则可以获取多个电话号码的方法 以便用户可以选择人员 然后获取电话号码 我想要的是检索所有联系人的号码 有可能吗 试试这个它适用于iOS 6 以及 iOS 5 0 或更早版本 示例项目演示 https
  • 如何在Vim终端模式下复制粘贴?

    我经常想从 terminal窗口到普通文本缓冲区 此刻我exitshell 会话并从历史记录中复制 一定有更好的方法 Copy To copy from a terminal window press CTRL W N This is a
  • 提交表单时Spring绑定异常

    卡住了 不知道为什么 Spring Form 在 get 中预填充时无法成功提交 给出绑定问题 Request call loadForm 但在方法中填充时工作正常setupFormObject with ModelAttribute注释标
  • wkhtmltopdf 和基于表单的身份验证

    我有一个使用基于表单的身份验证的应用程序 我正在尝试获取应用程序中页面的副本并使用 wkhtmltopdf 将其保存为 PDF wkhtmltopdf 已安装并且工作正常 我可以从应用程序内成功调用它来生成另一个网站的 PDF 无需身份验证
  • Rails has_many 自引用

    我的帐户模型如下 简化 class Account lt ActiveRecord Base attr accessible account number display name master account id has many ch
  • 如何在python中更改iBus输入法?

    我正在编写一个 Vim 插件来设置 iBus 引擎和输入法 到目前为止 我可以使用以下代码更改引擎 function im setEngine name python lt lt EOF try import ibus vim bus ib
  • .Net 3.5 日志记录

    我是一个相当新的 C 程序员 我想知道是否有人可以向我提供有关如何在现有解决方案中使用日志框架的更多信息 如果您这么称呼它 我正在尝试记录我正在做的项目 我想知道有哪些好的和简单的框架以及它们应该如何实现 我应该研究一个特定的主题吗 我还没
  • MongoDB 架构设计 - 实时聊天

    我正在启动一个项目 我认为该项目特别适合 MongoDB 因为它提供的速度和可扩展性 我目前感兴趣的模块是与实时聊天有关的 如果我要在传统的 RDBMS 中执行此操作 我会将其分为 频道 一个频道有很多用户 用户 一个用户有一个频道但有多条