艾体宝干货丨Redis与MongoDB的区别

Redis Remote Dictionary Server ,远程字典服务器)和 MongoDB 是两类知名的 NoSQL 数据库,其以非结构化的方式存储数据。与传统关系数据库使用表格、行和列来组织数据不同, NoSQL 数据库采用了不同的数据存储模型。 Redis 是一种开源的内存数据库,以键值对的形式存储数据,其将数据存储在 RAM 中,以实现高效的读写性能,同时也提供磁盘持久存储作为补充功能。 MongoDB 是另一种开源的文档数据库,通过序列化的 JSON 格式来存储数据, MongoDB 会将数据存储在外部存储中。

尽管 Redis MongoDB 都是广受欢迎的 NoSQL 数据库,并且在现代软件开发中得到了广泛的应用和验证,但二者在设计理念、应用场景等方面存在显著差异。对于刚接触 NoSQL 数据库的读者来说,这些差异可能会带来困惑。本文旨在为读者提供关于这两种数据库的详细信息,帮助大家更好地理解二者的区别,进一步根据自身开发团队的需求和业务应用场景,更有效地选择最合适的数据库解决方案。

数据模型

首先,我认为我们可以从数据模型开始聊起。所谓数据模型,指的就是我们向数据库中存储数据时,这些数据究竟以何种形式进行组织、存储。了解了数据模型,进而能窥探出数据库的设计思想,从而指导我们如何正确地去使用。例如 SQL 数据库在存储时,会将数据组织为表格的形式,同时表格还会附带若干属性约束,这就是典型的关系数据模型,如下图所示。

NoSQL 数据库本身是一个大的分类,其囊括了包含键值数据库、文档数据库、图数据库甚至时序数据库在内多种服务于不同需求的细分子类。本文中我们的目光将聚焦于 Redis MongoDB 采用的不同数据模型,以及二者在架构上不同存储数据的方式。

Redis

Redis 将数据存储在 RAM 中, RAM 带来的优势就在于数据可以被快速访问,并能提供极低的延迟。不过由于 RAM 的特性,这种存储方式也限制了可以存储的数据量,无论是 HDD 还是 SSD ,硬盘的单位存储价格始终远低于 RAM 。而为了实现数据持久性, Redis 提供了两种机制:快照( Snapshot )和仅追加文件( AOF )日志记录,这两种方法可以将数据集保存在磁盘上,规避 RAM 易失性的缺陷。

Redis 使用键值对的形式存储数据,每个数据条目都有一个唯一的键( Key )。它支持多种数据类型,常用的包括有序集合( Sorted Set )、哈希( Hash )、无序集合( Set )、列表( List )与字符串( String )。键值对的大小被限制为不超过 512MB ,不过通常我们在使用中会尽可能地避免使用较大的键值对。

Redis 还支持 Pub-Sub 或者流模式,这使其不仅仅是一个键值缓存系统。该功能允许在系统中实现消息队列等功能,额外的 Redis Model 支持也提供了缓存之外的拓展选项,不过这就是另一个独立的话题。

下图展示了 Redis 的数据模型。

MongoDB

MongoDB 是一种文档存储数据库,与传统的 SQL 驱动的关系数据库有显著不同。在关系数据库中,如上文所言,数据通常被简化为具有索引的 CSV 文件形式,每个文件代表一个表;而在文档存储中,数据则被简化为具有索引的 JSON 文件,每个文件对应一个文档,多个文档组合成一个集合。

JSON 文件的结构与 XML YAML 文件类似,也类似于 Python 中的字典。因此,可以按照这种层次结构来组织和涉及数据。在 MongoDB 中,文档由已命名的键组成,而这些键可以包含其他文档、数组或标量值。举例而言,一个文档中可能包含一个键 Address.Street ,其值为 123 Main St 。你可以通过在索引中查找 Address.Street 等于某个值的文档集合来进行搜索。

{
  _id:  "5f4e3ab0b5d6",
  Name:  "Alice Johnson",
  Address:
    Street: "123 Main St",
    City: "Springfield",
    State: "IL"
  Orders:
    - "A1001"
    - "B2002"
    - "C3003"
}

MongoDB 还允许文档包含数组,例如  Orders  数组,其中可以包含多个订单信息。可以针对  Orders  数组的内容进行复杂的查询操作,比如查找包含某个特定值子集的文档。举例来说,如果  Orders  包含  ["A1001", "B2002"] ,查询  Orders includes "A1001"  会返回这个文档;而查询  Orders includes any of ["B2002", "C3003"]  则会返回包含这些订单中任一项的文档。

文档的嵌套层次越深,其灵活性和数据组织的能力越强。例如, Address  可以包含一个子文档  Geo ,其中有  Latitude   Longitude  信息。如果业务的数据高度结构化,文档存储模型往往比关系数据库更具优势。

下图展示了 MongoDB 的数据模型。

什么情况下使用 Redis MongoDB

以开发团队以及应用需求为导向

如果您的应用需要频繁的查询操作, Redis 中的数据通常存储在各种专门的数据结构中,为了优化性能,开发人员需要为每种类型的对象选择特定的数据结构。因此,选择 Redis 可能会带来一些额外的开发与适配工作。而在 MongoDB 中,由于其数据结构更加一致( JSON ),类似的查询可能在实现层面上更加简单。不过事有两面,尽管在 Redis 中的查询或许需要处理多种数据结构,但这种些微复杂性带来的好处是响应速度的提升。 Redis 的高性能可以弥补在查询处理上的额外工作量。

对于开发人员而言,尤其是那些拥有传统数据库和 SQL 背景的开发人员对 MongoDB 的接受程度或许会更好。虽然二者都是 NoSQL 数据库,但 MongoDB 提供了一种更直观、更符合 SQL 习惯的方式来管理和查询数据。相较之下, Redis 虽然使用上完全称不上复杂,但以键值对为设计思想的存储模式,可能需要花费更多时间和精力去学习,但同样地,作为回报, Redis 也提供了更高的灵活性。

艾体宝工程师 Eero 认为,“就个人而言,我倾向于选择 Redis 来满足大多数需求。其高性能和灵活性使其在许多应用场景中相当有效。不过最终的选择,应该基于具体的应用需求和开发团队的技能组合。”

Redis

对于 需要快速查询的临时数据存储,非常建议使用 Redis Redis 能够 提供对频繁访问的数据的快速响应,因此非常适合用作缓存或会话存储等场景。此外, Redis 内置了对发布 - 订阅( Pub/Sub )消息传递模式的支持(新发布的 Redis Stream 还在此基础上进一步做了改),其在 实时应用程序事件驱动架构中表现出众。 Redis 还提供其它数据结构例如有序集合和列表,用于实现速率限制、任务队列与作业调度系统。最后, Redis 还能高效地对数据进行 计数汇总,也非常适用于跟踪排行榜数据或其他统计数据。

MongoDB

相比之下, MongoDB 适用于 存储复杂的应用程序数据,尤其是 大规模的数据集。其提供了更传统的数据库结构,同时支持无模式的存储,赋予了开发者相较于关系数据库更大的灵活性。 MongoDB 能够有效地处理大量的写入和读取操作,常见的用例如内容管理系统或大规模的用户资料管理。

两者非此即彼吗?

恰恰相反。许多应用程序中,同时使用 Redis MongoDB 是一种行之有效的策略。 Redis 的高性能与 MongoDB 的长期存储能力相得益彰,得以显著优化数据库的整体性能,提高系统的可扩展性,并为应用程序提供更多的灵活性。

例如, Redis 的高速内存存储使其能够迅速捕获和处理实时数据流,非常适用于需要实时响应的场景。处理后的数据或结果,可以存储在 MongoDB 中,进行存档或用于更复杂的分析。该策略一方面能提高系统的响应速度,另一方面还能为数据的持久性和可扩展性提供额外的保障。

另一个常见的应用场景是跨 Redis MongoDB 的混合数据模型。您可以利用 Redis 的键值存储来快速访问频繁使用的元数据,同时使用 MongoDB 处理更复杂的数据结构。如此,职责分明, Redis 提供低延迟的读取和写入操作,而 MongoDB 则处理复杂的查询和数据持久化。通过结合两种数据库的优点,进而构建一个既高效又灵活的系统,满足多种应用需求。

差异总结


Redis

MongoDB

数据模型

基于键值的内存数据存储

长期的文档数据库

扩展性

通过水平扩展、分片和分区数据,提供可扩展性

通过水平扩展、分片和分区数据,具有高度可扩展性

可用性

Redis   Sentinel Redis   Cluster   Redis Enterprise 提供各层级高可用

默认情况下,自动进行失效转移

完整性

提供用于创建单个原子操作的命令,但对 ACID 事务仅做到部分支持

内置对多文档 ACID 事务和回滚的支持

查询语言

使用自有的命令进行查询,主流语言客户端库支持

使用 MongoDB   查询语言( MQL )来查询和操作数据

 

 

 


请使用浏览器的分享功能分享到微信等