2

最近、レプリカ セットで Mongoengine と Flask を使用しようとしています。接続できますが、プライマリ ノードが変更されると、接続が失われ、切断されます。

これは、動作をテストできるスニペットです。非常に便利な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 バージョンを試しましたが、成功しませんでした。どんな助けでも本当に、本当に感謝します!

4

1 に答える 1

0

ここでの問題は、新しい予備選挙の選挙が瞬時に行われないことです。ドキュメントから:

状況によって異なりますが、通常、レプリカ セットは 1 分以内に新しいプライマリを選択します。

たとえば、レプリカ セットのメンバーがプライマリにアクセスできないことを宣言するのに 10 ~ 30 秒かかる場合があります (electionTimeoutMillis を参照)。残りのセカンダリの 1 つが選挙を行い、自身を新しいプライマリとして選出します。選択中、クラスターは書き込みに使用できません。

選択自体には、さらに 10 ~ 30 秒かかる場合があります。

プライマリがダウンしてからレプリカが新しいプライマリとして選出されるまでの間に、書き込みを受け入れる接続がありません (プライマリに移動する必要があるため)。

ただし、このような状況での回復力を高めるために、コードにできることがいくつかあります。

まず、接続に読み取り設定を設定する必要があります (詳細はこちら):

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

これは、選挙中の読み取りがかなり堅牢であることを意味します。

残念ながら、すべての書き込みをtryブロックでラップしない限り、選挙中に書き込みを行おうとすると、コードが失敗します。

(フラスコルートで書き込みを行っていると仮定すると)Webサーバーが500エラー応答をスローするため、これは質問の例よりも問題が少ないはずです。フラスコからルートを再度リクエストするまでに、選択は完了し、mongoengine は新しいプライマリに書き込みます。

于 2016-05-27T15:05:26.947 に答える