代码之家  ›  专栏  ›  技术社区  ›  Community wiki

什么时候去Redis?何时使用MongoDB?[已关闭]

  •  466
  • Community wiki  · 技术社区  · 2 年前

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

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

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

    那么,你认为这两种方法的用途是什么呢?什么时候选Redis?什么时候选择MongoDB?

    10 回复  |  直到 10 年前
        1
  •  308
  •   Shekhar    9 年前

    我想说,这取决于您的开发团队类型和您的应用程序需求。

    例如,如果您需要大量 查询 ,这主要意味着您的开发人员将需要更多的工作来使用Redis,在Redis中,您的数据可能存储在各种专门的数据结构中,并为每种类型的对象进行定制以提高效率。在MongoDB中,同样的查询可能更容易,因为数据的结构更一致。而在Redis中, 绝对速度 对这些查询的响应是处理数据可能存储的各种结构的额外工作的回报。

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

    A 隐藏物 层可能可以在Redis中更好地实现。对于更多可模式化的数据,MongoDB更好。 【注意:MongoDB和Redis在技术上都是无架构的】

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

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

        2
  •  236
  •   Alexander Gugel    10 年前

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

    • 如果您还不知道如何查询数据,请使用MongoDB。

      MongoDB适用于黑客马拉松、初创公司或每次你不知道如何查询插入的数据时。MongoDB不会对您的底层模式做出任何假设。虽然MongoDB是无模式的和非关系的,但这并不意味着根本没有模式。这只是意味着你的模式需要在你的应用程序中定义(例如使用Mongoose)。除此之外,MongoDB非常适合进行原型设计或尝试。它的性能不是很好,无法与Redis相比。

    • 使用Redis可以加快现有应用程序的速度。

      Redis可以很容易地集成为 LRU cache 。将Redis作为一个独立的数据库系统使用是非常罕见的(有些人更喜欢将其称为“键值”存储)。像Craigslist这样的网站使用 Redis next to their primary database .Antirez(Redis的开发者)使用Lamernews演示了将Redis作为一个独立的数据库系统确实是可能的。

    • Redis不会根据您的数据做出任何假设。

      Redis提供了一系列有用的数据结构(例如Sets、Hashes、Lists),但您必须明确定义如何存储数据。简而言之,Redis和MongoDB可以用来实现类似的事情。Redis只是速度更快,但不适合原型设计。这是一个您通常更喜欢MongoDB的用例。除此之外,Redis 真正地 灵活的它提供的底层数据结构是高性能数据库系统的构建块。

    什么时候使用Redis?

    • 缓存

      使用MongoDB缓存根本没有什么意义。太慢了。

    • 如果你有足够的时间来考虑你的数据库设计。

      您不能简单地将文档放入Redis。你必须考虑你想要存储和组织数据的方式。Redis中的hashes就是一个例子。它们与“传统”的嵌套对象大不相同,这意味着您必须重新思考存储嵌套文档的方式。一种解决方案是在哈希中存储对另一个哈希的引用(类似于 密钥:[第二个散列的id] )。另一个想法是将其存储为JSON,这对大多数具有*SQL背景的人来说似乎是违反直觉的。

    • 如果您需要 真正地 高性能。

      击败Redis提供的性能几乎是不可能的。想象一下你的数据库和你的缓存一样快。这就是使用Redis作为 真实的 数据库

    • 如果你不在乎 那个 关于缩放。

      扩展Redis不像以前那么难了。例如,你可以使用一种代理服务器来在多个Redis实例之间分发数据。主从复制不是 那个 虽然复杂,但在多个Redis实例之间分配密钥需要在应用程序站点上完成(例如使用哈希函数、Modulo等)。相比之下,扩展MongoDB要简单得多。

    何时使用MongoDB

    • 原型、初创企业、黑客马拉松

      MongoDB非常适合快速原型设计。尽管如此,性能并没有那么好。还要记住,您很可能必须在应用程序中定义某种模式。

    • 当您需要快速更改模式时。

      因为没有模式!在传统的关系型DBMS中更改表是非常昂贵和缓慢的。MongoDB通过不对底层数据进行大量假设来解决这个问题。尽管如此,它还是尽量优化,而不需要定义模式。

    TL;DR -如果性能很重要,并且您愿意花时间优化和组织数据,请使用Redis。 -如果您需要构建一个原型,而不必太担心您的数据库,请使用MongoDB。

    进一步阅读:

        3
  •  223
  •   Gabe Rainbow    9 年前

    Redis。假设您已经用php编写了一个站点;不管出于什么原因,它变得流行起来,走在了时代的前面,或者上面有色情内容。你会意识到这个php太慢了,“我会失去我的粉丝,因为他们根本不会等10秒看一个页面。”你会突然意识到,一个网页有一个恒定的url(它永远不会改变,哇),如果你愿意的话,这是一个主键,然后你会想起内存很快,而磁盘很慢,php甚至更慢(然后,你使用内存和这个你称之为“密钥”的URL来构建一个存储机制,而你决定将网页内容称为“值”。这就是你所拥有的全部——密钥和内容。你将其称为“模因缓存”。)。“你喜欢Richard Dawkins是因为他太棒了。你缓存你的html就像松鼠缓存它们的坚果一样。你不需要重写你的垃圾php代码。你很高兴。然后你看到其他人已经这么做了——但你选择Redis是因为另一个有令人困惑的猫图像,有些有尖牙。”。

    Mongo。你写了一个网站。你用任何语言写过很多书。您意识到,您的大部分时间都花在了编写那些糟糕的SQL子句上。你不是dba,但你在写愚蠢的sql语句。。。不仅是一个,而且到处都是。“选择这个,选择那个”。但你特别记得那个烦人的WHERE子句。姓氏等于“thornton”,电影等于“坏圣诞老人”。你会想,“为什么那些dba不做好他们的工作,给我一些存储过程?”然后你忘记了一些小字段,比如middlename,然后你必须放下表,导出所有10G的大数据,用这个新字段创建另一个,然后导入数据——在接下来的14天里,这种情况会持续10次,再加上添加一个带有地址的外键。然后你想lastname应该是lastname。几乎每天换一次。然后你说该死的。我必须开始写一个网站/系统,更不用说这个数据模型了。所以你在谷歌上搜索,“我讨厌写SQL,请不要写SQL,让它停止”,但弹出“nosql”,然后你读到一些东西,它说它只是在没有任何模式的情况下转储数据。你还记得上周的惨败,丢了更多的桌子,笑了。然后你选择mongo是因为一些大人物喜欢“airbud”这个合适的租赁网站使用它。太好了。不再更改数据模型,因为您有一个不断更改的模型。

        4
  •  16
  •   stackex    12 年前

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

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

        5
  •  11
  •   Bryan Migliorisi    14 年前

    很难回答的问题-与大多数技术解决方案一样,这实际上取决于您的情况,由于您没有描述您试图解决的问题,如何有人提出解决方案?

    你需要测试他们两个,看看他们中的哪一个满意 你的 需求。

    话虽如此,MongoDB不需要任何昂贵的硬件。与任何其他数据库解决方案一样,它将使用更多的CPU和内存更好地工作,但这肯定不是一个要求,尤其是对于早期开发目的。

        6
  •  10
  •   aaa90210    10 年前

    Redis是 在存储器中 数据存储,可以 将其状态保存到磁盘 (以启用重新启动后的恢复)。然而,作为内存中的数据存储意味着数据存储的大小(在单个节点上)不能超过系统上的总内存空间(物理RAM+交换空间)。事实上,这要少得多,因为Redis正在与系统上的许多其他进程共享该空间,如果它耗尽了系统内存空间,它很可能会被操作系统扼杀。

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

    Redis和Mongo都可以集群化,以实现高可用性、备份和增加数据存储的整体大小。

        7
  •  10
  •   John Moser    9 年前

    所有的答案(在撰写本文时)都假设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 。您可以在文档集合中进行搜索, 电话号码.手机 ,具有一定的价值;它们被编入索引。

    它还有一个数组 Accounts 其保存多个索引。可以在以下位置查询文档 账户 包含 确切地 值的某个子集, 全部的 值的某个子集,或 任何 值的某个子集。这意味着您可以搜索 Accounts = ["379-1111", "379-2574"] 而找不到以上内容;您可以搜索 Accounts includes ["379-1111"] 并找到上述文件;你可以搜索 Accounts includes any of ["974-3785","414-6731"] 并找到上述文件以及包括账户“974-3785”的任何文件(如有)。

    文件可以随心所欲地深入。 电话号码.手机 可以包含数组,甚至子文档( PhoneNumber.Mobile.Work PhoneNumber.Mobile.Personal )。如果您的数据是高度结构化的,那么文档是关系数据库的一大进步。

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

    对于大多数项目,您将不得不妥协,在一些SQL或文档存储不适合的小领域接受一些小的变通方案;对于一些存储大量数据(多列;行不相关)的大型复杂项目,将一些数据存储在一个模型中,将其他数据存储在另一个模型中将是有意义的。Facebook同时使用SQL和图形数据库(其中数据被放入节点,节点被连接到其他节点);Craigslist曾经使用MySQL和MongoDB,但一直在考虑完全转移到MongoDB上。如果将数据放在一个模型下,这些地方的数据跨度和关系将面临重大障碍。

    Redis:键值

    Redis基本上是一个键值存储。Redis让你给它一个键,然后查找一个值。Redis本身可以存储字符串、列表、散列和其他一些东西;不过,它只查名字。

    缓存失效是计算机科学的难题之一;另一个是命名事物。这意味着当你想避免对后端进行数百次过度查找时,你会使用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个行话时,你会阅读 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 而无需查询数据库。

    第二种情况是更新依赖信息。假设您生成页面的块并缓存它们的输出。标题显示玩家的经验、级别和金额;玩家的个人资料页面有一个显示其统计数据的块;等等玩家获得了一些经验。好吧,现在你有几个 templates:Header:Simon , templates:StatsBox:Simon , templates:GrowthGraph:Simon ,等等字段,在这些字段中缓存了通过模板引擎运行的六个数据库查询的输出。通常,当您显示这些页面时,您会说:

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

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

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

    结论

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

        8
  •  2
  •   Martin Kersten    10 年前

    如果你有足够的RAM,你应该两者都不用。Redis和MongoDB的价格相当于一个通用工具。这会带来很多开销。

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

    无论如何Redis好,MongoDB好。如果您关心子结构并需要聚合,请使用MongoDB。如果存储键和值是您主要关心的问题,那么这一切都与Redis有关。(或任何其他键值存储)。

        9
  •  2
  •   akazemis    9 年前

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

    Redis是一个Key/Value数据库,它使用内存存储,这使它速度极快。它是缓存内容和临时数据存储(内存中)的一个很好的候选者,由于大多数云平台(如Azure、AWS)都支持它,它的内存使用是可扩展的。但如果你要在资源有限的机器上使用它,请考虑内存使用。

    另一方面,MongoDB是一个文档数据库。这是一个很好的选择,可以保存大量的文本、图像、视频等,以及除交易外的几乎所有数据库操作。例如,如果你想开发博客或社交网络,MongoDB是一个合适的选择。它可以通过扩展策略进行扩展。它使用磁盘作为存储介质,因此数据将被持久化。

        10
  •  1
  •   Denys    9 年前

    如果您的项目预算允许您在环境中有足够的RAM内存,答案是Redis。特别是考虑到具有集群功能的新Redis 3.2。