Django----配置数据库读写分离

Django配置数据库读写分离

https://blog.csdn.net/Ayhan_huang/article/details/78784486

https://blog.csdn.net/ayhan_huang/article/details/77575186#t4

 

对网站的数据库作读写分离(Read/Write Splitting)可以提高性能,在Django中对此提供了支持,下面我们来简单看一下。注意,还需要运维人员作数据库的读写分离和数据同步。

 

配置数据库

我们知道在Django项目的settings中,可以配置数据库,除了默认的数据库,我在下面又加了一个db2。因为是演示,我这里用的是默认的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'),

},

}

 

 

创建models并执行数据库迁移

这里我简单创建一张产品表

 

from django.db import models

class Products(models.Model):

"""产品表"""

prod_name = models.CharField(max_length=30)

prod_price = models.DecimalField(max_digits=6, decimal_places=2)

 

创建完成后,执行数据库迁移操作:

 

python manage.py makemigrations # 在migrations文件夹下生成记录,迁移前检查

python manage.py migrate # 创建表

 

 

在migrations文件夹下生成记录,并在迁移前检查是否有问题,默认值检查defualt数据库,但是可以在后面的数据库路由类(Router)中通过allow_migrate()方法来指定是否检查其它的数据库。

 

其实第二步迁移默认有参数python manage.py migrate --database default ,在默认数据库上创建表。因此完成以上迁移后,执行python manage.py --database db2,再迁移一次,就可以在db2上创建相同的表。这样在项目根目录下,就有了两个表结构一样的数据库,分别是db.sqlite3和db2.sqlite3。

 

读写分离

手动读写分离

在使用数据库时,通过.using(db_name)来手动指定要使用的数据库

 

from django.shortcuts import HttpResponse

from . import models


def 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)

 

自动读写分离

通过配置数据库路由,来自动实现,这样就不需要每次读写都手动指定数据库了。数据库路由中提供了四个方法。这里这里主要用其中的两个:def db_for_read()决定读操作的数据库,def db_for_write()决定写操作的数据库。

 

定义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',]

 

可以指定多个数据库路由,比如对于读操作,Django将会循环所有路由中的db_for_read()方法,直到其中一个有返回值,然后使用这个数据库进行当前操作。

 

一主多从方案

网站的读的性能通常更重要,因此,可以多配置几个数据库,并在读取时,随机选取,比如:

 

class Router:

  def db_for_read(self, model, **hints):

  """

  读取时随机选择一个数据库

  """

    import random

    return random.choice(['db2', 'db3', 'db4'])

 

  def db_for_write(self, model, **hints):

  """

  写入时选择主库

  """

    return 'default'


分库分表

 

在大型web项目中,常常会创建多个app来处理不同的业务,如果希望实现app之间的数据库分离,比如app01走数据库db1,app02走class Rout

  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'

 

posted on 2018-11-03 08:47  <Hbw>  阅读(293)  评论(0)    收藏  举报