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

Django Multiple Databases Fallback til Master, hvis Slave er nede

Du er på rette vej med at bruge en router. Jeg antager, at det faktum, at dine to db-definitioner er identiske, blot er en tastefejl.

(FYI, jeg vil henvise til databasehierarkiet ved hjælp af den mere følsomme master->følger )

I dine db_for_read()-funktioner kan du tjekke, om der er forbindelse til din følger. Dette kan medføre lidt mere overhead, men det er omkostningerne ved at have auto-failover for en database. Et eksempel på en databasedefinition ville være:

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',
    },
}  

Du kan teste forbindelsen med et hurtigt forsøg/undtagen som dette eksempel . En router, der bruger denne, og som gør det, du har brug for, ser sådan ud:

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'

Dette vil stadig syncdb i master, som du ønsker. Du kan også lave logikken for både db_for_read() og db_for_write() mere kompliceret (som f.eks. kun at vælge følger-db for visse modeller, der forespørges til dine rapporter.

Jeg ved ikke, hvad denne test_connection() ligger til grund for vil forårsage for hver læsning, da det vil afhænge af MySQL-serveren og timeout. Måske er en bedre arkitektur at cache disse rapporter ved hjælp af memcached, eller bare finde ud af problemerne med at slaven nogensinde går ned og opdatere dine databasedefinitioner i indstillinger først.




  1. Tildeling af den samme parameterværdi flere gange i pdo execute

  2. Fejlfinding af disk I/O-flaskehalse

  3. Dårlig praksis i databasedesign

  4. Indsæt data og indstil fremmednøgler med Postgres