Django配置数据库读写分离
對(duì)網(wǎng)站的數(shù)據(jù)庫(kù)作讀寫分離(Read/Write Splitting)可以提高性能,在Django中對(duì)此提供了支持,下面我們來簡(jiǎn)單看一下。注意,還需要運(yùn)維人員作數(shù)據(jù)庫(kù)的讀寫分離和數(shù)據(jù)同步。
配置數(shù)據(jù)庫(kù)
我們知道在Django項(xiàng)目的settings中,可以配置數(shù)據(jù)庫(kù),除了默認(rèn)的數(shù)據(jù)庫(kù),我在下面又加了一個(gè)db2。因?yàn)槭茄菔?#xff0c;我這里用的是默認(rèn)的SQLite,如果希望用MySQL,看這里 。
DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': os.path.join(BASE_DIR, 'db.sqlite3'),},'db2': {'ENGINE': 'django.db.backends.sqlite3','NAME': os.path.join(BASE_DIR, 'db2.sqlite3'),}, }創(chuàng)建models并執(zhí)行數(shù)據(jù)庫(kù)遷移
這里我簡(jiǎn)單創(chuàng)建一張產(chǎn)品表
from django.db import modelsclass Products(models.Model):"""產(chǎn)品表"""prod_name = models.CharField(max_length=30)prod_price = models.DecimalField(max_digits=6, decimal_places=2)創(chuàng)建完成后,執(zhí)行數(shù)據(jù)庫(kù)遷移操作:
python manage.py makemigrations # 在migrations文件夾下生成記錄,遷移前檢查 python manage.py migrate # 創(chuàng)建表在migrations文件夾下生成記錄,并在遷移前檢查是否有問題,默認(rèn)值檢查defualt數(shù)據(jù)庫(kù),但是可以在后面的數(shù)據(jù)庫(kù)路由類(Router)中通過allow_migrate()方法來指定是否檢查其它的數(shù)據(jù)庫(kù)。
其實(shí)第二步遷移默認(rèn)有參數(shù)python manage.py migrate --database default ,在默認(rèn)數(shù)據(jù)庫(kù)上創(chuàng)建表。因此完成以上遷移后,執(zhí)行python manage.py --database db2,再遷移一次,就可以在db2上創(chuàng)建相同的表。這樣在項(xiàng)目根目錄下,就有了兩個(gè)表結(jié)構(gòu)一樣的數(shù)據(jù)庫(kù),分別是db.sqlite3和db2.sqlite3。
讀寫分離
手動(dòng)讀寫分離
在使用數(shù)據(jù)庫(kù)時(shí),通過.using(db_name)來手動(dòng)指定要使用的數(shù)據(jù)庫(kù)
from django.shortcuts import HttpResponse from . import modelsdef write(request):models.Products.objects.using('default').create(prod_name='熊貓公仔', prod_price=12.99)return HttpResponse('寫入成功')def read(request):obj = models.Products.objects.filter(id=1).using('db2').first()return HttpResponse(obj.prod_name)自動(dòng)讀寫分離
通過配置數(shù)據(jù)庫(kù)路由,來自動(dòng)實(shí)現(xiàn),這樣就不需要每次讀寫都手動(dòng)指定數(shù)據(jù)庫(kù)了。數(shù)據(jù)庫(kù)路由中提供了四個(gè)方法。這里這里主要用其中的兩個(gè):def db_for_read()決定讀操作的數(shù)據(jù)庫(kù),def db_for_write()決定寫操作的數(shù)據(jù)庫(kù)。
定義Router類
新建myrouter.py腳本,定義Router類:
class Router:def db_for_read(self, model, **hints):return 'db2'def db_for_write(self, model, **hints):return 'default'配置Router
settings.py中指定DATABASE_ROUTERS
DATABASE_ROUTERS = ['myrouter.Router',]可以指定多個(gè)數(shù)據(jù)庫(kù)路由,比如對(duì)于讀操作,Django將會(huì)循環(huán)所有路由中的db_for_read()方法,直到其中一個(gè)有返回值,然后使用這個(gè)數(shù)據(jù)庫(kù)進(jìn)行當(dāng)前操作。
一主多從方案
網(wǎng)站的讀的性能通常更重要,因此,可以多配置幾個(gè)數(shù)據(jù)庫(kù),并在讀取時(shí),隨機(jī)選取,比如:
class Router:def db_for_read(self, model, **hints):"""讀取時(shí)隨機(jī)選擇一個(gè)數(shù)據(jù)庫(kù)"""import randomreturn random.choice(['db2', 'db3', 'db4'])def db_for_write(self, model, **hints):"""寫入時(shí)選擇主庫(kù)"""return 'default'分庫(kù)分表
在大型web項(xiàng)目中,常常會(huì)創(chuàng)建多個(gè)app來處理不同的業(yè)務(wù),如果希望實(shí)現(xiàn)app之間的數(shù)據(jù)庫(kù)分離,比如app01走數(shù)據(jù)庫(kù)db1,app02走數(shù)據(jù)庫(kù)
class Router:def db_for_read(self, model, **hints):if model._meta.app_label == 'app01':return 'db1'if model._meta.app_label == 'app02':return 'db2'def db_for_write(self, model, **hints):if model._meta.app_label == 'app01':return 'db1'if model._meta.app_label == 'app02':return 'db2'更多請(qǐng)參考官網(wǎng)
總結(jié)
以上是生活随笔為你收集整理的Django配置数据库读写分离的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hadoop3.2.2--记录java.
- 下一篇: Rpm包的安装与yum的配置