如何确保insert()已传播到副本集的所有成员

时间:2015-02-18 11:23:41

标签: php mongodb

我在插入MongoDB集合后立即检索文档时遇到问题。我正在创建文档,然后运行查询(无法提前确定)以获取集合中所有文档的子集。问题是我插入的部分或全部文件未包含在结果中。

过程是:

  1. 查找最新记录的时间戳
  2. 查找自那时以来发生的交易
  3. 为这些交易生成记录,并为每个交易生成insert()(这可以而且将成为单个批量插入)
  4. find()部分记录
  5. 文档总是成功编写,但在运行find()时,通常不会包含新文档。几秒后它们就可用了。

    我相信在我尝试检索它们时,新文档还没有传播到副本集的所有成员,但我怀疑这可能不是这种情况,因为我使用的是{{{ 1}}和insert()

    我相信这可以通过写入问题来解决,但是我不确定要指定什么值以确保文档已传播到副本集的所有成员,或者至少是将用于该副本集的成员。 find()操作,如果可以提前知道的话。

    我不想硬编码成员总数,因为当添加另一个成员时,这会破坏。 find()操作是否缓慢无关紧要。

2 个答案:

答案 0 :(得分:0)

基本上你正在寻找一个write concern,它(在Layman的术语中)允许你指定插入完成的时间。

在PHP中,这是通过提供option in the insert statement来完成的,所以你需要像

这样的东西
  

w = N副本集已确认写入将由主服务器确认,并复制到N-1个辅助服务器。

或者如果您不想硬编码N

  

w =已确认副本集标记集写入将是   由整个标签集的成员承认

$collection->insert($someDoc, ["w" => 3]);

答案 1 :(得分:0)

阅读偏好

当你写一个集合时,最好将readPreference设置为“primary”,以确保你从你写的同一个MongoDB服务器上读取。

您可以使用MongoCollection::setReadPreference()方法执行此操作。

$db->mycollection->setReadPreference(MongoClient::RP_PRIMARY);
$db->mycollection->insert(['foo' => 'bar']);
$result = $db->mycollection->find([]);

写关注(不要这样做!)

您可能很想使用write concern等待数据通过w=3复制到所有辅助节点(对于3服务器设置)。然而,这不是可行的方法。

MongoDB复制的一个好处是,它将自动进行故障转移。在这种情况下,您可能只有少于3台可以接受数据的服务器,导致您的脚本永远等待。

没有w=all写入所有已启动的服务器。使用这样的写入问题并不好。刚刚从故障转移中恢复过来的辅助设备可能会落后数小时,需要很长时间才能赶上。你的脚本会等待(挂起),直到所有的副词都被赶上来。

从不在管理任务之外使用w=NN > majority的良好做法。