sql >> Database >  >> RDS >> Mysql

Django Meerdere databases Terugvallen op Master als Slave niet beschikbaar is

U bent op de goede weg met het gebruik van een router. Ik neem aan dat het feit dat uw twee db-definities identiek zijn, gewoon een typfout is.

(Ter info, ik ga verwijzen naar de databasehiërarchie met behulp van de meer gevoelige master->volger )

In je db_for_read()-functies kun je controleren op connectiviteit met je volger. Dit kan wat meer overhead met zich meebrengen, maar dat zijn de kosten van automatische failover voor een database. Een voorbeeld van een databasedefinitie zou zijn:

DATABASES = {
'follower': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'follower',
        'USER': 'root',
        'HOST': '54.34.65.24',
        'PORT': '3306',
    },
'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'application',
        'USER': 'root',
        'HOST': '54.34.65.23',
        'PORT': '3306',
    },
}  

U kunt de verbinding testen met een snelle poging/behalve zoals dit voorbeeld . Een router die dit gebruikt en doet wat je nodig hebt, ziet er als volgt uit:

from django.conf import settings
import socket


def test_connection_to_db(database_name):
    try:
        db_definition = getattr(settings, 'DATABASES')[database_name]
        s = socket.create_connection((db_definition['HOST'], db_definition['PORT']), 5)
        s.close()
        return True
    except (AttributeError, socket.timeout) as e:
        return False


class FailoverRouter(object):
    """A router that defaults reads to the follower but provides a failover back to the default"""

    def db_for_read(self, model, **hints):
        if test_connection_to_db('follower'):
            return 'follower'
        return 'default'

    def db_for_write(self, model, **hints):
        "Point all writes to the default db"
        return 'default'

    def allow_syncdb(self, db, model):
        "Make sure only the default db allows syncdb"
        return db == 'default'

Dit zal nog steeds synchroniseren in de master zoals je wilt. U kunt ook de logica maken voor zowel db_for_read() en db_for_write() ingewikkelder (zoals kies de volger db alleen voor bepaalde modellen die worden opgevraagd voor uw rapporten.

Ik weet niet wat deze test_connection() kost zal veroorzaken voor elke read, aangezien dat afhangt van de MySQL-server en de time-out. Misschien is het een betere architectuur om deze rapporten in de cache op te slaan met behulp van memcached, of gewoon de problemen op te lossen met de slaaf die ooit uitvalt en eerst je databasedefinities bij te werken in de instellingen.




  1. Python's mysqldb obscure documentatie

  2. Het resultaat van een uitdrukking (bijv. Functie-aanroep) gebruiken in een lijst met opgeslagen procedureparameters?

  3. Een csv-bestand naar de SQL Server-database schrijven met python

  4. Hoe postgresql op ubuntu grondig te zuiveren en opnieuw te installeren?