Mysql数据库实现读写分离

一、配置多个数据库

settings.py中配置

DATABASES = {
    'default': {
         'ENGINE': 'django.db.backends.mysql',
          'NAME': 'db8',
          'HOST':'127.0.0.1',
          'PORT':3306,
          'USER':'root',
          'PASSWORD':'',
      },
    'slave': {
          'ENGINE': 'django.db.backends.mysql',
          'NAME': 'db9',
          'HOST':'127.0.0.1',
          'PORT':3306,
          'USER':'root',
          'PASSWORD':'',
      },
}

二、手动读写分离

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

  • 优点:不需要进行其余的配置,只需要通过.using(slave)来手动指定要使用的数据库就行。
  • 缺点:在大量的对数据库进行操作之后,此种方法繁琐
查看需要using指定:
    user = User.objects.using('slave').filter(username=user, password=pwd).first()
保存:
    user_obj.save(using='db8')
删除:
    user_obj.delete(using='db8')

三、自动读写分离

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

  • 新建一个数据库操作的路由分发类(新建utils文件夹,文件夹下建db_router.py):
class MasterSlaveDBRouter():
  '''数据库主从读写分离路由'''
    def db_for_read(self, model, **hints):
    """读数据库"""
        return "default"

    def db_for_write(self, model, **hints):
    """写数据库"""
        return "slave"

    def allow_relation(self, obj1, obj2, **hints):
    """是否运行关联操作"""
        return True
  • 在settings中配置路由类:
DATABASE_ROUTERS =["utils.db_router.MasterSlaveDBRouter"]

四、一主多从

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

    class MasterSlaveDBRouter:
        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 MasterSlaveDBRouter:
        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'
    

附:

将数据库的所有表导出到d盘下的abc.sql:
mysqldump -u root -p db8 >d:abc.sql
将abc.sql文件的数据导入到db9数据库内:
mysql -u root -p db9

你可能感兴趣的:(Mysql数据库实现读写分离)