MongoDB的插入安全模式有多安全?

时间:2011-08-11 13:51:21

标签: mongodb batch-file safe-mode

我正在开发一个包含一些重要数据的项目。这意味着如果灯或服务器发生故障,我们不能丢失任何一个。我们正在使用MongoDB作为数据库。如果没有插入一个元素,我想确保在插入和回滚整个批处理之后我的数据在数据库中。我知道Mongo背后的哲学是我们不需要交易,但我怎样才能确保我的数据在插入后真的安全存储而不是发送到某个“黑洞”。

  • 我应该搜索一下吗?

  • 我应该使用一些特定的mongoDB命令吗?

  • 即使一台服务器满足要求,我也应该使用分片 速度和方式如果光线不保证任何东西 落下了?

什么是最佳解决方案?

2 个答案:

答案 0 :(得分:14)

您最好的选择是使用写问题 - 这些允许您告诉MongoDB一个数据的重要性。最快的Write Concern也是最不安全的 - 在下一次预定的刷新之前,数据不会刷新到磁盘。最安全的将确认数据已经在多台机器上写入磁盘,然后再返回。

您正在寻找的写问题是FSYNC_SAFE(至少从Java driver的角度来看它是调用的)或REPLICAS_SAFE,它确认您的数据已被复制。

请记住,MongoDB没有传统意义上的事务 - 您的回滚必须手动滚动,因为您无法告诉Mongo数据库为您执行此操作。

您需要做的另一件事是使用相对较新的--journal选项(使用Write Ahead Log),或者使用副本集在多台计算机之间共享数据,以便最大限度地提高数据的完整性。发生碰撞/断电事件。

在处理特别大的数据集时,分片不是一种防止硬件故障作为共享负载的方法 - 分片不应该与副本集混淆,副本集是一种将数据写入多个磁盘的方法而不是一台机器。

因此,如果您的数据足够有价值,您肯定应该使用副本集,甚至可能选择其他数据中心/可用区/机架/等中的从站,以提供您所需的弹性。

有一种方法可以指定副本集中各个节点的优先级(不记得是否已经实现了),这样如果主节点发生故障,则选择的新主节点是如果这样的机器可用(即阻止该国另一侧的奴隶成为主人,除非它确实是唯一的其他选择),所以同一个数据中心。

答案 1 :(得分:5)

我收到了Google群组中名为 GVP 的人的非常好的回答。我会引用它(基本上它加起来Rich的答案):

  

我想确保我的数据在数据库之后   如果未插入一个元素,则插入并回滚整个批次。

     

这是一个复杂的主题,你必须做出一些权衡   考虑一下。

     

我应该使用分片吗?

     

Sharding用于缩放写入。为了数据安全,你想看一个   副本集。

     

我应该使用一些特定的mongoDB命令吗?

     

首先要考虑的是“安全”模式或“getLastError()”   安德烈亚斯表示。如果您发出“安全”写,您就知道了   数据库已收到插入并应用了写入。然而,   MongoDB每60秒只刷新一次磁盘,因此服务器可能会失败   没有磁盘上的数据。

     

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

     

要考虑的第三件事是   复制。驱动程序支持“W”参数,表示“复制”   返回前,此数据为N个节点。如果写入未达到   “N”节点在某个超时之前,然后写入失败(异常   扔了)。但是,您必须根据以下内容正确配置“W”   副本集中的节点数。再次,因为一个硬盘   可能会失败,即使有日记,你也会想看看复制。   然后是跨数据中心的复制,这种复制太长了   进入这里。最后要考虑的是你需要“滚动”   从我的理解,MongoDB没有这个“回滚”   容量。如果您正在进行批量插入,那么您将获得最佳效果   指示哪些元素失败。

     

以下是此驱动程序上PHP驱动程序的链接:http://it.php.net/manual/en/mongocollection.batchinsert.php您必须检查有关复制和W参数的详细信息。我相信同样的限制适用于此。