Bạn đang đi đúng hướng với việc sử dụng bộ định tuyến. Tôi giả định rằng thực tế là hai định nghĩa db của bạn giống hệt nhau chỉ là lỗi đánh máy.
(FYI, tôi sẽ tham khảo hệ thống phân cấp cơ sở dữ liệu bằng cách sử dụng người theo dõi chính-> nhạy cảm hơn )
Trong các hàm db_for_read (), bạn có thể kiểm tra kết nối với người theo dõi của mình. Điều này có thể phát sinh chi phí nhiều hơn một chút, nhưng đó là chi phí của việc tự động chuyển đổi dự phòng cho cơ sở dữ liệu. Một định nghĩa cơ sở dữ liệu mẫu sẽ là:
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',
},
}
Bạn có thể kiểm tra kết nối bằng cách thử nhanh / ngoại trừ như cái này ví dụ . Một bộ định tuyến sử dụng điều này thực hiện những gì bạn cần sẽ trông giống như sau:
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'
Điều này sẽ vẫn syncdb trong chính như bạn muốn. Ngoài ra, bạn có thể tạo logic cho cả db_for_read()
và db_for_write()
phức tạp hơn (chẳng hạn như chọn db người theo dõi chỉ dành cho một số mô hình nhất định được truy vấn cho báo cáo của bạn.
Tôi không biết chi phí này test_connection()
này là bao nhiêu sẽ gây ra cho mỗi lần đọc, vì điều đó sẽ phụ thuộc vào máy chủ MySQL và thời gian chờ. Có lẽ một kiến trúc tốt hơn là lưu các báo cáo này vào bộ nhớ cache bằng cách sử dụng memcached, hoặc chỉ cần giải quyết các vấn đề với nô lệ đã từng gặp sự cố và cập nhật các định nghĩa cơ sở dữ liệu của bạn trong cài đặt trước.