zoukankan      html  css  js  c++  java
  • django 实现读写分离

    • 主要目的:单个数据库进行读写操作频繁,降低速度,增加服务器读写数据库压力,为了解决这一问题,对数据库进行读写分离,将大大提升项目的性能。其基本原理是:
      • 让主数据库处理事务性的增删改查,而从数据库处理查询操作,当主数据库因一些事务性操作导致数据变更后,同步更新到其他读库。写库一个,读库可以有多个。采用日志同步的方式实现主从同步。
    1. 在Django的配置文件settings.py中,DATABASES中添加代码如下:

      DATABASES = {
          'default': {
              'ENGINE': 'django.db.backends.mysql',
              'HOST': '127.0.0.1',  # 主服务器的运行ip
              'PORT': 3306,   # 主服务器的运行port
              'USER': 'django',  # 主服务器的用户名
              'PASSWORD': 'django',  # 主服务器的密码
              'NAME': 'djangobase'   #  数据表名
          },
          'slave': {
              'ENGINE': 'django.db.backends.mysql', 
              'HOST': '127.0.0.1',
              'PORT': 8306,
              'USER': 'django_slave',
              'PASSWORD': 'django_slave',
              'NAME': 'djangobase_slave'
          }
      }  
      
    2. 在models.py创建完表后,进行数据库迁移

      python manage.py makemigrations  # 在migrations文件夹下生成记录
      python manage.py migrate --database default  # 默认可以不写参数
      python manage.py migrate --database slave  # 在从库再迁移一次,就可以在上面建立相同的表
      
    3. 创建数据库操作的路由分类

      • 使用sqllite

    • 使用mysql

    • 在项目的utils中创建db_router.py文件,并在该文件中定义一个db类,用来进行读写分离
    #读写分离
    class MasterSlaveDBRouter(object):
     
        def db_for_read(self, model, **hints):
            """读数据库"""
            return "slave"
     
        def db_for_write(self, model, **hints):
            """写数据库"""
            return "default"    #默认的库 读
     
        def allow_relation(self, obj1, obj2, **hints):
            """是否运行关联操作"""
            return True  
    
    #一主多从  多个数据库读  一个数据库写
    class Router:
    
        def db_for_write(self, model, **kwargs):
            return 'db1'
    
        def db_for_read(self, model, **kwargs):
            return random.choices['db2', 'db3', 'db4']
        
    #分库分表
    class Router:
    
        def db_for_write(self, model, **kwargs):
            app_name = model._meta.app_label
            if app_name == 'app01':
                return 'db1'
            elif app_name == 'app02':
                return 'db2'
    
        def db_for_read(self, model, **kwargs):
            app_name = model._meta.app_label
            if app_name == 'app01':
                return 'db1'
            elif app_name == 'app02':
                return 'db2'
    
    1. 配置读写分离路由

      • 在配置文件中增加
      #配置读写分离
      DATABASE_ROUTERS = ['项目名.utils.db_router.MasterSlaveDBRouter("自定义的类名称")']
      
    2. 还可以使用手动的方式进行读写分离

      • 进行orm操作的时候使用using操作对应数据库
      def write(request):
          models.User.objects.using('default').create(name='张三', pwd='123', phone=1234)
          return HttpResponse('写成功')
      
      
      def read(request):
          obj = models.User.objects.filter(id=1).using('db2').first()
          return HttpResponse('读成功')
      
  • 相关阅读:
    教你如何在 Visual Studio 2013 上使用 Github
    如果你也会C#,那不妨了解下F#(1):F# 数据类型
    博客园主题美化
    适配器模式 实战
    mysql in 超过1000 解决方案
    shell: 循环日期+1
    sqoop export 报错:Got exception running Sqoop: org.kitesdk.data.DatasetNotFoundException: Descriptor location does not exist:
    git 回滚到执行版本,并推送到远程分支
    hive表增加字段,并指定字段位置
    微信抢红包架构设计
  • 原文地址:https://www.cnblogs.com/plyc/p/14437422.html
Copyright © 2011-2022 走看看