Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Slave lesen, Master-Setup lesen/schreiben

Ich habe ein Beispiel dafür in meinem Blog unter http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/ . Grundsätzlich können Sie die Session so erweitern, dass sie Abfrage für Abfrage zwischen Master oder Slave auswählt. Ein möglicher Fehler bei diesem Ansatz besteht darin, dass Sie bei einer Transaktion, die sechs Abfragen aufruft, möglicherweise beide Slaves in einer Anfrage verwenden .... aber wir versuchen nur, Djangos Funktion zu imitieren :)

Ein etwas weniger magischer Ansatz, der auch den Umfang der Verwendung expliziter festlegt, den ich verwendet habe, ist ein Decorator für aufrufbare Anzeigen (wie auch immer sie in Flask heißen), wie dieser:

@with_slave
def my_view(...):
   # ...

with_slave würde so etwas tun, vorausgesetzt, Sie haben eine Sitzung und einige Engines eingerichtet:

master = create_engine("some DB")
slave = create_engine("some other DB")
Session = scoped_session(sessionmaker(bind=master))

def with_slave(fn):
    def go(*arg, **kw):
        s = Session(bind=slave)
        return fn(*arg, **kw)
    return go

Die Idee ist, dass der Aufruf von Session(bind=slave) ruft die Registrierung auf, um das tatsächliche Sitzungsobjekt für den aktuellen Thread abzurufen, und erstellt es, wenn es nicht existiert. Da wir jedoch ein Argument übergeben, wird scoped_session behaupten, dass die Sitzung, die wir hier erstellen, definitiv brandneu ist.

Sie richten es für alle nachfolgenden SQL auf den "Slave". Wenn die Anfrage beendet ist, stellen Sie sicher, dass Ihre Flask-App Session.remove() aufruft um die Registrierung für diesen Thread zu löschen. Wenn die Registrierung das nächste Mal im selben Thread verwendet wird, wird es eine neue Sitzung sein, die an den "Master" zurückgebunden wird.

Oder eine Variante, Sie möchten den "Slave" nur für diesen Anruf verwenden, dies ist insofern "sicherer", als es alle vorhandenen Bindungen an die Sitzung wiederherstellt:

def with_slave(fn):
    def go(*arg, **kw):
        s = Session()
        oldbind = s.bind
        s.bind = slave
        try:
            return fn(*arg, **kw)
        finally:
            s.bind = oldbind
    return go

Für jeden dieser Dekorateure können Sie die Dinge umkehren, indem Sie die Sitzung an einen "Slave" binden, wo der Dekorateur sie für Schreibvorgänge auf "Master" setzt. Wenn Sie in diesem Fall einen zufälligen Slave wollten, wenn Flask eine Art "Anforderungsbeginn"-Ereignis hätte, könnten Sie es an diesem Punkt einrichten.