Mysql
 sql >> Database >  >> RDS >> Mysql

Lettura slave, configurazione master di lettura-scrittura

Ho un esempio di come farlo sul mio blog all'indirizzo http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/ . Fondamentalmente puoi migliorare la Session in modo che scelga tra master o slave in base alla query. Un potenziale problema con questo approccio è che se hai una transazione che chiama sei query, potresti finire per utilizzare entrambi gli slave in una richiesta ... ma stiamo solo cercando di imitare la funzionalità di Django :)

Un approccio leggermente meno magico che stabilisce anche l'ambito di utilizzo in modo più esplicito che ho usato è un decoratore sui callable di visualizzazione (qualunque siano chiamati in Flask), come questo:

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

with_slave farebbe qualcosa del genere, supponendo che tu abbia una Session e alcuni motori impostati:

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

L'idea è quella di chiamare Session(bind=slave) invoca il registro per ottenere l'oggetto Session effettivo per il thread corrente, creandolo se non esiste, tuttavia poiché stiamo passando un argomento, scoped_session affermerà che la Session che stiamo creando qui è decisamente nuova di zecca.

Lo punti allo "slave" per tutto l'SQL successivo. Quindi, al termine della richiesta, ti assicurerai che la tua app Flask stia chiamando Session.remove() per cancellare il registro per quel thread. Quando il registro verrà utilizzato successivamente sullo stesso thread, sarà una nuova Session collegata al "master".

O una variante, vuoi usare "slave" solo per quella chiamata, questo è "più sicuro" in quanto ripristina qualsiasi collegamento esistente alla sessione:

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

Per ognuno di questi decoratori puoi invertire le cose, fare in modo che la Session sia legata a uno "slave" dove il decoratore la mette su "master" per le operazioni di scrittura. Se volevi uno slave casuale in quel caso, se Flask avesse una sorta di evento "richiesta di inizio" potresti impostarlo a quel punto.