Django主从数据库分离配置

数据库主从配置,django

发表时间:2020-08-25

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

配置数据库

我们知道在Django项目的settings中,可以配置数据库,除了默认的数据库,我在下面又加了一个db2。因为是演示,我这里用的是MySQL 。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'AAAA',
        'HOST': 'XXXXX',
        'PORT': 3306,
        'USER': 'root',
        'PASSWORD': '1qaz!QAZ',
        'CHARSET': 'utf8',
        'TIME_ZONE': 'Asia/Shanghai',
        },
    'slave1': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'AAAA_slave1',
        'HOST': 'XXXXX',
        'PORT': 3306,
        'USER': 'root',
        'PASSWORD': '1qaz!QAZ',
        'CHARSET': 'utf8',
        'TIME_ZONE': 'Asia/Shanghai',
    },

}

# 数据库路由配置
DATABASE_ROUTERS = [
    # 'common.db_routers.MultiDbRouter', # 多数据库配置
    'common.db_routers.MasterSlaveRouter',  # 主从数据库路由配置
]

迁移文件

其实第二步迁移默认有参数python manage.py migrate --database default ,在默认数据库上创建表。因此完成以上迁移后,执行python manage.py --database slave1,再迁移一次,就可以在slave1上创建相同的表。

读写分离

手动读写分离
在使用ORM 调用数据库时,通过.using(db_name)来手动指定要使用的数据库

自动读写分离

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

定义Router类
新建db_route.py脚本,定义Router类:

import random


# class MultiDbRouter:
#     """多数据库路由"""
#
#     @staticmethod
#     def db_for_read(model, **hints):
#         if model._meta.app_label == 'ar_map':
#             return 'slave1'
#         return 'default'
#
#     @staticmethod
#     def db_for_write(model, **hints):
#         if model._meta.app_label == 'ar_map':
#             return 'slave1'
#         return 'default'
#
#     @staticmethod
#     def allow_relation(obj1, obj2, **hints):
#         return None
#
#     @staticmethod
#     def allow_migrate(db, app_label, model_name=None, **hints):
#         return True


class MasterSlaveRouter:
    """主从复制路由"""

    @staticmethod
    def db_for_read(model, **hints):
        '''指定xxx_app 读数据时,使用指定setting配置的数据库xxx'''
        if model._meta.app_label == 'xxx_app':
            return 'xxx'
        return random.choice(('slave1', ))

    @staticmethod
    def db_for_write(model, **hints):
        '''指定xxx_app 写的时候,使用指定setting配置的数据库xxx'''
        if model._meta.app_label == 'xxx_app':
            return 'xxx'
        return 'default'

    @staticmethod
    def allow_relation(obj1, obj2, **hints):
        return None

    @staticmethod
    def allow_migrate(db, app_label, model_name=None, **hints):
        '''  python manage.py migrate --database=slave1
            django默认迁移 default 数据库
        '''
        return True
'''
稍微追溯一下源码, 当需要一个db时, 拿数据库的manager举例, 会通过django.db的router去获取

而router就是django.db.utils中定义的一个类, 它使用了setttings.py中DATABASE_ROUTERS配置. 

/home/liwuang/.pyenv/versions/3.6.5/lib/python3.6/site-packages/django/db/utils.py
'''

配置Router
settings.py中已经指定DATABASE_ROUTERS

DATABASE_ROUTERS = [
    # 'common.db_routers.MultiDbRouter', # 多数据库配置
    'common.db_routers.MasterSlaveRouter',  # 主从数据库路由配置
]

可以指定多个数据库路由,比如对于读操作,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 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'

 

参考地址:https://www.pythonf.cn/read/140551

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django配置数据库自动读写分离需要使用Django数据库路由功能。数据库路由是Django中的一个机制,它可以根据请求的类型(读请求或写请求)将请求路由到不同的数据库中。以下是配置数据库自动读写分离的步骤: 1. 创建一个数据库路由类,继承自Django的base.DatabaseRouter类,重写db_for_read和db_for_write方法,指定读请求和写请求分别要使用的数据库。 ```python class ReadWriteRouter: def db_for_read(self, model, **hints): return 'read_db' def db_for_write(self, model, **hints): return 'write_db' ``` 2. 将数据库路由类添加到Django的settings.py文件中的DATABASE_ROUTERS设置中。 ```python DATABASE_ROUTERS = ['path.to.ReadWriteRouter'] ``` 3. 在settings.py文件中定义读数据库和写数据库的连接信息。 ```python DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mydatabase', 'USER': 'mydatabaseuser', 'PASSWORD': 'mypassword', 'HOST': 'localhost', 'PORT': '3306', }, 'read_db': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mydatabase', 'USER': 'mydatabaseuser', 'PASSWORD': 'mypassword', 'HOST': 'localhost', 'PORT': '3307', }, 'write_db': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mydatabase', 'USER': 'mydatabaseuser', 'PASSWORD': 'mypassword', 'HOST': 'localhost', 'PORT': '3308', } } ``` 4. 在读数据库和写数据库配置相应的权限和备份策略。读数据库应该具有读权限,且应该配置为只读。写数据库应该具有读写权限,且应该配置为主数据库,其他数据库(如从数据库)应该定期备份。 配置完成后,Django将自动将读请求发送到读数据库中,将写请求发送到写数据库中,实现数据库自动读写分离
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值