如何让MongoDB连接字符串解决被击倒的节点?

时间:2013-09-10 20:32:11

标签: php mongodb replication

我正在对我已设置的群集进行测试。现在,我有一个三节点集群,一个主节点,一个从节点和一个仲裁器。

我有一个类似

的连接字符串
mongodb://admin:pass@the_slave_node,the_master_node

我的印象是连接字符串中固有的一个特性是提供多个主机会在客户端引入一定程度的弹性。我期待当我拿下the_slave_node时,php驱动程序应该已经移动并尝试连接到the_master_node,但是这似乎并非如此,而是我收到了错误:

The MongoCursor object has not been correctly initialized by its constructor

我知道MongoClient负责建立初始连接,实际上它就是代码中的那种方式。所以这个错误告诉我MongoClient没有正确连接,我也没有实现正确的错误检查。然而,这是一个不同的问题 -

如果至少有一台主机启动且某些主机已关闭,我如何保证MongoClient将连接到主机csv中的至少一台主机?

谢谢

1 个答案:

答案 0 :(得分:0)

  

MongoCursor对象尚未被其构造函数

正确初始化

只有在构建自己的MongoCursor并覆盖其构造函数时才会发生此错误。

例如

会发生这种情况
class MyCursor extends MongoCursor {
    function __construct(MongoClient $connection, $ns , array $query = array(), array $fields = array()) {
    /* Do some work, forgetting to call parent::__construct(....); */
    }
}

如果你没有扩展任何类,那么这个错误肯定是一个bug,你应该report it please:)

  

我如何保证MongoClient将连接至少一个主机

将每个数据中心的至少一个成员放入种子列表中。 调整各种超时选项,并计划主要关闭时的情况(例如,您应该从哪个服务器读取?)

我怀疑你可能忘记指定“replicaSet”选项,因为你没有提到你的连接字符串?

我建议使用以下代码段(随意调整),尤其是在可能时需要完全一致的情况下(例如始终从主要内容中读取)。

<?php
$seedList = "hostname1:port,hostname2:port";
$options  = array(
    // If the server is down, don't wait forever
    "connectTimeoutMS"   => 500,
    // When the server goes down in the middle of operation, don't wait forever
    "socketTimeoutMS"    => 5000, 
    "replicaSet"         => "ReplicasetName",
    "w"                  => "majority",
    // Don't wait forever for majority write acknowledgment
    "wtimeout"           => 500,
    // When the primary goes down, allow reading from secondaries
    "readPreference"     => MongoClient::RP_PRIMARY_PREFERRED,
    // When the primary is down, prioritize reading from our local datacenter
    // If that datacenter is down too, fallback to any server available
    "readPreferenceTags" => array("dc:is", ""),
);
try {
    $mc = new MongoClient($seedList, $options);
} catch(Exception $e) {
    /* I always have some sort of "Skynet"/"Ground control"/"Houston, We have a problem" system to automate taking down (or put into automated maintenance mode) my webservers in case of epic failure.. */
    automateMaintenance($e);
}