あなたはルーターを使って正しい方向に進んでいます。 2つのdb定義が同一であるという事実は、単なるタイプミスだと思います。
(参考までに、<a rel="nofollow noreferrer noopener" href ="https://stackoverflow.com/questions/2013785/alternative-to-master-and-slave-in-を使用して、データベース階層を参照します。 entity-relationship">より敏感なマスター->フォロワー )
db_for_read()関数で、フォロワーへの接続を確認できます。これにはもう少しオーバーヘッドが発生する可能性がありますが、それはデータベースの自動フェイルオーバーを行うためのコストです。データベース定義の例は次のとおりです。
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',
},
}
thisのように、簡単な試行/例外で接続をテストできます。例 。これを使用して必要なことを実行するルーターは、次のようになります。
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'
これはあなたが望むようにマスターでまだsyncdbになります。また、両方のdb_for_read()
のロジックを作成することもできます。 およびdb_for_write()
より複雑です(レポートでクエリされる特定のモデルに対してのみフォロワーデータベースを選択するなど。
このtest_connection()
のオーバーヘッドがわかりません MySQLサーバーとタイムアウトに依存するため、すべての読み取りが発生します。おそらく、より良いアーキテクチャは、memcachedを使用してこれらのレポートをキャッシュするか、スレーブがダウンする問題を解決し、最初に設定でデータベース定義を更新することです。