django mysql 讀寫分離

最近需要用到Django的MySQL讀寫分離技術,查了一些資料,把方法整理了下來。

在Django裏實現對MySQL的讀寫分離,實際上就是將不同的讀寫請求按一定的規則路由到不同的數據庫上(可以是不同類型的數據庫),我們需要做的就是,定義不同的數據庫,定義不同的路由規則。當然前提是你需要手動實現MySQL的主從同步..

首先定義我們的主從數據庫:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'ospf',
        'USER': 'root',
        'PASSWORD': 'hunantv',
    },
    'slave': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'ospf',
        'USER': 'ospf',
        'PASSWORD': 'hunantv',
        'HOST': '192.168.8.52'
    }
}

定義我們的路由規則,路由規則可以有好多個,每個規則是一個類。如下所示:  

import socket
from django.conf import settings

def test_connection_to_db(database_name):
    try:
        db_definition = getattr(settings, 'DATABASES')[database_name]
        s = socket.create_connection((db_definition['HOST'], 3306), 2)
        s.close()
        return True
    except (AttributeError, socket.timeout) as e:
        return False


class FailoverRouter(object):

    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'ospf' and test_connection_to_db('slave'):
            return 'slave'
        return 'default'

    def db_for_write(self, model, **hints):
        "Point all writes to the default db"
        return 'default'

    def allow_relation(self, obj1, obj2, **hints):
        db_list = ('default', 'slave')
        if obj1._state.db in db_list and obj2._state.db in db_list:
            return True
        return None

    def allow_syncdb(self, db, model):
        "Make sure only the default db allows syncdb"
        return db == 'default'

db_for_read.有個read故名思議就是從哪裏讀. app_label是應用的名稱.. 

由於我希望用戶、權限表還是從主數據庫讀,,所以就加了這個限制.. test_connection_to_db 是判斷從數據庫是否異常,, 在異常的情況下會自動到 主數據庫讀取.. 

最後在setting.py中加上這個路由規則:

DATABASE_ROUTERS = ['lvs.models.FailoverRouter']

因爲Django不負責主從數據庫之間的同步,所以如果在讀取完數據後馬上要對數據進行操作,可以顯式地使用主數據庫來讀取並修改數據。

>>> Author.objects.using('default').all() 

>>> my_object.save(using='default')


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章