Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何确保insert()已传播到副本集的所有成员_Php_Mongodb - Fatal编程技术网

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

Php 如何确保insert()已传播到副本集的所有成员,php,mongodb,Php,Mongodb,插入MongoDB集合后立即从中检索文档时遇到问题。我正在创建文档,然后运行一个查询(无法预先确定),以获取集合中所有文档的子集。问题是我插入的部分或全部文档没有包含在结果中 这个过程是: 查找最近记录的时间戳 查找自那时以来发生的事务 为这些事务生成记录,并插入每个事务(insert())(这可以并且将成为单个批量插入) find()一些记录 文档总是成功编写的,但在运行find()时,新文档往往不包括在内。几秒钟后就可以使用了 我相信在我尝试检索新文档时,这些新文档尚未传播到副本集的所有成员

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

这个过程是:

  • 查找最近记录的时间戳
  • 查找自那时以来发生的事务
  • 为这些事务生成记录,并插入每个事务(
    insert()
    )(这可以并且将成为单个批量插入)
  • find()
    一些记录
  • 文档总是成功编写的,但在运行
    find()
    时,新文档往往不包括在内。几秒钟后就可以使用了

    我相信在我尝试检索新文档时,这些新文档尚未传播到副本集的所有成员,尽管我怀疑情况可能并非如此,因为我正在使用与
    insert()
    find()
    相同的连接

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


    我不想硬编码的成员总数,因为这将打破当另一个成员被添加。如果
    insert()
    操作很慢,这无关紧要。

    基本上您正在寻找一个,它(用外行的话说)允许您指定插入何时完成

    在PHP中,这是通过提供

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

    或者如果您不想硬编码
    N

    w=副本集标记集已确认写入操作 由整个标记集的成员确认

    $collection->insert($someDoc,[“w”=>3])

    读取首选项 在向集合写入时,最好将设置为“primary”,以确保正在从写入的同一个MongoDB服务器读取数据

    你可以用这个方法


    写下关注点(不要这样做!) 通过使用
    w=3
    (对于3服务器设置),您可能会尝试使用等待将数据复制到所有辅助设备。然而,这不是我们要走的路

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

    没有
    w=all
    写入所有启动的服务器。使用这样的书面关注是不好的。刚刚从故障转移中恢复的辅助系统可能会落后数小时,需要很长时间才能赶上。您的脚本将等待(挂起),直到所有辅助脚本都被捕获


    一个好的做法是从不在管理任务之外使用
    w=N
    N>多数

    对服务器数量进行硬编码时,如果其中一个二级服务器停机,您会得到一个超时。@Jasny ArnoldDaniels我告诉过你这是个好主意吗?作者明确要求向所有成员宣传——我向他展示了如何实现它。他还表示,他不想硬编码。所以N可能是任何数字。当N在运行时未知时,无法使用此方法。读大师的书解决了他的问题,尽管方式与他提出的不同。@Jasny ArnoldDaniels你的意思是“w=副本集”不是正确的解决方案?
    w=副本集
    不存在。我想你的意思是
    w=
    。是一种高级功能,可用于指定服务器的子集。我不太适合这种情况。要防止读取过时的数据,请从主机读取。除非您100%确定您的设置是100%正常的,否则不应使用写关注N>多数。@Kelvin您不应等到它传播到所有成员。相反,请确保您读取了已写入的服务器(主服务器)。您能显示您的代码吗?另外,您能否澄清您是如何连接到您的实例的?您正在从主目录读取,对吗?
    setReadPreference()
    看起来正是我所需要的,但不幸的是它没有按预期工作;插入的记录仍无法返回。我运行的是MongoDB 2.4,这个版本可能有问题吗?在某些情况下,这是一项管理任务,因此我也不担心插入需要花费一些时间。1)我不认为这是这里的问题,因为OP没有提到读取首选项。2)主选项是最重要的,因此不需要设置。3) 有什么问题吗。这是确保没有回滚的有效方法。我同意W>多数可能是危险的,所以考虑一下
    $db->mycollection->setReadPreference(MongoClient::RP_PRIMARY);
    $db->mycollection->insert(['foo' => 'bar']);
    $result = $db->mycollection->find([]);