我想要的不是Redis和MongoDB之间的比较。我知道它们是不同的;性能和API是完全不同的。

Redis非常快,但是API非常“原子化”。MongoDB会消耗更多的资源,但是API非常非常容易使用,我对它非常满意。

它们都很棒,我想在部署中尽可能多地使用Redis,但很难编写代码。我想在开发中尽可能多地使用MongoDB,但它需要一台昂贵的机器。

那么你认为两者的作用是什么呢?什么时候选择Redis?什么时候选择MongoDB?


很难回答的问题——和大多数技术解决方案一样,这真的取决于你的情况,因为你没有描述你正在试图解决的问题,谁能提出解决方案呢?

您需要对它们进行测试,以确定其中哪一个满足您的需求。

也就是说,MongoDB不需要任何昂贵的硬件。与任何其他数据库解决方案一样,它需要更多的CPU和内存才能更好地工作,但肯定不是必需的——特别是对于早期开发目的。

我想说的是,这取决于你所在的开发团队以及你的应用程序需求。

For example, if you require a lot of querying, that mostly means it would be more work for your developers to use Redis, where your data might be stored in variety of specialized data structures, customized for each type of object for efficiency. In MongoDB the same queries might be easier because the structure is more consistent across your data. On the other hand, in Redis, sheer speed of the response to those queries is the payoff for the extra work of dealing with the variety of structures your data might be stored with.

MongoDB为具有传统DB和SQL经验的开发人员提供了简单、更短的学习曲线。然而,Redis的非传统方法需要更多的努力去学习,但更大的灵活性。

如。缓存层可能在Redis中可以更好地实现。对于更多可模式的数据,MongoDB更好。[注:MongoDB和Redis在技术上都是无模式的]

如果你问我,我个人对大多数需求的选择是Redis。

最后,我希望你现在已经看到http://antirez.com/post/MongoDB-and-Redis.html

也许这个资源可以帮助你在两者之间做出选择。 它还讨论了其他几个NoSQL数据库,并提供了一个简短的特征列表,以及对每个数据库的“我将使用它做什么”的解释。

http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis

我只是注意到这个问题已经很老了。不过,我认为以下方面值得补充:

Use MongoDB if you don't know yet how you're going to query your data. MongoDB is suited for Hackathons, startups or every time you don't know how you'll query the data you inserted. MongoDB does not make any assumptions on your underlying schema. While MongoDB is schemaless and non-relational, this does not mean that there is no schema at all. It simply means that your schema needs to be defined in your app (e.g. using Mongoose). Besides that, MongoDB is great for prototyping or trying things out. Its performance is not that great and can't be compared to Redis. Use Redis in order to speed up your existing application. Redis can be easily integrated as a LRU cache. It is very uncommon to use Redis as a standalone database system (some people prefer referring to it as a "key-value"-store). Websites like Craigslist use Redis next to their primary database. Antirez (developer of Redis) demonstrated using Lamernews that it is indeed possible to use Redis as a stand alone database system. Redis does not make any assumptions based on your data. Redis provides a bunch of useful data structures (e.g. Sets, Hashes, Lists), but you have to explicitly define how you want to store you data. To put it in a nutshell, Redis and MongoDB can be used in order to achieve similar things. Redis is simply faster, but not suited for prototyping. That's one use case where you would typically prefer MongoDB. Besides that, Redis is really flexible. The underlying data structures it provides are the building blocks of high-performance DB systems.

什么时候使用Redis?

Caching Caching using MongoDB simply doesn't make a lot of sense. It would be too slow. If you have enough time to think about your DB design. You can't simply throw in your documents into Redis. You have to think of the way you in which you want to store and organize your data. One example are hashes in Redis. They are quite different from "traditional", nested objects, which means you'll have to rethink the way you store nested documents. One solution would be to store a reference inside the hash to another hash (something like key: [id of second hash]). Another idea would be to store it as JSON, which seems counter-intuitive to most people with a *SQL-background. If you need really high performance. Beating the performance Redis provides is nearly impossible. Imagine you database being as fast as your cache. That's what it feels like using Redis as a real database. If you don't care that much about scaling. Scaling Redis is not as hard as it used to be. For instance, you could use a kind of proxy server in order to distribute the data among multiple Redis instances. Master-slave replication is not that complicated, but distributing you keys among multiple Redis-instances needs to be done on the application site (e.g. using a hash-function, Modulo etc.). Scaling MongoDB by comparison is much simpler.

何时使用MongoDB

