什么时候Redis? 什么时候到MongoDB?
我想要的不是Redis和MongoDB之间的比较。 我知道他们是不同的; 性能和API是完全不同的。
Redis非常快,但API非常“primefaces”。 MongoDB会吃更多的资源,但是这个API非常容易使用,而且我非常满意。
他们都很棒,我想尽可能地使用Redis进行部署,但是很难编写代码。 我想尽可能地在开发中使用MongoDB,但是它需要一个昂贵的机器。
那么你怎么看待这两者的使用呢? 什么时候选Redis? 何时selectMongoDB?
我会说,这取决于你的开发团队和你的应用程序的需要。
例如,如果您需要大量的查询 ,那大多意味着您的开发人员使用Redis的工作量会更大,您的数据可能会存储在各种专用数据结构中,并针对每种types的对象进行自定义以提高效率。 在MongoDB中,相同的查询可能更容易,因为整个数据结构更加一致。 另一方面,在Redis中,对这些查询的响应速度之快就是为了处理数据可能存储的各种结构的额外工作所带来的回报。
MongoDB为具有传统数据库和SQL经验的开发人员提供了简单性,更短的学习曲线。 但是,Redis的非传统方法需要学习更多的努力,但更大的灵活性。
例如。 Redis中可能更好地实现caching层。 对于更多可模式化的数据,MongoDB更好。 [注意:MongoDB和Redis在技术上都是无模式的]
如果你问我,我个人的select是Redis的大部分要求。
我只是注意到这个问题是相当古老的。 不过,我认为以下几个方面值得一提:
-
如果您还不知道如何查询数据,请使用MongoDB。
MongoDB适用于Hackathons,初创公司或每次不知道如何查询插入的数据。 MongoDB不会对您的底层架构做任何假设。 虽然MongoDB是无模式和非关系的,但这并不意味着根本没有模式。 它只是意味着你的模式需要在你的应用程序中定义(例如使用Mongoose)。 除此之外,MongoDB非常适合原型devise或尝试。 它的performance并不好,不能与Redis相提并论。
-
使用Redis来加速您现有的应用程序。
Redis可以很容易地集成为一个LRUcaching 。 使用Redis作为独立的数据库系统是非常罕见的(有些人更喜欢将其称为“键值”存储)。 像Craigslist这样的网站在主数据库旁边使用了Redis 。 Antirez(Redis的开发者)使用Lamernews表明,使用Redis作为独立的数据库系统确实是可行的。
-
Redis不会根据您的数据做出任何假设。
Redis提供了一些有用的数据结构(例如集合,哈希,列表),但是你必须明确地定义你想要如何存储数据。 简而言之,可以使用Redis和MongoDB来实现类似的function。 Redis只是更快,但不适合原型。 这是一个典型的情况,你通常喜欢MongoDB。 除此之外,Redis 真的很灵活。 它提供的基础数据结构是高性能DB系统的构build块。
何时使用Redis?
-
高速caching
使用MongoDB进行caching根本没有什么意义。 这太慢了。
-
如果你有足够的时间考虑你的数据库devise。
你不能简单地把你的文档扔进Redis。 你必须考虑你想要存储和组织数据的方式。 Redis中有一个例子是哈希。 它们与“传统的”嵌套对象完全不同,这意味着您将不得不重新考虑存储嵌套文档的方式。 一种解决scheme是将散列内的引用存储到另一个散列(类似key:[第二个散列的id] )。 另一个想法是将其存储为JSON,这对于大多数拥有* SQL背景的人来说似乎是违反直觉的。
-
如果你需要真正的高性能。
击败Redis提供的性能几乎是不可能的。 想象一下你的数据库和你的caching一样快。 这就是使用Redis作为真正的数据库的感觉。
-
如果你不关心缩放。
缩放Redis并不像以前那么辛苦。 例如,您可以使用一种代理服务器来在多个Redis实例之间分配数据。 主从复制并不复杂,但是在多个Redis实例中分发密钥需要在应用程序站点上完成(例如使用散列函数,Modulo等)。 通过比较来缩放MongoDB要简单得多。
何时使用MongoDB
-
原型,初创公司,Hackathons
MongoDB非常适合于快速原型devise。 不过,performance并不好。 另外请记住,您很可能必须在应用程序中定义某种模式。
-
当你需要快速改变你的模式。
因为没有图式! 在传统的关系数据库pipe理系统中改变表格是非常昂贵和缓慢的。 MongoDB通过不对底层数据做出很多假设来解决这个问题。 尽pipe如此,它试图尽可能地优化,而不需要你定义一个模式。
TL; DR – 如果性能很重要,并且愿意花时间优化和组织数据,请使用Redis。 – 如果你需要build立一个原型而不用担心你的数据库,可以使用MongoDB。
进一步阅读:
- 使用Redis作为主要数据存储时需要考虑的有趣方面
Redis的。 假设你已经用php写了一个网站, 无论出于何种原因,它变得stream行起来,超前于它,或者已经色情。 你意识到这个PHP真是太慢了,“我会失去我的粉丝,因为他们不会等待一个页面10秒。 你有一个突然的认识,一个网页有一个不变的url(它永远不会改变,哇),如果你愿意,主要关键,然后你记得,内存是快的,而磁盘缓慢,PHP甚至更慢。 :(然后你使用内存和这个URL来调用一个存储机制,在你决定调用“value”的网页内容的时候,你调用一个“key”,这就是你所拥有的全部内容 – 键和内容,你称之为“meme cache”。你喜欢理查德·道金斯(Richard Dawkins),因为他太棒了,像caching你的html一样,松鼠caching他们的坚果,你不需要重写你的垃圾代码,你很高兴,然后你看到其他人已经做到了 – 但是你select了Redis,因为其他人混淆猫的图像,一些与f牙。
蒙戈。 你写了一个网站。 哎,你写了很多,用任何语言。 你意识到,你的大部分时间都花在编写这些臭鼬SQL子句上。 你不是一个DBA,但你在那里,写愚蠢的SQL语句…不只是一个,而是到处都是。 “select这个,select”。 但是特别的是,你还记得那个让人讨厌的WHERE子句。 凡姓氏等于“桑顿”,电影等于“坏圣诞老人”。 Urgh。 你想:“为什么dbas只是做他们的工作,给我一些存储过程呢?” 然后你忘记了一些次要的字段,例如middlename,然后你必须删除表格,导出所有10G的大数据,并用这个新的字段创build另一个,并导入数据,并在接下来的14天内继续执行10次继续记住像称呼,标题的废话,再加上地址的外键。 然后你认为姓氏应该是姓氏。 几乎每天都有一个变化。 然后你说darnit。 我必须去写一个网站/系统,而不必介意这个数据模型BS。 所以你谷歌,“我讨厌写SQL,请不要SQL,让它停止”,但popup'nosql',然后你读了一些东西,它说它只是转储数据没有任何架构。 你还记得上周的惨败,更多的桌子和微笑。 那么你selectmongo是因为一些像“airbud”这样的租赁网站使用它。 甜。 没有更多的数据模型的变化,因为你有一个模型,你只是不断变化。
也许这个资源有助于两者之间的决定。 它还讨论了其他几个NoSQL数据库,并提供了一个简短的特性列表,以及“我将如何使用它”的解释。
难以回答的问题 – 与大多数技术解决scheme一样,这取决于您的情况,既然您没有描述您正在尝试解决的问题,那么如何提出解决scheme?
你需要testing他们两个,看看他们中的哪一个满足你的需求。
据说,MongoDB不需要任何昂贵的硬件。 像任何其他数据库解决scheme一样,使用更多的CPU和内存可以更好地工作,但当然不是必需的 – 特别是对于早期的开发目的。
Redis是内存数据存储,可以将其状态保存到磁盘 (以便在重新启动后启用恢复)。 但是,作为内存数据存储意味着数据存储(在单个节点上)的大小不能超过系统上的总内存空间(物理RAM +交换空间)。 实际上,Redis将会less得多,因为Redis正在与系统上的许多其他进程共享这个空间,而且如果耗尽系统内存空间,它很可能会被操作系统中止。
Mongo是一个基于磁盘的数据存储,当它的工作集适合物理RAM(如所有软件)时,它是最有效的。 作为基于磁盘的数据意味着对Mongo数据库的大小没有内在的限制,但是configuration选项,可用磁盘空间和其他问题可能意味着数据库大小超过一定限制可能变得不切实际或效率低下。
Redis和Mongo都可以进行集群以实现高可用性,备份和增加数据存储的整体大小。
所有的答案(在撰写本文时)都假设Redis,MongoDB和基于SQL的关系数据库都是基本相同的工具:“存储数据”。 他们根本不考虑数据模型。
MongoDB:复杂的数据
MongoDB是一个文档存储。 与SQL驱动的关系数据库进行比较:关系数据库简化了索引的CSV文件,每个文件都是一个表; 文档商店简化索引JSON文件,每个文件是一个文件,多个文件分组在一起。
JSON文件在结构上与XML和YAML文件相似,而且与Python中的字典相似,所以请根据这种层次结构考虑您的数据。 索引时,结构是关键:文档包含命名键,其中包含其他文档,数组或标量值。 考虑下面的文件。
{ _id: 0x194f38dc491a, Name: "John Smith", PhoneNumber: Home: "555 999-1234", Work: "555 999-9876", Mobile: "555 634-5789" Accounts: - "379-1111" - "379-2574" - "414-6731" }
上面的文档有一个键值PhoneNumber.Mobile
,其值为555 634-5789
。 您可以search关键字PhoneNumber.Mobile
具有一定价值的文档集合; 他们被索引。
它也有一系列的Accounts
,其中包含多个索引。 可以查询一个文档,在这个文档中, Accounts
包含一些值的子集, 所有的值的子集,或者任何一个值的子集。 这意味着您可以searchAccounts = ["379-1111", "379-2574"]
并找不到上述; 你可以searchAccounts includes ["379-1111"]
并find上面的文件; 您可以searchAccounts includes any of ["974-3785","414-6731"]
并find上述和任何文件包括帐户“974-3785”,如果有的话。
文件要尽可能深。 PhoneNumber.Mobile
可以容纳一个数组,甚至一个子文档( PhoneNumber.Mobile.Work
和PhoneNumber.Mobile.Personal
)。 如果你的数据是高度结构化的,文档是关系数据库的一大步。
如果你的数据大部分是平坦的,关系数据和严格的结构,你最好用关系数据库。 此外,最重要的是您的数据是否最适合于相互关联的CSV文件集合或XML / JSON / YAML文件集合。
对于大多数项目,您必须妥协,在SQL或文档商店不适合的一些小范围内接受一个小的解决办法; 对于一些存储广泛数据的大型复杂项目(很多列;行是不相关的),将一些数据存储在一个模型中,将另一些数据存储在另一个模型中是有意义的。 Facebook使用SQL和graphics数据库(数据放入节点,节点连接到其他节点); Craigslist曾经使用过MySQL和MongoDB,但一直在研究MongoDB。 如果放在一个模型下,这些数据的跨度和关系面临重大障碍。
Redis:关键价值
Redis基本上是一家重要的商店。 Redis让你给它一个键,并查找一个单一的值。 Redis本身可以存储string,列表,哈希和其他一些东西; 但是,它只是按名称查找。
caching失效是计算机科学的难题之一, 另一个是命名的东西。 这意味着当你想避免数百个额外的查询到后端时,你会使用Redis,但是当你需要一个新的查询时你必须弄清楚。
最明显的失效案例是更新写:如果你阅读的user:Simon:lingots = NOTFOUND
,你可能会SELECT Lingots FROM Store s INNER JOIN UserProfile u ON s.UserID = u.UserID WHERE u.Username = Simon
和存储结果, 100
,作为SET user:Simon:lingots = 100
。 然后当你授予西蒙5 lingots,你读取user:Simon:lingots = 100
, SET user:Simon:lingots = 105
,和UPDATE Store s INNER JOIN UserProfile u ON s.UserID = u.UserID SET s.Lingots = 105 WHERE u.Username = Simon
。 现在,您的数据库和Redis中有105个,并且可以在不查询数据库的情况下获得user:Simon:lingots
。
第二种情况是更新依赖信息。 假设您生成一个页面块并caching它们的输出。 标题显示玩家的经验,级别和金额; 玩家的个人资料页面有一个显示其统计数据的块; 等等。 玩家获得一些经验。 那么,现在你有几个templates:Header:Simon
, templates:StatsBox:Simon
, templates:GrowthGraph:Simon
等等,你已经caching了通过模板引擎运行的六个数据库查询的输出。 通常,当你显示这些页面时,你会说:
$t = GetStringFromRedis("templates:StatsBox:" + $playerName); if ($t == null) { $t = BuildTemplate("StatsBox.tmpl", GetStatsFromDatabase($playerName)); SetStringInRedis("Templates:StatsBox:" + $playerName, $t); } print $t;
由于您刚刚更新了GetStatsFromDatabase("Simon")
的结果, GetStatsFromDatabase("Simon")
必须将templates:*:Simon
从键值caching中删除。 当你试图呈现任何这些模板时,你的应用程序将从你的数据库中取出数据(PostgreSQL,MongoDB)并将其插入到你的模板中; 那么它将把结果存储在Redis中,并且希望在下一次显示那个输出块时,不要打扰数据库查询和渲染模板。
Redis还可以让你做发布者订阅消息队列等。 这完全是另一个话题。 这里指的是Redis是一个键值caching,它不同于关系数据库或文档存储。
结论
根据您的需求select您的工具。 最大的需求通常是数据模型,因为这决定了代码的复杂性和容错性。 专门的应用程序将依靠性能,在所有的地方你写一切混合的C和大会; 大多数应用程序将只处理generics情况,并使用Redis或Memcached等caching系统,这比高性能SQL数据库或文档存储快得多。
如果你有足够的内存,你就不能使用。 Redis和MongoDB的价格是一个通用工具。 这引入了很多开销。
有人说Redis比Mongo快10倍。 这可能不是真的了。 MongoDB(如果我没记错的话)声称只要内存configuration相同,就可以击败memcache来存储和caching文件。
无论如何。 Redis很好,MongoDB很好。 如果你关心的子结构,并需要聚合去MongoDB。 如果存储密钥和值是你主要关心的所有关于Redis的。 (或任何其他键值存储)。
Redis和MongoDB都是非关系数据库,但它们是不同的类别。
Redis是一个Key / Value数据库,它使用内存存储,使其超快速。 这是一个很好的候选人caching的东西和临时数据存储(在内存中)和大多数云平台(如Azure,AWS)支持它,它的内存使用量是可扩展的。但是如果你要在你的机器上使用它有限的资源,考虑它的内存使用情况。
另一方面,MongoDB是一个文档数据库。 保存大量的文本,图像,video等,以及几乎所有与数据库有关的事务都是很好的select。例如,如果您想要开发博客或社交networking,MongoDB是一个合适的select。 可扩展的扩展策略。 它使用磁盘作为存储介质,所以数据将被保存。
如果您的项目有所增长,可以在您的环境中拥有足够的RAM内存 – 回答是Redis。 特别是考虑到具有群集function的新Redis 3.2。