【问题标题】:MongoEngine ReplicaSet Connection fails on stepdownMongoEngine ReplicaSet 连接在降级时失败
【发布时间】:2016-05-09 19:47:16
【问题描述】:

最近我一直在尝试将 Mongoengine 和 Flask 与 Replica 集一起使用。我可以连接,但是当主节点发生变化时,连接会丢失并且出现中断。

这是一个可以测试行为的 sn-p。它使用非常有用的http://flip-flop.mlab.com/ 站点来调试副本集问题

from flask import Flask
from mongoengine import connect
from flask_mongoengine import MongoEngine
import os
db = MongoEngine()
app = Flask(__name__)


class TestDoc(db.Document):
    texto = db.StringField()


class ProductionConfig:
    def get_conn_data(self):
        conn = {
         'host':"mongodb://testdbuser:testdbpass@flip.mongolab.com:53117,flop.mongolab.com:54117/testdb?replicaSet=rs-flip-flop",
         'replicaSet': 'rs-flip-flop'
    }
        return conn


import time

app.config['MONGODB_SETTINGS'] = ProductionConfig().get_conn_data()
db.init_app(app)

if __name__ == '__main__':
    with app.test_client() as c:
        while True:
            time.sleep(1)
            print(TestDoc.objects().count())
            TestDoc(texto="1").save()

每次主节点更改时我都会收到错误消息:pymongo.errors.AutoReconnect: connection closed

非常感谢!我尝试了几个不同的 pyMongo 版本,但没有成功。任何帮助都将非常非常感谢!

【问题讨论】:

  • 你能确认你运行的是哪个版本的mongoengine和mongodb吗?
  • 我一直在使用 pymongo==3.2 和 flask-mongoengine==0.7.4

标签: python-3.x flask mongoengine replicaset flask-mongoengine


【解决方案1】:

这里的问题是新主节点的选举不是即时的。来自the docs

它会有所不同,但副本集通常会在一个 分钟。

例如,副本的成员可能需要 10-30 秒 设置为声明一个主节点不可访问(参见electionTimeoutMillis)。一 余下的二级党员举行选举,将自己选为 新的小学。选举期间,集群不可用 写。

选举本身可能还需要 10-30 秒。

在主节点宕机和副本被选为新主节点之间的这段时间内,没有连接可以接受写入(因为它们必须转到主节点)。

但是,您可以对代码执行一些操作,使其在这些情况下更具弹性。

首先,您应该在连接上设置读取首选项 (more info here):

    conn = {
     'host':"mongodb://testdbuser:testdbpass@flip.mongolab.com:53117,flop.mongolab.com:54117/testdb",
     'replicaSet': 'rs-flip-flop',
    'read_preference': ReadPreference.SECONDARY_PREFERRED
    } 

这意味着在选举期间读取应该非常强大。

不幸的是,如果在选举期间尝试编写代码,如果没有将所有写入都包含在 try 块中,您的代码将会崩溃。

这应该比您的问题示例中看起来的问题要少,因为(假设您在烧瓶路由中进行写入)网络服务器将抛出 500 错误响应。当您再次从烧瓶请求路由时,选举应该已经完成​​,并且 mongoengine 将写入新的主节点。

【讨论】:

  • 这完全正确。留给我做的另一件事是更改我的 uwsgi 文件添加“lazy-apps = true”。否则,当出现连接错误(由于故障转移)时,整个应用程序将冻结。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 2014-08-24
  • 1970-01-01
  • 2020-05-27
  • 2013-07-25
  • 1970-01-01
相关资源
最近更新 更多