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