Prototyping, Startups, Hackathons MongoDB is perfectly suited for rapid prototyping. Nevertheless, performance isn't that good. Also keep in mind that you'll most likely have to define some sort of schema in your application. When you need to change your schema quickly. Because there is no schema! Altering tables in traditional, relational DBMS is painfully expensive and slow. MongoDB solves this problem by not making a lot of assumptions on your underlying data. Nevertheless, it tries to optimize as far as possible without requiring you to define a schema.

博士TL; -如果性能是重要的,你愿意花时间优化和组织你的数据使用Redis。 -使用MongoDB,如果你需要建立一个原型,而不用担心你的DB太多。

进一步阅读:

当使用Redis作为主要数据存储时,需要考虑一些有趣的方面

Redis. Let’s say you’ve written a site in php; for whatever reason, it becomes popular and it’s ahead of its time or has porno on it. You realize this php is so freaking slow, "I’m gonna lose my fans because they simply won’t wait 10 seconds for a page." You have a sudden realization that a web page has a constant url (it never changes, whoa), a primary key if you will, and then you recall that memory is fast while disk is slow and php is even slower. :( Then you fashion a storage mechanism using memory and this URL that you call a "key" while the webpage content you decide to call the "value." That’s all you have - key and content. You call it "meme cache." You like Richard Dawkins because he's awesome. You cache your html like squirrels cache their nuts. You don’t need to rewrite your crap php code. You are happy. Then you see that others have done it -- but you choose Redis because the other one has confusing images of cats, some with fangs.

Mongo. You’ve written a site. Heck you’ve written many, and in any language. You realize that much of your time is spent writing those stinking SQL clauses. You’re not a dba, yet there you are, writing stupid sql statements... not just one but freaking everywhere. "select this, select that". But in particular you remember the irritating WHERE clause. Where lastname equals "thornton" and movie equals "bad santa." Urgh. You think, "why don’t those dbas just do their job and give me some stored procedures?" Then you forget some minor field like middlename and then you have to drop the table, export all 10G of big data and create another with this new field, and import the data -- and that goes on 10 times during the next 14 days as you keep on remembering crap like salutation, title, plus adding a foreign key with addresses. Then you figure that lastname should be lastName. Almost one change a day. Then you say darnit. I have to get on and write a web site/system, never mind this data model bs. So you google, "I hate writing SQL, please no SQL, make it stop" but up pops 'nosql' and then you read some stuff and it says it just dumps data without any schema. You remember last week's fiasco dropping more tables and smile. Then you choose mongo because some big guys like 'airbud' the apt rental site uses it. Sweet. No more data model changes because you have a model you just keep on changing.

如果你有足够的RAM,你应该使用这两种方法。Redis和MongoDB达到了通用工具的价格。这会带来很多开销。

有一种说法是Redis比Mongo快10倍。这可能不再是真的了。MongoDB(如果我没记错的话)声称只要内存配置相同,就可以在存储和缓存文档方面击败memcache。

不管怎样。Redis不错,MongoDB也不错。如果你关心子结构并且需要聚合,那么就选择MongoDB。如果存储键和值是你主要关心的,它都是关于Redis。(或任何其他键值存储)。

Redis是一个在内存中的数据存储,它可以将它的状态持久化到磁盘(以便重启后恢复)。但是,作为内存中的数据存储,意味着数据存储的大小(单个节点上)不能超过系统上的总内存空间(物理RAM +交换空间)。实际上,Redis会与系统上的许多其他进程共享这个空间,如果它耗尽了系统内存空间,它很可能会被操作系统杀死。

Mongo是一个基于磁盘的数据存储,当它的工作集适合物理RAM(像所有软件一样)时,它是最有效的。作为基于磁盘的数据意味着对Mongo数据库的大小没有内在的限制,但是配置选项、可用的磁盘空间和其他问题可能意味着超过一定限制的数据库大小可能变得不切实际或效率低下。

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。移动,值为555 634-5789。您可以搜索一个文档集合,其中键PhoneNumber。移动,有一定的价值;他们的索引。

It also has an array of Accounts which hold multiple indexes. It is possible to query for a document where Accounts contains exactly some subset of values, all of some subset of values, or any of some subset of values. That means you can search for Accounts = ["379-1111", "379-2574"] and not find the above; you can search for Accounts includes ["379-1111"] and find the above document; and you can search for Accounts includes any of ["974-3785","414-6731"] and find the above and whatever document includes account "974-3785", if any.

你想要多深就有多深。PhoneNumber。Mobile可以保存一个数组,甚至一个子文档(PhoneNumber.Mobile。Work和PhoneNumber.Mobile.Personal)。如果您的数据是高度结构化的,文档是关系数据库的一大进步。

如果您的数据主要是平面的、关系的和结构严格的,那么最好使用关系数据库。同样,重要的标志是您的数据模型最适合于相互关联的CSV文件的集合还是XML/JSON/YAML文件的集合。

For most projects, you'll have to compromise, accepting a minor work-around in some small areas where either SQL or Document Stores don't fit; for some large, complex projects storing a broad spread of data (many columns; rows are irrelevant), it will make sense to store some data in one model and other data in another model. Facebook uses both SQL and a graph database (where data is put into nodes, and nodes are connected to other nodes); Craigslist used to use MySQL and MongoDB, but had been looking into moving entirely onto MongoDB. These are places where the span and relationship of the data faces significant handicaps if put under one model.

复述:键值

Redis基本上是一个键值存储。Redis允许你给它一个键,然后查找一个单独的值。Redis本身可以存储字符串、列表、散列和其他一些东西;但是,它只能根据名称查找。

缓存失效是计算机科学的难题之一;另一个是命名。这意味着当你想要避免数百个多余的后端查询时,你会使用Redis,但你必须弄清楚什么时候你需要一个新的查询。

The most obvious case of invalidation is update on write: if you read user:Simon:lingots = NOTFOUND, you might SELECT Lingots FROM Store s INNER JOIN UserProfile u ON s.UserID = u.UserID WHERE u.Username = Simon and store the result, 100, as SET user:Simon:lingots = 100. Then when you award Simon 5 lingots, you read user:Simon:lingots = 100, SET user:Simon:lingots = 105, and UPDATE Store s INNER JOIN UserProfile u ON s.UserID = u.UserID SET s.Lingots = 105 WHERE u.Username = Simon. Now you have 105 in your database and in Redis, and can get user:Simon:lingots without querying the database.

The second case is updating dependent information. Let's say you generate chunks of a page and cache their output. The header shows the player's experience, level, and amount of money; the player's Profile page has a block that shows their statistics; and so forth. The player gains some experience. Well, now you have several templates:Header:Simon, templates:StatsBox:Simon, templates:GrowthGraph:Simon, and so forth fields where you've cached the output of a half-dozen database queries run through a template engine. Normally, when you display these pages, you say:

$t = GetStringFromRedis("templates:StatsBox:" + $playerName);
if ($t == null) {
  $t = BuildTemplate("StatsBox.tmpl",
                     GetStatsFromDatabase($playerName));
  SetStringInRedis("Templates:StatsBox:" + $playerName, $t);
}
print $t;

因为您刚刚更新了GetStatsFromDatabase("Simon")的结果,所以必须从键值缓存中删除模板:*:Simon。当你试图呈现这些模板中的任何一个,你的应用程序将从你的数据库(PostgreSQL, MongoDB)获取数据,并将其插入到你的模板;然后,它将结果存储在Redis中,希望在下次显示该输出块时,不必费心进行数据库查询和渲染模板。

Redis还允许你做发布者订阅消息队列等等。那完全是另一个话题了。这里的要点是Redis是一个键值缓存,它不同于关系数据库或文档存储。

结论

根据需要选择工具。最大的需求通常是数据模型,因为这决定了您的代码有多复杂和易出错。专门的应用程序将依赖于性能,在这些应用程序中,您可以混合使用C和汇编编写所有内容;大多数应用程序只会处理一般情况,并使用缓存系统,如Redis或Memcached,这比高性能SQL数据库或文档存储要快得多。

Redis和MongoDB都是非关系数据库,但它们属于不同的类别。

Redis是一个键/值数据库,它使用内存存储,这使得它非常快。它是缓存和临时数据存储(在内存中)的一个很好的候选人,因为大多数云平台(如Azure,AWS)都支持它,它的内存使用是可扩展的。但是如果您要在资源有限的机器上使用它,请考虑它的内存使用量。

另一方面,MongoDB是一个文档数据库。对于保存大型文本、图像、视频等以及几乎所有与数据库相关的内容(除了事务)来说,这是一个很好的选择。例如,如果你想开发一个博客或社交网络,MongoDB是一个合适的选择。它具有向外扩展的策略。它使用磁盘作为存储介质,因此数据将被持久化。

如果你的项目预算允许你有足够的RAM内存在你的环境-答案是Redis。尤其是考虑到新的Redis 3.2的集群功能。