Doctrine ODM / MongoDB没有重试查询?

时间:2012-06-20 17:58:12

标签: php mongodb doctrine doctrine-odm

我正在使用Doctrine ODM连接到MongoDB。我有一个三节点副本集:两个fulls和一个仲裁器。复制仅用于提高可用性,我不寻求跨节点分发读取。我的应用程序经常使用消息MongoCursorException记录not master and slaveok=false。我没有看到任何证据表明mongodb日志中发生了故障转移事件,并且主要事件没有发生变化。更正:确实发生了故障转移,但not master and slaveok=false的例外情况经常出现,甚至在新主要成功当选后6小时出现。

怎么办?我看到我们的doctrine-mongodb版本包含(experimental?) retry functionality,但我看不到一种简单的方法来启用它。

不确定是否重要,但这是一个Symfony2(v2.0)应用程序。

https://groups.google.com/d/topic/mongodb-user/6p710Rdycpg/discussion意味着我们需要重试(强调我的):

  

您的申请必须写入以重新连接/重试,因为有   任何数量的瞬态(网络)错误都可能出现   正常运行期间的滚动升级过程

Mongo PHP extension docs似乎解释了这一点:

  

如果第一次尝试因某些原因失败,驱动程序将自动重试“普通”查询(而不是命令)几次。这是为了在副本集故障转移期间减少异常(尽管您可能仍需要处理一些故障)并掩盖瞬态网络问题。

我认为doctrine-mongodb只是使用PHP扩展来实际与mongod交谈。所以我有点困惑,我是否应该担心重试配置。

我想我解决了部分问题:我this advice from Kristina Chodorow后面的连接字符串中删除了仲裁。我不再看到任何MongoCursorException个消息not master and slaveok=false。我可能一直在打https://jira.mongodb.org/browse/PHP-392

但是,在故障转移期间,我仍然收到一些MongoCursorException消息couldn't determine master。例如,我刚刚进行了故障转移;根据mongod日志,几秒钟后就会选出一个新的主服务器,但Web应用程序甚至在5分钟后就抛出了这个异常。

2 个答案:

答案 0 :(得分:6)

我假设您正在使用与DoctrineMongoDBBundle上的2.0分支对应的其中一个标记(此时最多为2.2.1)。 Symfony 2.1+兼容性在捆绑版本3+中。

配置类在文档管理器级别公开retry_queryretry_connect选项,默认为零。在YML中,配置如下所示:

doctrine_mongodb:
    # Other proxy, hydrator and connection configuration options

    default_document_manager: dm1

    document_managers:
        dm1:
            retry_query: 1
            retry_connect: 1
            # Other mapping, metadata and DM options follow

我意识到bundle documentation中未提及此问题,因此我在this commit中添加了一个部分。

答案 1 :(得分:1)

您是否已将replicaSet选项配置为指向MongoDB中配置的指定副本集?

Symfony DoctrineMongoDBBundle Docs

查看底部的完整配置。据我所知,您需要命名服务器配置行中的所有服务器 AND 在选项部分中命名replicaSet。该页面上的文档并没有说清楚。

查看代码。看起来应该通过设置来配置重试系统。

retryConnect
retryQuery

与数据库名称处于同一级别。

这是我的Zend Framework配置的一个例子,基本上做同样的事情。

; Database details
resources.odm.configuration.defaultDB = "test"
resources.odm.connection.options.replicaSet = "test-replica-set"
resources.odm.connection.server = "mongodb://rs1a.testing.com:27017,rs1b.testing.com:27017,rs1c.testing.com:27017"
resources.odm.configuration.retryConnect = 3
resources.odm.configuration.retryQuery = 3

当我没有配置replicaSet时,我遇到了类似的错误。