Meine Python-Webanwendung verfügt über mehrere Verbindungen, die auf demselben MongoDb-Server registriert sind, jedoch drei verschiedene Datenbanken. Die Anwendung läuft unter 4 Gunicorn-Mitarbeitern.Blockieren, bis die Konfiguration des neuen Replikatsatzes erfolgreich ist
Ich verwende ein Replikat-Set.
Wenn das primäre heruntergefahren ist, schlägt die aktuelle Abfrage fehl und eine Aktualisierung wird in MongoReplicaSetClient (2.8 geplant, aber ich denke in 3.2 ist es das gleiche). Die nächste Abfrage ist möglicherweise erfolgreich, wenn bis zu diesem Zeitpunkt eine neue Primärdatenbank ausgewählt wird und MonitorThread Informationen darüber erhält, wie die Verbindung des Clients aktualisiert wird.
Die Aktualisierung betrifft jedoch nur diesen Client. Andere Clients, die mit demselben MongoDB-Server verbunden sind, sind nicht betroffen - mit jedem geschieht die gleiche Geschichte. Das bedeutet, dass, wenn jeder Worker mit 3 Datenbanken auf demselben MongoDB-Server verbunden ist und ich dieselbe HTTP-Anfrage wiederhole, die alle 3 Datenbanken verwendet, wenn eine primäre fehlschlägt, dauert es unbestimmte Zeit, alle verbundenen Clients zu aktualisieren. Wenn jede HTTP-Anfrage an jeden von vier Routern round-robiniert wird, benötigen wir 12 Anfragen, um jeden Mongo-Client zu aktualisieren. Aber in Wirklichkeit gehen die Anfragen nicht um.
Blick in PyMongo Code MongoReplicaSetClient._send_message_with_response
Ich sehe, dass, wenn der primäre ausfällt, self.disconnect
genannt wird, die self.__schedule_refresh
nennt. Diese Methode hat das Argument sync
, das erlaubt "zu blockieren, bis die Aktualisierung abgeschlossen ist".
Meine Idee ist zu fangen AutoReconnect
Ausnahme und Anruf __schedule_refresh(sync=True)
auf allen Clients, die mit der fehlgeschlagenen primären verbunden sind und blockieren, bis die neue Replikat-Set-Konfiguration vorhanden ist. Daher werden HTTP-Anfragen nicht verarbeitet (was zu 500 führt), bis die Datenbank in Ordnung ist.
Aber __schedule_refresh
ist eine private Methode. Auch ich weiß nicht, ob es sequentiell auf allen Klienten anschnallt, wird schnell sein - sieht MonitorThread
seine Arbeit in Intervallen aus.
Oder vielleicht könnte ich MongoReplicaSetClient.refresh
verwenden.
Was denken Sie über die Idee? Hat es Nachteile?
Würdest du mir bei der Implementierung helfen?