sql >> Databasteknik >  >> RDS >> Mysql

Django Multiple Databases Fallback till Master om Slave är nere

Du är på rätt väg med att använda en router. Jag antar att det faktum att dina två db-definitioner är identiska bara är ett stavfel.

(FYI, jag kommer att hänvisa till databashierarkin med den mer känsliga master->följaren )

I dina db_for_read()-funktioner kan du söka efter anslutning till din följare. Detta kan medföra lite mer omkostnader, men det är kostnaden för att ha auto-failover för en databas. Ett exempel på databasdefinition skulle vara:

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 testa anslutningen med ett snabbt försök/förutom som detta exempel . En router som använder denna som gör vad du behöver skulle se ut:

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'

Detta kommer fortfarande att syncdb i master som du vill. Du kan också skapa logiken för både db_for_read() och db_for_write() mer komplicerat (som att välja efterföljaren endast för vissa modeller som efterfrågas för dina rapporter.

Jag vet inte vad det här test_connection() ligger för kommer att orsaka för varje läsning, eftersom det beror på MySQL-servern och timeout. En bättre arkitektur kanske är att cachelagra dessa rapporter med hjälp av memcached, eller bara lösa problemen med att slaven någonsin går ner och uppdatera dina databasdefinitioner i inställningarna först.




  1. Förstå Amazon Auroras Multi-AZ-distribution

  2. Det går inte att logga in på SQL Server + SQL Server Authentication + Fel:18456

  3. Vad är Check Constraint i SQL Server - SQL Server / TSQL Tutorial Del 82

  4. Mysql left join med villkor i höger tabell