1

在过去的两天里,我一直在阅读和学习 NoSQL 和 MongoDB、CouchDB 等,但我仍然无法确定这是否适合我。

让我担心的是最终的一致性问题。这种类型的一致性是否仅在使用集群时才会发挥作用?(我将我的网站托管在一个专用服务器中,所以我不知道我是否可以从 NoSQL 中受益)对于哪种应用程序可以具有最终一致性(而不是 ACID),对于哪些应用程序不是吨?你能给我一些例子吗?在可以最终保持一致性的应用程序中可能发生的最糟糕的事情是什么?

我读到的另一件事是 MongoDB 在内存中保留了很多东西。在文档中,它说明了具有 2gb 数据限制的 32 位系统。那是因为 32 位系统的内存限制吗?

4

3 回答 3

5

我只能为 CouchDB 发言,但无需在最终一致性和 ACID 之间进行选择,它们不在同一类别中。

CouchDB 完全是 ACID。文档更新是原子的、一致的、隔离的和持久的(使用 CouchDB 推荐的生产设置 delay_commits=false,您的更新会在返回 201 成功代码之前刷新到磁盘)。CouchDB 不提供的是多项目事务(因为当项目存储在单独的服务器中时,这些事务很难扩展)。'transaction' 和 'ACID' 之间的混淆令人遗憾,但也可以原谅,因为典型的 RDBMS 通常同时支持这两者。

最终一致性是关于数据库副本如何在同一数据集上收敛。考虑传统 RDBMS 中的主从设置。该关系的某些配置将使用分布式事务机制,使得主从始终处于同步状态。但是,出于性能原因,通常会放宽这一点。主服务器可以在本地进行事务,然后通过事务日志将它们懒惰地转发给从服务器。这也是“最终一致性”,当日志完全耗尽时,两台服务器将汇聚在同一个数据集上。CouchDB 更进一步,消除了主从之间的区别。也就是说,CouchDB 服务器可以被视为平等的对等点,在任何主机上所做的更改都会正确地复制到其他主机。

最终一致性的诀窍在于如何处理不同主机上相同项目的更新。在 CouchDB 中,这些单独的更新被检测为同一项目上的“冲突”,并且复制确保所有冲突的更新都存在于所有主机上。CouchDB 然后选择其中一个作为当前版本。可以通过删除不想保留的冲突来修改此选择。

于 2011-09-25T16:52:07.000 回答
4
  • 在过去的两天里,我一直在阅读和学习 NoSQL 和 MongoDB、CouchDB 等,但我仍然无法确定这是否适合我。

NoSQL 数据库解决了一系列问题,这些问题很难(更)用传统的 RDMS 解决。the right storage for you如果您的任何问题都在该集合中,则可以使用 NoSQL 。

  • 最终一致性是否仅在使用集群时才起作用?

当您可能从刚刚保留的数据中读回不同/先前版本的数据时,最终一致性“开始” 。例如:

您将同一条数据持久化到多个位置,例如 A 和 B。根据配置,持久化操作可能会在仅持久化到 A(而不是 B)后返回。之后,您从 B 读取该数据,但该数据尚不存在。最终它会在那里,但不幸的是当你读回来的时候不是

  • 对于哪种应用程序可以具有最终一致性(而不是 ACID),而对于哪些不是?

NOT OK=> 你有一个家庭银行账户,有 100 美元可用。现在你和你的配偶试图同时(在不同的商店)以 100 美元的价格买东西。如果银行使用“最终一致性”模型来实现这一点,例如在多个节点上,你的配偶可能在你花完所有的几毫秒后花费了 100 美元。对于银行来说,这不是一个好日子。

OK=> 你在 Twitter 上有 10000 个关注者。你发了推文“嘿,今晚谁想做一些黑客行为?”。100% 的一致性意味着所有这 10000 人都会同时收到您的邀请。但是,如果约翰在玛丽看到你的推文 2 秒后看到了你的推文,那么真的不会发生什么坏事。

  • 在可以最终保持一致性的应用程序中可能发生的最糟糕的事情是什么?

例如,当节点 A 获取数据和节点 B 获取相同的数据 [它们是同步的] 之间存在巨大的延迟。如果 NoSQL 解决方案是可靠的,那将是可能发生的更糟糕的事情。

  • 我读到的另一件事是 MongoDB 在内存中保留了很多东西。在文档中,它说明了具有 2gb 数据限制的 32 位系统。那是因为 32 位系统的内存限制吗?

来自 MongoDB 文档:

" MongoDB 是在 Linux、Windows 和 OS X 上运行的服务器进程。它可以作为 32 位或 64 位应用程序运行。我们建议在 64 位模式下运行,因为 Mongo 的总数据大小限制在大约2GB 用于 32 位模式下的所有数据库。 "

于 2011-09-26T03:49:02.623 回答
1

Brewers CAP 定理是了解您可以使用哪些选项的最佳来源。我可以说这一切都取决于,但如果我们谈论 Mongo,那么它提供了开箱即用的水平可扩展性,并且在某些情况下总是很好。

现在关于一致性。实际上,您可以通过三种方式使数据保持最新:

1)首先要考虑的是“安全”模式或 Andreas 指出的“getLastError()”。如果您发出“安全”写入,您就知道数据库已收到插入并应用了写入。但是,MongoDB 仅每 60 秒刷新一次磁盘,因此服务器可能会在磁盘上没有数据的情况下发生故障。

2)第二件事要考虑的是“日志”(v1.8+)。打开日记功能后,每 100 毫秒将数据刷新到日志中。所以你在失败之前有一个更小的时间窗口。驱动程序有一个比“安全”更进一步的“fsync”选项(检查该名称),它等待确认数据已刷新到磁盘(即日志文件)。但是,这仅涵盖一台服务器。如果服务器上的硬盘死了会发生什么?那么你需要第二个副本。

3)要考虑的第三件事是复制。驱动程序支持“W”参数,表示“将此数据复制到 N 个节点”,然后再返回。如果在某个超时之前写入没有到达“N”个节点,则写入失败(抛出异常)。但是,您必须根据副本集中的节点数正确配置“W”。同样,由于硬盘驱动器可能会发生故障,即使使用日记功能,您也需要查看复制。然后是跨数据中心的复制,这太长了,无法进入这里。最后要考虑的是您对“回滚”的要求。据我了解,MongoDB 没有这种“回滚”能力。如果您正在执行批量插入,您将得到的最好结果是指示哪些元素失败。

无论如何,当数据一致性成为开发人员的责任时,有很多场景,您需要小心并包括所有场景并调整数据库模式,因为在 Mongo 中没有像我们这样的“这是正确的方法”习惯于在 RDB-s 中。

关于内存——这完全是一个性能问题,MongoDB 将索引和“工作集”保存在 RAM 中。通过限制您的 RAM,您可以限制您的工作集。您实际上可以拥有 SSD 和更少量的 RAM,而不是大量的 RAM 和 HDD - 至少这些是官方建议。无论如何,这个问题是个人的,您应该针对您的特定用例进行性能测试

于 2011-09-25T16:50:47.537 回答