当成员变得不可用时,MongoDB副本集非常慢

时间:2012-03-13 14:18:17

标签: php mongodb

我们昨天遇到了生产系统问题 在遵循官方文件时无法解释。

设置:

  • MongoDB 2.0.1
  • 副本集跨越5个具有一个首选主节点的服务器
  • 使用PHP驱动程序的V 1.2.6的PHP应用程序
  • 一个大约有300万条目的集合
  • SlaveOkay为每个连接设置为true
  • MongoDB的连接字符串包括副本集中的所有五个服务器

问题:

昨天其中一个副手突然死亡(硬件崩溃)和 变得完全无法使用从那时起,许多人都读了 从PHP驱动程序执行的操作花了30多秒 完成(在它很少超过0.1秒之前)。

  • rs.status()清楚地报告说失败的二级是 NOK,无法访问。
  • 所有相同的查询都直接通过控制台发送到主要或 任何次要的都在0.1秒内处理(如预期的那样)

一开始我接受了失败的二级参考 从PHP中的连接字符串,但这没有产生任何变化 整体表现。只有当我做了一个明确的 来自副本集的rs.remove(hostname_port)执行了性能 恢复正常。

我想这不是预期的行为?我们可以保护自己吗? 将来有这样的事情吗?

4 个答案:

答案 0 :(得分:2)

与V1.2.6 php驱动程序相关的副本集至少有一个significant bug。您是否可以将驱动程序升级到更新版本?

答案 1 :(得分:1)

我最近也有同样的问题。

解决方案是在php中设置mongo“ timeout ”参数。

原因是不同的 - 当其中一个mongodb服务器关闭时,另一个Linux机箱正在尝试与无法访问的mongo实例建立TCP连接。操作系统将使用预定义的间隔发送几个SYN数据包,尝试建立连接。您可以通过“cat / proc / sys / net / ipv4 / tcp_syn_retries 查看重试次数(请参阅http://www.sekuda.com/overriding_the_default_linux_kernel_20_second_tcp_socket_connect_timeout的更多信息)。如果没有mongo“超时”,php应用程序将不得不等待“操作系统连接尝试时间”,这会显着增加加载时间。
如果tcp_sync_retreis太高,PHP可能会在操作系统完成连接尝试之前达到默认的mongo“timeout”(等于PHP default_socket_timeout)。 PHP将超时,Web服务器可能会返回504 Gateway Timeout错误(在我们的例子中,它是使用nginx& php-fpm)。

答案 2 :(得分:0)

您解决了这个问题吗?

我们有类似的东西,它似乎与连接字符串中节点的顺序有关。

如果您的故障服务器是连接字符串中的第一个,则PHP驱动程序将等待该连接尝试超时,然后再尝试第二个服务器,依此类推。如果您的超时设置为默认值20秒,则会造成很大的延迟。

我们还没有解决这个问题。

答案 3 :(得分:0)

昨天我遇到了这个问题

场景:PHP 5.4 + mongodb 2.4.8 replicaset with 3 servers

当mongodb守护程序关闭但同一个linux服务器网络启动时 php应用程序没有问题。

当replicaset中三个mongodb服务器中的任何一个服务器的linux服务器关闭时,页面加载需要永远完成,对于php来说非常慢

我的结论是它与mongodb无关,实际上是一个网络问题

所以我只是在replicaset连接的options hash中设置了 timeout 参数,如下所示:

$options = [
    "replicaSet"     => $_ENV['MONGODB_REPLICA'], 
    "readPreference" => \MongoClient::RP_SECONDARY_PREFERRED,
    "timeout"        => 1000
];
self::$mongoClient = new \MongoClient($_ENV['MONGODB_URI'], $options);

该解决方案为我解决了问题。 我希望它也可以帮助你们。