Mysql
 sql >> Base de données >  >> RDS >> Mysql

Lecture esclave, configuration maître lecture-écriture

J'ai un exemple de la façon de procéder sur mon blog à http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/ . Fondamentalement, vous pouvez améliorer la session afin qu'elle choisisse entre le maître ou l'esclave sur une base requête par requête. Un problème potentiel avec cette approche est que si vous avez une transaction qui appelle six requêtes, vous pourriez finir par utiliser les deux esclaves dans une seule requête... mais là, nous essayons juste d'imiter la fonctionnalité de Django :)

Une approche un peu moins magique qui établit également la portée de l'utilisation plus explicitement que j'ai utilisée est un décorateur sur les callables de vue (quel que soit leur nom dans Flask), comme ceci :

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

with_slave ferait quelque chose comme ça, en supposant que vous ayez une session et que certains moteurs soient configurés :

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'idée est que l'appel de Session(bind=slave) appelle le registre pour accéder à l'objet Session réel pour le thread actuel, en le créant s'il n'existe pas - cependant, puisque nous passons un argument, scoped_session affirmera que la Session que nous créons ici est définitivement toute nouvelle.

Vous le pointez sur "l'esclave" pour tous les SQL suivants. Ensuite, lorsque la demande est terminée, vous vous assurez que votre application Flask appelle Session.remove() pour vider le registre de ce thread. Lors de la prochaine utilisation du registre sur le même thread, il s'agira d'une nouvelle session liée au "maître".

Ou une variante, vous voulez utiliser "l'esclave" juste pour cet appel, c'est "plus sûr" en ce sens qu'il restaure toute liaison existante à la session :

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

Pour chacun de ces décorateurs, vous pouvez inverser les choses, faire en sorte que la session soit liée à un "esclave" où le décorateur la place sur "maître" pour les opérations d'écriture. Si vous vouliez un esclave aléatoire dans ce cas, si Flask avait une sorte d'événement "demande de début", vous pouvez le configurer à ce stade.