MongoDB与Redis的结合

100

请问有哪些例子可以说明同时使用Redis和MongoDB会有什么好处?

3个回答

162
Redis和MongoDB可以一起使用,效果很好。一个以运行MongoDB、Redis(以及MySQL和Sphinx)而闻名的公司是Craiglist。请查看Jeremy Zawodny的此演示文稿
MongoDB适用于持久化、面向文档的数据以多种方式索引。Redis更适用于易失性数据或延迟敏感的半持久性数据。
以下是在MongoDB之上使用Redis的一些具体示例。
  • MongoDB 2.2之前没有过期机制,无法真正使用固定集合来实现TTL。Redis具有基于TTL的过期机制,便于存储易失性数据。例如,用户会话通常存储在Redis中,而用户数据将存储和索引在MongoDB中。请注意,MongoDB 2.2引入了低精度的过期机制,可用于清除数据等操作。

  • Redis提供了方便的集合数据类型及其相关操作(多个集合的联合、交集、差集等)。在此功能上实现基本的分面搜索或标记引擎非常容易,这是对MongoDB更传统索引能力的有趣补充。

  • Redis支持高效的阻塞弹出操作列表。这可用于实现即席分布式排队系统。它比MongoDB的可追溯游标更加灵活,因为后端应用程序可以侦听几个队列并设置超时时间,原子地将项目转移到另一个队列中等等。如果应用程序需要一些排队,则将队列存储在Redis中,并将持久性功能数据保留在MongoDB中。

  • Redis还提供了发布/订阅机制。在分布式应用程序中,事件传播系统可能很有用。这再次是Redis的一个绝佳用例,而持久数据存储在MongoDB中。

因为使用MongoDB比Redis更容易设计数据模型(Redis更低级),所以利用MongoDB的灵活性作为主要持久化数据,同时利用Redis提供的附加功能(低延迟、项目过期、队列、发布/订阅、原子块等)是有趣的。这确实是一个很好的组合。
请注意,永远不要在同一台机器上运行Redis和MongoDB服务器。MongoDB内存被设计为可以交换出去,而Redis则不行。如果MongoDB触发了一些交换活动,Redis的性能将会非常糟糕。它们应该在不同的节点上进行隔离。

19
MongoDB 2.2 (刚刚发布)添加了TTL支持,从而解决了您提出的第一个问题:http://docs.mongodb.org/manual/tutorial/expire-data/。 - John Zwinck
每个方面的比较优势都有很棒的观点。 - Brian Bulkowski
2
关于每个比较优势的一些重要观点。Redis 的一个亮点是为内存调优。还有其他专注于低延迟的项目,例如 AerospikeDB,这些项目专注于集群和可靠性,以及固态硬盘存储,当实时使用情况超出 Redis 能够轻松处理的范围时可以使用它们。 - Brian Bulkowski
1
Jeremy Zawodny的演讲视频:https://www.youtube.com/watch?v=qFcB1Xw1WSk - Frankenmint

26

很明显,两者之间有远远更多的不同之处,但对于一个极高层次的概述:

在用例方面:

  • Redis通常用作分布式计算的缓存层或共享白板。
  • MongoDB通常用作传统SQL数据库的替换。

技术上:

  • Redis是一种内存数据库,具有磁盘持久性(整个数据库需要适合RAM)。
  • MongoDB是一种基于磁盘的数据库,只需要足够的RAM来存放索引。

它们有些重叠,但同时使用它们是非常普遍的。原因如下:

  • MongoDB可以以更便宜的价格存储更多的数据。
  • Redis对于整个数据集来说更快。
  • MongoDB的文化是“存储所有数据,稍后确定访问模式”
  • Redis的文化是“仔细考虑如何访问数据,然后存储”
  • 两者都有依赖它们的开源工具,其中许多工具被一起使用。

Redis可以用作传统数据存储的替代品,但通常与其他正常的“长”数据存储一起使用,如Mongo、Postgresql、MySQL等。


1
Redis可以作为MongoDB缓存服务器出色地工作。以下是其工作原理。
每当mongoose发出缓存查询时,它首先会转到缓存服务器。
缓存服务器将检查是否以前曾发出过该确切查询。
如果没有,则缓存服务器将获取查询并将其发送到mongodb,Mongo将执行查询。
然后我们将获取该查询的结果,再返回到缓存服务器,缓存服务器将在自身上存储查询结果。
它会说每次我执行该查询,我得到这个响应,因此它将维护发出的查询和来自这些查询的响应之间的记录。
缓存服务器将获取响应并将其发送回mongoose,mongoose将将其提供给express,并最终进入应用程序。
每当再次发出完全相同的查询时,mongoose将向缓存服务器发送相同的查询,但是如果缓存服务器看到此查询以前已经发出,则不会将查询发送到mongodb,而是立即将上次收到的查询响应发送回mongoose。 这里没有索引,也没有完整的表扫描。
我们正在进行一个简单的查找,以确定此查询是否已执行。是的?好的,立即将请求发送回去,不要向mongo发送任何内容。
我们有mongoose服务器、缓存服务器(Redis)和Mongodb。
在缓存服务器上,可能有一个数据存储器,其中所有键都是之前发出的某种类型的查询,而值则是该查询的结果。
所以也许我们正在查找一堆由_id组成的博客文章。
所以这里的键可能是我们以前查找过的记录的_id。
所以让我们想象一下,mongoose发出了一个新的查询,试图找到_id为123的博客文章,查询流入缓存服务器,缓存服务器将检查是否有任何查询正在查找_id为123的结果。
如果它不存在于缓存服务器中,则将该查询取出并发送到mongodb实例。Mongodb将执行查询,获取响应并发送回来。
这个结果被发送回到缓存服务器,缓存服务器将接收到的结果立即发送回mongoose,以便我们尽可能地快速获得响应。
接下来,缓存服务器将接收到发出的查询,并将其添加到已发出查询的集合中,并将查询结果存储在查询旁边。因此,我们可以想象,在未来再次发出相同的查询时,它会命中缓存服务器,查看它拥有的所有密钥,并说:“哦,我已经找到了那篇博客文章”,它不会连接Mongo,只需获取查询结果并直接发送给Mongoose。我们没有执行复杂的查询逻辑、没有索引等。它尽可能快速,是一个简单的键值查找。这就是缓存服务器(Redis)与MongoDB配合工作的概述。现在还有其他问题。我们是否永久缓存数据?如何更新记录?我们不希望总是将数据存储在缓存中并从缓存中读取。缓存服务器不用于任何写入操作。缓存层仅用于读取数据。如果我们要写入数据,写入将始终转到mongodb实例,并且我们需要确保每次写入数据时,清除与Mongo中刚刚更新的记录相关的缓存服务器上存储的任何数据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接