149

我到处看,我看到 MongoDB 是 CP。但是当我深入研究时,我发现它最终是一致的。使用safe=true时是CP吗?如果是这样,这是否意味着当我使用 safe=true 编写时,所有副本都会在得到结果之前更新?

4

7 回答 7

123

默认情况下,MongoDB 是强一致的——如果你先写然后再读,假设写成功,你将始终能够读取刚刚读到的写的结果。这是因为 MongoDB 是单主系统,默认情况下所有读取都转到主系统。如果您有选择地启用从辅助节点读取,那么 MongoDB 最终会变得一致,可以读取过时的结果。

MongoDB 还通过副本集中的自动故障转移获得高可用性:http ://www.mongodb.org/display/DOCS/Replica+Sets

于 2012-07-02T16:33:11.693 回答
64

我同意卢卡斯的帖子。您不能只说 MongoDB 是 CP/AP/CA,因为它实际上是C、A 和 P 之间的权衡,取决于数据库/驱动程序配置和灾难类型:这是一个视觉回顾,下面是更详细的解释。

Scenario                   | Main Focus | Description
---------------------------|------------|------------------------------------
No partition               |     CA     | The system is available 
                           |            | and provides strong consistency
---------------------------|------------|------------------------------------
partition,                 |     AP     | Not synchronized writes 
majority connected         |            | from the old primary are ignored                
---------------------------|------------|------------------------------------
partition,                 |     CP     | only read access is provided
majority not connected     |            | to avoid separated and inconsistent systems

一致性:

当您使用单个连接或正确的写入/读取关注级别这将降低您的执行速度)时,MongoDB 具有很强的一致性。一旦您不满足这些条件(尤其是当您从辅助副本读取时),MongoDB 就会变得最终一致。

可用性:

MongoDB 通过Replica-Sets获得高可用性。一旦主节点出现故障或变得不可用,辅助节点将确定一个新的主节点再次可用。这样做有一个缺点:由旧主节点执行但未同步到辅助节点的每次写入都将被回滚并保存到回滚文件中,只要它重新连接到集合(旧主节点是辅助节点)现在)。因此,在这种情况下,为了可用性而牺牲了一些一致性。

分区容差:

通过使用上述 Replica-Sets MongoDB 还实现了分区容错性:只要一个 Replica-Set 的一半以上的服务器相互连接,就可以选择一个新的 Primary。为什么?确保两个分离的网络不能同时选择一个新的主。当没有足够的辅助节点相互连接时,您仍然可以从中读取(但不能确保一致性),但不能写入。为了保持一致性,该集合实际上是不可用的。

于 2017-06-08T15:45:05.820 回答
21

由于出现了一篇精彩的新文章以及Kyle 在该领域的一些很棒的实验,在将 MongoDB 和其他数据库标记为 C 或 A 时,您应该小心。

当然 CAP 有助于不费吹灰之力地追踪数据库的优势,但人们经常忘记 CAP 中的 C 意味着原子一致性(线性化)。这让我在尝试分类时很难理解。所以,除了 MongoDB 提供强一致性之外,这并不意味着它是 C。这样,如果有人进行这种分类,我建议也更深入地了解它的实际工作原理,以免留下疑问。

于 2015-05-15T00:19:32.237 回答
12

是的,使用时是CP safe=true。这仅仅意味着,数据进入了主磁盘。如果您想确保它也到达某个副本,请查看“w=N”参数,其中 N 是必须保存数据的副本数。

有关更多信息,请参阅

于 2012-07-02T13:16:38.903 回答
4

只要有分区,MongoDB 就会选择 Consistency over Availability。这意味着当有一个分区(P)时,它会选择一致性(C)而不是可用性(A)。

为了理解这一点,让我们了解一下 MongoDB 是如何实现副本集的。一个副本集有一个主节点。提交数据的唯一“安全”方式是写入该节点,然后等待该数据提交到集合中的大多数节点。(发送写入时,您将看到 w=majority 的标志)

分区可能在以下两种情况下发生:

  • 当主节点关闭时:系统变得不可用,直到选择新的主节点。
  • 当 Primary 节点与太多 Secondary 节点断开连接时:系统不可用。其他辅助节点将尝试选举一个新的主节点,当前的主节点将下台。

Basically, whenever a partition happens and MongoDB needs to decide what to do, it will choose Consistency over Availability. It will stop accepting writes to the system until it believes that it can safely complete those writes.

于 2020-04-22T20:08:26.397 回答
3

Mongodb 从不允许写入辅助。它允许从辅助读取但不允许写入。因此,如果您的主服务器出现故障,您将无法写入,直到辅助服务器再次成为主服务器。这就是在 CAP 定理中牺牲高可用性的方式。通过只从主数据库中读取数据,您可以获得强一致性。

于 2019-08-28T11:07:21.723 回答
2

我不确定Mongo的P。想象一下情况:

  • 您的副本被分成两个分区。
  • Writes continue to both sides as new masters were elected
  • 分区已解决 - 现在所有服务器都已重新连接
  • 发生的情况是新的 master 被选出 - 具有最高 oplog 的那个,但是来自另一个 master 的数据被恢复到分区之前的公共状态,并且它被转储到一个文件以进行手动恢复
  • 所有的次要都赶上了新的主人

这里的问题是转储文件的大小是有限的,如果你有一个分区很长时间,你可能会永远丢失你的数据。

你可以说它不太可能发生——是的,除非在云中它比人们想象的更常见。

这个例子就是为什么在将任何字母分配给任何数据库之前我会非常小心。有这么多的场景和实现并不完美。

如果有人知道这种情况是否已在以后的 Mongo 版本中得到解决,请发表评论!(我已经有一段时间没有关注正在发生的一切了..)

于 2015-10-10T10:16:39.190 回答