0

我正在我设置的集群上运行一些测试。现在,我有一个三节点集群,一个主节点、一个从节点和一个仲裁节点。

我有一个像这样的连接字符串

mongodb://admin:pass@the_slave_node,the_master_node

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

The MongoCursor object has not been correctly initialized by its constructor

我知道 MongoClient 负责建立初始连接,实际上在代码中就是这样。所以这个错误向我表明 MongoClient 没有正确连接并且我没有实施正确的错误检查。然而,这是一个不同的问题——

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

谢谢

4

1 回答 1

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(....); */
    }
}

如果你没有扩展任何类,那么这个错误肯定是一个错误,你应该报告它:)

我如何保证 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);
}
于 2013-10-18T01:11:01.217 回答