繁体   English   中英

最佳实践 - 使用mongodb向客户端发送大型文档

[英]Best Practices - Sending clients large documents in mongodb

我正在创建一个大型聊天应用程序,我的同事告诉我应该切换我处理客户端数据的方式。

我使用的是MongoDB,我有多个模式,但关注的是实时聊天模式。

{
    name: String,
    members: Number,
    chatMessages: [{
         message: String,
         date: Number,
         userProfileImage: Number,
         isMod: Boolean
    }],

}

当聊天室很小时,这很好用,但是我意识到我正在向客户端发送大量文件,例如

{
    name: "Chat Room Name",
    members: 123,
    chatMessages: [{
         message: "Example Message",
         date: 1500075913,
         userProfileImage: 352356263,
         isMod: false
    } ... 1000's of times
    ],
}

而且我知道必须有一种更有效的方式,每个用户都获得了这个巨大的文档,但是其中近90%只需要最后50个文档。 经过一段时间的头脑风暴后,我想出了3个可能的解决方案,我不确定应该实施哪一个。

  1. 只需向客户端发送最近50条聊天消息,并使用客户端html页面上的网络套接字来指示它们何时向上滚动到足以需要一组新的50条消息。 我不确定这会有多好,因为我仍然找到文档,并将所有数据存储在一个巨大的对象数组中。
  2. 为消息创建一个新的模式,并描述一个消息ID数组(而不是1000个对象,1000个_id的)。 但是我不确定这是否更有效,因为现在MongoDB将不得不搜索所有已经发出的消息,然后重新填充它们。
  3. 这是我能想到的最有创意的一个,创建一个存储50条消息的模式,在实时聊天模式中只有id引用50消息模式,服务器客户端是最后一个,后续是其他请求由客户通过网络套接字制作。

所以那些是我的尝试,我想知道如何改变我的数据库逻辑,以便尽可能高效和优化。 谢谢。

如果这有帮助,这里有一些数据:

  • 数据库聊天室:1,425
  • 最大的房间:17,000条消息
  • 平均有10%的聊天室:800条消息
  • 底部50%的聊天室平均:35条消息

我会改进所有的逻辑,并改变策略:

  • 每个聊天室都是一个集合
  • 每条消息都是具有唯一增量ID和时间戳的文档

您可以使用findAndModify()按顺序存储消息,并保证ID不会重复。

与大型文档相比,MongoDB在存储数百万个小文档方面要好得多:

我看到的最大的性能打击是文档增长,特别是当您进行大量更新时。 如果文档大小在写入后增加,则必须读取整个文档并将其重写到数据文件的另一部分,并更新索引以指向新位置,这比简单地更新现有文档花费的时间要多得多。

使用MongoDB每天处理20亿份文档和30TB

然后检索最后50个文档是一项微不足道的任务:文档范围是[current ID, current ID - 50] 使用索引,运行起来会非常快。

可以进行垃圾收集以删除低于某个ID的所有消息(例如:25000条消息的历史记录,不再有=>删除ID <max ID - 25000的所有文档)。

最终,您还可以使用MongoDB的上限集合 :它们允许以流式方式(基于事件)进行有序写入和收集消耗。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM