关于MongoDB 的一些谣言

[译文] 原文 -> https://developer.mongodb.com/article/everything-you-know-is-wrong
翻译的哪里有不清楚的,烦请指出 - 理解和能翻译好是两码事,边走边学。谢谢。

 

在我加入MongoDB这小一年的时间里我学习到很多新东西。在这之前通过一些关于MongoDB的介绍,对它的使用看起来如此简单印象深刻,但是从来没有上手实操过, 仅仅在我准备面试的时候我才真正的上手玩一玩。‌

和其他人一样,之前我也道听途说很多关于MongoDB的可怕故事. "它数据之间没有关系作为连接!" “如果你只是想存储文档(Documents)那可能还行,但是之后你想做聚合(Aggregation)那怎么办? 到时候就为时已晚,并且! 它还不支持事务(Transactions)!”

直到我开始寻找这些信息的来源时,我才开始意识到两件事: 首先, 很多帖子/博客都是很久之前的,因此它们认识的是一个仅仅三年的产品,而不是我们今天拥有的经过实际测试的成熟版本。其次,他们所说的几乎所有内容都不是真的 - 甚至有一些是一开始就是错误的。

综上,我决定就网上对MongoDB的错误信息进行一次演讲(并写下这篇博客文章),并一一反驳每个谬论。

谣言 0: MongoDB 是 web scale

YouTube视频中有两只狗(狗?我认为它们是狗)。你可能已经看到了, 其中的一只就是那种完全不了解他们相信的技术内部构造, 对他们相信的技术的盲目信奉。另一只就更加理性,对第一只狗拒绝面对现实的态度感到忧伤。

在MongoDB的第一天, 我的一个朋友就给我发送了此视频的链接,以防万一我没看过。 (我其实看过。)在视频底部查看日期!该视频已经发行了十多年。当时真的很有趣,但是现在呢?几乎里面所有的东西都已经过时了。

我们并不难过! 实际上,MongoDB里的许多人都在T恤或笔记本电脑上贴上了视频里面的狗。他是MongoDB里的一个非正式吉祥物。只是不要看视频来寻找事实。另外, 不要向我们发该视频的链接-我们都看过了~~

 

MongoDB到底是什么?

在介绍MongoDB所没有的东西之前,让我们先概述一下MongoDB的实际含义。

MongoDB是一个 面向文档的分布式数据库. 它的集群(clusters - 我们称它为副本集)大部分是自我管理的 - 一旦你预先设定该集群中有多台机器,如果其中任何一个节点出现故障或网络出现问题,它就会被妥善的处理安置好。 如果任意一台机器宕机了,剩下的机器会自动补上。集群中的任意一台机器都存储着数据库中的所有的数据。(下图为一个集群或副本集)

 

集群的主要目的是 冗余 而不是 可扩展性。 通常情况下,所有的用户都是连接到同一个服务器上(称为当选主节点), 它的主要作用是 执行查询和更新 并且 负责 将数据传输到备用节点上(当主节点出现宕机时会被用作备用)。

你可以通过直接连接到备用节点上来做一些有趣的事情比如 跑一些分析查询(analytics query),因为相对主节点备用节点上有比较少的读操作. 但是总的来说, 强制连接到备用节点上进行读操作意味着你要承担读取的数据不是最新的风险。所以,不要贸然的这样操作,除非你已经权衡好利弊.

到目前为止,我阐述了 分布(distributed) 但是 什么是 面向文档的数据库 呢?

MongoDB与传统关系数据库的不同之处在于,MongoDB它无法将数据原子存储在数据库表中的扁平行中,它允许你将分层的结构化数据存储在文档(通常是类似JSON对象)中。文档被存储在集合中,集合实际上就是一堆文档。任意文档的结构或者模式都可以不同于这个集合中的其他文档。 你还可以(应该!)根据 要运行的查询和要存储的数据来对集合中的文档进行创建索引。而且,如果你希望进行验证以确保集合中的所有文档都遵循集合结构,那么可以将JSON模式作为验证器应用于集合中。
 

{

'_id': ObjectId('573a1390f29313caabcd4135'),

'title': 'Blacksmith Scene',

'fullplot': 'A stationary camera looks at a large anvil with a

blacksmith behind it and one on either side.',

'cast': ['Charles Kayser', 'John Ott'],

'countries': ['USA'],

'directors': ['William K.L. Dickson'],

'genres': ['Short'],

'imdb': {'id': 5, 'rating': 6.2, 'votes': 1189},

'released': datetime.datetime(1893, 5, 9, 0, 0),

'runtime': 1,

'year': 1893

}

上面的文档是一个例子,显示了1893年的电影!该文档是使用PyMongo驱动程序查询的。

请注意,例子中的某些值是数组,例如“ countries”和“ cast”。一些值是对象(我们称它们为子文档)。这展示了MongoDB文档的层次结构性质 - 它们不像关系数据库中的表行那样平坦。

还要注意,“released”的值是一个原生(native)Python 的日期时间类型,以及第一个值的特殊ObjectId类型。也许这些实际上不是JSON文档?我稍后再说...

谣言 1: MongoDB 只停留在版本 V3.2

如果你在 Debian Stretch 上使用 apt-get 安装 MongoDB,那默认的安装版本将会是 3.2。不幸的是,这个版本已经有五年历史了!从那时起,已经有五个主要的年度版本,其中包含大量的新功能,以及安全性、性能和可伸缩性方面的改进。

最新的版本是 MongoDB v4.4 (2020年10月). 如果你想要安装它,则应该安装MongoDB Community Server,但在这之前请确保您已阅读有关MongoDB Atlas(我们的托管数据库即服务产品)的信息!

谣言 2: MongoDB 是一个JSON数据库

你肯定听说过MongoDB是一个JSON数据库,尤其是如果你最近阅读过MongoDB.com主页!

 

但是正如我之前暗示的那样,MongoDB 不是一个JSON 数据库. 它支持其他数据类型,例如ObjectIds,原生的日期对象(native date objects),更多其他数字类型,地理基元(geographic primitives)和有效的二进制类型等等。

这是因为 MongoDB 是一个BSON数据库!

这个区别看起来可能是微不足道的,但确是非常重要的。它比使用基于文本的格式存储结构化数据更有效地存储、传输和遍历,并且比JSON支持更多的数据类型,它在MongoDB中也无处不在。

  • MongoDB 存储BSON文档

  • 查找文档的查询是BSON文档

  • 查询的结果以BSON文档的形式呈现

  • BSON 甚至被用在 MongoDB使用的wire protocol

谣言3: MongoDB 不支持 事务

在阅读来自第三方对MongoDB的描述时,您可能会遇到将其描述为BASE数据库的博客。 BASE是 “基本可用性 (Basic Availability);软状态 (Soft-state);最终一致性 (Eventual consistency)”的首字母缩写。

但情况并非如此!其中的某些部分一直以来就是错的 - MongoDB从来都不是默认 “最终一致性(Eventual consistent)" - 更新被流式传输并按顺序存储到备用节点上,因此尽管它们可能落后于其他节点,但它们从来都不会不一致。软状态描述了需要不断更新数据,否则数据将过期,事实也并非如此。

最后,如果大部分节点出现问题导致仲裁(Quorum)不能达到标定的值,那么MongoDB将进入只读(read-only)状态(降低可用性)。这是故意为之。它确保在出现错误时能够保持一致性(Consistency)和分区容错(Partition tolerance)。

MongoDB是一个ACID数据库。它支持原子性(Atomicity),一致性(Consistency),隔离性(Isolation)和持久性(Durability)。

对单个文档的多个部分的更新一直都是原子性的。但是从v4.0开始,MongoDB支持跨多文档和集合的事务。从v4.2开始,分片群集中的所有分片甚至都支持此功能。

尽管MongoDB已经支持事务,但应谨慎使用它们。它们会降低性能,并且由于MongoDB支持丰富的层次结构文档,因此,如果您的架构设计正确,则不必经常在多个文档之间进行更新。

谣言4: MongoDB 不支持关系

关于MongoDB的另一个过时的谣言是,你不能在集合或文档之间建立关系。实际上,你可以通过查询(我们称它为聚合管道)来连接不同的集合和文档。它们功能强大,可让你使用直观的查询模型来查询和转换多个集合中的数据,该模型包括一系列应用于数据在管道中移动的管道阶段。

MongoDB 从 v2.2 开始就已经支持 lookups (joins).

下面的示例文档显示了在执行连接订单集合和库存集合的查询之后,如何将返回的订单文档包含相关的库存文档并嵌入到数组中。

 

After a lookup, related documents are *embedded* in the documents returned.

Enter a caption for this image (optional)

我的观点是,与其为关系联接中发现的每个关系复制行 相比 以上将相关文档嵌入要返回的主文档中更为直观.

谣言5: 分片 (Sharding) 是 MongoDB的全部

您可能会听到人们谈论分片是MongoDB的一项很酷的功能。是的 - 这绝对是MongoDB的一项很酷的核心功能。

分片是指对数据进行划分并将每个片段放入不同的副本集或集群中。这是处理大量数据集的技术。 MongoDB支持自动确保将数据和请求发送到正确的副本集,并合并来自多个分片的结果。

但是分片存在着一个基本的问题。

我在之前的博文中提到,为了允许仲裁机制,副本集中的最小节点数为三个。一旦需要分片,就至少有两个副本集,因此最少有六台服务器。最重要的是,您需要运行一个称为mongos的服务器的多个实例。 Mongos是分片集群的代理,用于处理请求和响应的路由。为了获得高可用性,您至少需要两个mongos实例。

 

 

因此,这意味着最小的分片集群为八台服务器,并且每增加一个分片就至少要增加三台服务器。

集群还使你的数据更难管理,并且对你可以执行的查询类型增加了一些限制。分片在你需要时很有用,但是简单地升级硬件通常更便宜、更容易!

扩展数据主要与RAM有关,因此,如果可以,请购买更多RAM。如果你的瓶颈是CPU,请升级CPU或购买更大的磁盘。

一旦扩展到超出单台计算机可以容纳的RAM,你就可以使用MongoDB的分片功能。之外,你还可以使用分片来做一些整洁的事情,例如geo-pinning,可以将用户数据存储在地理上更靠近用户位置的位置,以减少延迟。‌

在考虑使用分片进行扩展之前,至少先考虑将硬件升级是否是更有效的选择。

在考虑任何一种办法之前,你应该先看一下MongoDB托管的数据库即服务产品(Database-as-a-Service)MongoDB Atlas。 (是的,我知道我已经提到过!)除了为你托管数据库之外,MongoDB Atlas还将根据需要进行上下扩展数据库,以保持可用性,同时保持较低的成本。它可以处理备份和冗余,还包括其他功能,例如图表,文本搜索,无服务器功能等等。

谣言6: MongoDB 是不安全的

关于MongoDB的一个相当长久的谣言是它从根本上是不安全的。我个人的感觉是,这是有关MongoDB的更不公平的谣言之一,但是不能否认,网络上存在许多不安全的MongoDB实例,而且有许多涉及MongoDB的引人注目的数据泄露事件。

历史上这是由于MongoDB的分发方式所致。在某些Linux版本上在部署MongoDB的时候,默认身份验证机制被禁用但是网络被启用.

因此,如果你没有设置防火墙,或者你在防火墙上打开了MongoDB端口,以便让Web服务器可以访问它,那么你的数据可能会被盗。现如今,网络上的机器人很可能会找到你的数据,在数据库中对其进行加密,然后添加一个文档,告诉你将比特币发送到哪里以获取解密你数据的密钥。‌

我会争辩说,如果你将不受保护的数据库服务器放在网络上,那是你的错 - 这种肯定情况已经发生过很多次了,但是有很多方法可以避免发生这种灾难。

我们已经修复了默认设置。除非启用身份验证,否则MongoDB将不会连接到网络,或者你向服务器提供特定配置来覆盖此行为。因此,你仍然有可能是不安全的,但是现在至少必须先阅读用户手册!

除此之外,MongoDB使用行业安全标准,例如TLS加密传输中的数据,使用SCRAM-SHA-256来安全地验证用户。‌

MongoDB还具有客户端字段级加密(FLE)功能,该功能允许你将数据存储在MongoDB中,以便在传输过程中和静态时都对其进行加密。这意味着,如果第三方要获得对数据库服务器的访问权,则他们将无法在不获得客户端访问权的情况下读取加密数据。

谣言7: MongoDB 会丢失数据

这个谣言是经典的Hacker News 比喻。有人发布了一个例子,说了他们如何成功地使用MongoDB来建了一个东西,然后有个人立即发表评论说:“我知道这个人曾经在MongoDB中丢失了所有数据。它只是将其丢弃了。请避免使用它!”

如果你进一步的接触这些用户,让他们开一个报告来描述下这个事故。他们从来都没有回音!

更重要的是,MongoDB专门花钱通过Jepsen来跑测试,以确保即使在严峻的网络条件下数据的一致性。这些测试已被添加到我们的自动化测试套件中。当然我们在测试中发现了问题 , 他们是有意为之, 并且我们已修复了它们。Jepsen测试对MongoDB的默认值仍然存在一些分歧,但是,如果你阅读了该手册,那么可以依靠MongoDB来稳定地、一致地存储和维护数据。

MongoDB已经被使用在了许多非常关注保存数据的行业中。这个范围包括从银行业比如摩根士丹利,巴克莱银行和汇丰银行到福布斯等大型出版品牌。我们从来没有收到任何关于大规模数据丢失的报告。如果你确实有第一手资料来讲述数据丢失的情况,恳请你给我们提交一个报告。无论你是付费企业客户还是开源用户,我们都会认真对待。

谣言8: MongoDB 很容易

像任何其他的数据库一样,MongoDB是一个大而复杂的系统。虽然很容易上手,但是如果你不去读用户手册,那之后会变得很棘手。

你会错过真正想要或需要的功能,或者你想要以一种复杂的方式来优化数据库或进行扩展。

你不能一蹴而就。但好消息是MongoDB的学习资料有很多并且很有趣!

MongoDB文档是详尽且好读的。 MongoDB大学有许多免费课程。

在MongoDB开发人员论坛上,我们详细介绍了一些MongoDB的模式用于模式设计和开发。我的大牛同事Lauren Schaefer,他撰写了一系列描述MongoDB Anti-Patterns的文章,来帮助你认识到何时你可能做的不是最佳的。

MongoDB有一个活跃的社区论坛,你可以在里面进行提问或炫耀你的项目。

因此,MongoDB既庞大又复杂,还有很多东西要学习,但是我希望本文能够以某种方式解释MongoDB是什么以及它不是什么,并且如何学习有效的使用它。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值