我正在用MongoDB支持一个实时websocket服务器应用程序.

客户群正在增长,单线程性能已经不够.我需要一个发布/订阅层来跨线程分发消息.

我通常会 Select Redis,但由于应用程序已经使用MongoDB,我可以使用可定制的游标避免依赖性.然而,我担心性能.

MongoDB的可定制游标性能与Redis在pub/sub架构中的性能相比如何?

推荐答案

实际上,它们是非常不同的动物.

MongoDB可裁剪光标的工作方式有点像队列.它可以与封顶集合一起使用,因此您不必显式删除集合中的项.它非常有效,但请记住,MongoDB会在每次写入操作时锁定整个集合(实际上是数据库),因此它限制了可伸缩性.另一个可伸缩性限制是连接数.每个客户端连接都会在mongod服务器(或mongos)中添加一个连接线程.

尽管如此,你仍然可以期望每秒有数万个项目没有重大问题,这对于一系列应用来说已经足够了.

另一方面,Redis通常可以同时处理更多的连接,因 for each 连接不创建线程(Redis是一个单线程事件循环).它的CPU效率也非常高,因为它不会在所有项目上排队.使用Redis pub/sub,项目将在与发布相同的事件循环迭代中传播到订阅服务器.这些项目甚至没有存储在内存中,Redis甚至没有一个单独的索引需要维护.它们只能从一个套接字缓冲区中检索,并被推入另一个套接字缓冲区.

然而,由于没有排队,Redis发布/订阅消息的传递根本无法保证.如果发布消息时订阅服务器关闭,则该订阅服务器的消息将丢失.

有了Redis,你可以在一个内核上每秒看到数十万个项目,尤其是如果你使用流水线和多个发布客户端的话.

Mongodb相关问答推荐

防止查找简单字段

MongoDB(Mongoose)条件判断没有像我预期的那样工作

如何在MongoDB中查找和过滤嵌套数组

如何填充Mongoose中的嵌套引用

MongoDB:如何从数组中的所有对象中删除属性?

Spring Boot 升级后未映射 Mongo 模板结果

MongoDB:从开始日期和结束日期数组中匹配特定日期的聚合查询

MongoDB C# 驱动程序 - 如何将 _id 存储为 ObjectId 但映射到字符串 Id 属性?

声明多个模式后无法从数据库中获取数据(mongoose + express + mongodb

如何构建我只需要打开一次 mongodb 连接的快速应用程序?

Mongoid 有 Map/Reduce 吗?

具有多个字段的mongodb文本搜索

Mongoose.js 通过一个 connect() 调用创建到 MongoDB 的多个连接

使用 Mongoid 和 Ruby 查询最近 30 天的日期范围?

MongoDB - 我如何找到另一个集合中的文档未引用的所有文档

docker 在不同的端口上运行 mongo 映像

如何在 Meteor 应用程序之间共享 MongoDB 集合?

如何仅通过一次调用将一组对象保存到mongoose数据库?

获取 mongodb 中所有唯一标签的列表

从 Grunt 任务中启动 MongoDB