首页 文章

什么时候去Redis?什么时候到MongoDB? [关闭]

提问于
浏览
467

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

Redis非常快,但API非常'原子' . MongoDB将占用更多资源,但API非常易于使用,我对它非常满意 .

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

那你怎么看待它们的用途呢?何时选择Redis?什么时候选择MongoDB?

10 回答

  • 16

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

    Redis是一个Key / Value数据库,它使用内存存储,使其超快 . 它是缓存和临时数据存储(在内存中)的理想选择,并且由于大多数 Cloud 平台(例如Azure,AWS)支持它,它的内存使用是可扩展的 . 但是如果你要在你的机器上使用它有限的资源,考虑它的内存使用情况 .

    另一方面,MongoDB是一个文档数据库 . 这是一个很好的选择,可以保存大型文本,图像,视频等,以及除了交易之外的几乎所有数据库 . 例如,如果您想开发博客或社交网络,MongoDB是一个合适的选择 . 它具有横向扩展策略的可扩展性 . 它使用磁盘作为存储介质,因此数据将保持不变 .

  • 236

    我刚刚注意到这个问题很老了 . 不过,我认为以下几个方面值得补充:

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

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

    • 使用Redis加速现有应用程序 .

    Redis可以轻松集成为LRU cache . 将Redis用作独立的数据库系统非常罕见(有些人更喜欢将其称为"key-value" -store) . 像Craigslist这样的网站使用Redis next to their primary database . Antirez(Redis的开发人员)证明了使用Lamernews确实可以将Redis用作独立的数据库系统 .

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

    Redis提供了许多有用的数据结构(例如集合,散列,列表),但您必须明确定义如何存储数据 . 简而言之,可以使用Redis和MongoDB来实现类似的功能 . Redis速度更快,但不适合原型设计 . 这是一个通常更喜欢MongoDB的用例 . 除此之外,Redis灵活多变 . 它提供的底层数据结构是高性能数据库系统的构建块 .

    何时使用Redis?

    • 缓存

    使用MongoDB进行缓存并不是很有意义 . 这太慢了 .

    • 如果您有足够的时间考虑数据库设计 .

    您可以'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 359469 , nested objects, which means you'll必须重新考虑存储嵌套文档的方式 . 一种解决方案是将散列内的引用存储到另一个散列(类似于key:[id of second hash]) . 另一个想法是将其存储为JSON,这对于具有* SQL背景的大多数人来说似乎是违反直觉的 .

    • 如果您需要 really 高性能 .

    击败Redis提供的性能几乎是不可能的 . 想象一下,您的数据库与缓存一样快 . 这就是将Redis用作真实数据库的感觉 .

    • 如果你不关心缩放 .

    扩展Redis并不像以前那么难 . 例如,您可以使用一种代理服务器,以便在多个Redis实例之间分发数据 . 主从复制并不复杂,但是在多个Redis实例之间分配密钥需要在应用程序站点上完成(例如使用哈希函数,Modulo等) . 通过比较缩放MongoDB要简单得多 .

    何时使用MongoDB

    • 原型,初创公司,黑客马拉松

    MongoDB非常适合快速原型设计 . 然而,表现不是那么好 . 还要记住,您很可能必须在应用程序中定义某种模式 .

    • 需要快速更改架构时 .

    因为没有架构!在传统的关系型DBMS中更改表格非常昂贵且速度慢 . MongoDB通过不对您的基础数据做出很多假设来解决这个问题 . 然而,它试图尽可能地优化而不要求您定义模式 .

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

    进一步阅读:

  • 223

    Redis的 . 假设您已经在php中编写了一个站点;无论出于何种原因,它变得流行,它超前于它的时间或者有色情内容 . 你意识到这个PHP非常缓慢,“我会失去我的粉丝,因为他们根本不会等待10秒钟的页面 . ”你突然意识到一个网页有一个常量的网址(它永远不会改变,哇),如果你愿意的话,它是一个主键,然后你会想起内存很快,而磁盘很慢而且php甚至更慢 . :(然后你使用内存和这个你称之为“密钥”的URL来设计存储机制,而你决定称之为“ Value ”的网页内容 . 这就是你所拥有的 - 关键和内容 . 你称之为“meme cache” . 你喜欢理查德道金斯,因为他很棒 . 你缓存你的html像松鼠缓存他们的坚果 . 你不需要重写你的垃圾PHP代码 . 你很高兴 . 然后你看到其他人已经做到了 - 但你选择Redis因为另一个有猫的混乱图像,有些有f牙 .

    蒙戈 . 你写过一个网站 . 哎呀,你用很多语言写了很多东西 . 你意识到你花了很多时间来编写那些臭臭的SQL子句 . 你不是dba,但是你在那里,编写愚蠢的sql语句......不只是一个,而是在各处吓坏 . “选择此项,选择” . 但特别要记住烦人的WHERE子句 . 姓氏等于“thornton”,电影等于“坏圣诞老人” . Urgh . 你认为,“为什么那些dbas不做他们的工作并给我一些存储过程?”然后你忘记了一些像midname这样的小字段,然后你必须放弃表格,导出所有10G的大数据并用这个新字段创建另一个,然后输入数据 - 在接下来的14天中你会继续10次继续记住像称呼, Headers 的废话,再加上带地址的外键 . 然后你认为lastname应该是lastName . 每天几乎换一次 . 然后你说darnit . 我必须继续写一个网站/系统,不要介意这个数据模型 . 所以你谷歌,“我讨厌编写SQL,请不要SQL,让它停止”,但弹出'nosql',然后你读了一些东西,它说它只是转储没有任何架构的数据 . 你记得上周的惨败让更多 table 和笑容消失了 . 然后你选择mongo,因为像'airbud'这样的租赁网站的一些大家伙使用它 . 甜 . 没有更多的数据模型更改,因为您有一个模型,您只是不断变化 .

  • 2

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

    例如,如果您需要大量的 querying ,这通常意味着您的开发人员使用Redis会更加有效,您可以将数据存储在各种专用数据结构中,为每种类型的对象进行自定义以提高效率 . 在MongoDB中,相同的查询可能更容易,因为结构在整个数据中更加一致 . 另一方面,在Redis中,对这些查询的响应 sheer speed 是处理数据可能存储的各种结构的额外工作的回报 .

    MongoDB为具有传统数据库和SQL经验的开发人员提供了简单,更短的学习曲线 . 但是,Redis的非传统方法需要更多的学习努力,但需要更大的灵活性 .

    例如 . 在Redis中可能更好地实现 cache 层 . 对于更多可架构的数据,MongoDB更好 . [注意:MongoDB和Redis在技术上都是无模式的]

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

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

  • 10

    如果你有足够的RAM,你应该使用它们 . Redis和MongoDB是以通用工具为代价的 . 这引入了很多开销 .

    有人说Redis比Mongo快10倍 . 那可能不再那么真实了 . MongoDB(如果我没记错的话)声称只要内存配置相同,就可以打败memcache来存储和缓存文件 .

    无论如何 . Redis很好,MongoDB很好 . 如果您关心子结构并需要聚合,请访问MongoDB . 如果存储密钥和值是您主要关心的问题,那就是Redis . (或任何其他键值存储) .

  • 10

    所有答案(在撰写本文时)都假设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 . 您可以搜索密钥 PhoneNumber.Mobile 具有某些值的文档集合;他们被编入索引 .

    它还有一个包含多个索引的 Accounts 数组 . 可以查询文档,其中 Accounts 恰好包含某些值的子集,所有值的某个子集或任何某个值的子集 . 这意味着您可以搜索 Accounts = ["379-1111", "379-2574"] 而找不到上述内容;你可以搜索 Accounts includes ["379-1111"] 并找到上面的文件;并且您可以搜索 Accounts includes any of ["974-3785","414-6731"] 并找到上述内容以及任何包含帐户"974-3785"的文档(如果有) .

    文件尽可能深入 . PhoneNumber.Mobile 可以包含数组,甚至是子文档( PhoneNumber.Mobile.WorkPhoneNumber.Mobile.Personal ) . 如果您的数据结构很高,那么文档距离关系数据库很大 .

    如果您的数据大部分是平坦的,关系型的,并且结构严谨,那么您最好使用关系数据库 . 同样,最重要的是,您的数据模型是否最适合于相关的CSV文件集合或XML / JSON / YAML文件集合 .

    对于大多数项目,您必须妥协,在SQL或文档存储不适合的某些小区域接受小规模的解决方案;对于存储大量数据的大型复杂项目(许多列;行无关紧要),将一些数据存储在一个模型中以及将其他数据存储在另一个模型中是有意义的 . Facebook使用SQL和图形数据库(数据放入节点,节点连接到其他节点); Craigslist曾经使用MySQL和MongoDB,但一直在考虑完全转移到MongoDB上 . 如果放在一个模型下,这些地方的数据 Span 和关系将面临重大障碍 .

    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 . 然后当你奖励Simon 5 lingots时,你会读到 user:Simon:lingots = 100SET user:Simon:lingots = 105UPDATE Store s INNER JOIN UserProfile u ON s.UserID = u.UserID SET s.Lingots = 105 WHERE u.Username = Simon . 现在你的数据库和Redis中有105个,并且可以在不查询数据库的情况下获得 user:Simon:lingots .

    第二种情况是更新相关信息 . 让's say you generate chunks of a page and cache their output. The header shows the player'的经验,水平和金额;玩家的 Profiles 页面有一个显示其统计数据的块;等等 . 玩家获得一些经验 . 那么,现在你有几个 templates:Header:Simontemplates:StatsBox:Simontemplates: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数据库或文档存储快得多 .

  • 2

    也许这个资源有助于在两者之间做出决定 . 它还讨论了其他几个NoSQL数据库,并提供了一个简短的特性列表,以及每个数据库的 "what I would use it for" 解释 .

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

  • 1

    难以回答的问题 - 与大多数技术解决方案一样,它实际上取决于您的情况,因为您没有描述您要解决的问题,有谁能提出解决方案?

    你需要对它们进行测试,看看哪些满足了 your 的需要 .

    话虽如此,MongoDB不需要任何昂贵的硬件 . 像任何其他数据库解决方案一样,它可以更好地使用更多的CPU和内存,但是当然不是要求 - 特别是对于早期开发目的 .

  • 11

    如果你的项目已经让你的环境有足够的RAM内存 - 请回答Redis . 特别是考虑到具有集群功能的新Redis 3.2 .

  • 310

    Redis是一个 in memory 数据存储,可以将其状态保存到磁盘(以便在重新启动后启用恢复) . 但是,作为内存数据存储意味着数据存储(在单个节点上)的大小不能超过系统上的总内存空间(物理RAM交换空间) . 实际上,由于Redis与系统上的许多其他进程共享该空间,并且如果它耗尽系统内存空间,它可能会被操作系统杀死,这将远不如此 .

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

    Redis和Mongo都可以进行群集,以实现高可用性,备份和增加数据存储的总体大小 .

相关问题