Jesteś na dobrej drodze z użyciem routera. Zakładam, że to, że twoje dwie definicje baz danych są identyczne, to tylko pomyłka.
(FYI, zamierzam odwołać się do hierarchii bazy danych, używając bardziej wrażliwy master->follower )
W swoich funkcjach db_for_read() możesz sprawdzić łączność ze swoim obserwatorem. Może to wiązać się z nieco większym obciążeniem, ale jest to koszt automatycznego przełączania awaryjnego bazy danych. Przykładowa definicja bazy danych to:
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',
},
}
Możesz przetestować połączenie za pomocą szybkiej próby/poza tym, jak to przykład . Router używający tego, który robi to, czego potrzebujesz, wyglądałby tak:
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'
To nadal będzie synchronizowane w master, tak jak chcesz. Możesz także stworzyć logikę dla obu db_for_read()
i db_for_write()
bardziej skomplikowane (np. wybierz bazę danych obserwujących tylko dla niektórych modeli, które są odpytywane w Twoich raportach.
Nie wiem, jakie obciążenie to test_connection()
spowoduje to dla każdego odczytu, ponieważ będzie to zależeć od serwera MySQL i limitu czasu. Być może lepszą architekturą jest buforowanie tych raportów za pomocą memcached lub po prostu rozwiązanie problemów z awarią urządzenia podrzędnego i zaktualizowanie definicji bazy danych w ustawieniach.