我正在使用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分钟后就抛出了这个异常。
答案 0 :(得分:6)
我假设您正在使用与DoctrineMongoDBBundle上的2.0分支对应的其中一个标记(此时最多为2.2.1)。 Symfony 2.1+兼容性在捆绑版本3+中。
配置类在文档管理器级别公开retry_query
和retry_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时,我遇到了类似的错误。