首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django多个数据库返回到主人,如果从被关闭

Django多个数据库返回到主人,如果从被关闭
EN

Stack Overflow用户
提问于 2014-10-28 12:54:21
回答 1查看 6K关注 0票数 17

我已经为Django的MySQL db后端设置了主从复制设置。目前,我只为主数据库读写,但我的仪表板是相当密集的查询。我在寻找一个选项,在其中我可以定义如下数据库

代码语言:javascript
复制
DATABASES = {
'default_slave': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'application',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '3306',
    },
'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'application',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '', 
        'PORT': '3306',
    },
}  

对于仪表板、报告和其他各种应用程序,我想做的是:

尝试连接: default_slave :如果可以访问default_slave,则使用default

也就是说,如果从数据库启动,则从从数据库本身获取报告,如果不从主数据库获取报告,则从主数据库获取报告。

Catch是,从可以向上或向下,我希望这是动态可选择的数据库用于获取报告,基于可重述。

这有可能吗?我能在手前测试连接并向前移动吗?

有了这个,我会写和sync_db的主人,并始终读从奴隶,如果奴隶是上。

需要一些raw queriesorm queries的解决方案/提示

路由器的概念看上去不错,但我不知道是否有可能在从上掉头。

更新

如何进行多数据库

数据库

代码语言:javascript
复制
DATABASES = {
'default_slave': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'application',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '3306',
    },
'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'application',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '', 
        'PORT': '3306',
    },
}  
'linux': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'application',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '', 
        'PORT': '3306',
    },
}  
'linux_slave': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'application',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '', 
        'PORT': '3306',
    },
}  
'mac': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'application',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '', 
        'PORT': '3306',
    },
}  
'mac_slave': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'application',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '', 
        'PORT': '3306',
    },
}  
'pc': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'application',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '', 
        'PORT': '3306',
    },
}  
'pc_slave': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'application',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '', 
        'PORT': '3306',
    },
}  

现在,我有了1.静态数据2.动态数据

静态数据必须存储在“默认”中,然后复制到“default_slave”中

对于动态数据,查询首先需要判断动态数据可能位于何处:在“mac”、“pc”或“linux”中。

为此,我在“静态表”中添加了一个字段:“query_on”,它包含“mac”、“linux”或“pc”。

现在,通过使用查询集,我只是在编写static = Static.objects.get(pk = 1)

query_on = static.query_on dynamic = Dynamic.objects.get(static = static).using(alias=query_on)

这很好,查询路由到它需要执行的数据库,这里我需要判断:

  1. 如果<'query_on'>_slave:connection已启动:使用:<'query_on'>_slave
  2. 如果<'query_on'>_slave:connection关闭:使用:<'query_on'>

怎么做呢?

应用程序的详细信息:

  1. 有一个数据库:默认(配置和分析数据库):用于维护配置数据和报表分析数据。
  2. 有20个数据库(原始数据库):例如: mac、linux、rhel、windows、pc .(示例名称):用于收集原始数据,这不是用于分析的进程
  3. 每个数据库都有一个或多个从站,命名约定也是: default_slave_0、default_slave_1、default_slave_2等等。

现在需要每5分钟、30分钟、1小时先查询分析数据.这个查询需要发送到特定的数据库,因为并不是每个数据库都包含分析所需的特定数据集。

要做到这一点,我们需要

  1. 从以下位置获取配置数据(默认值或其任何一个从站(问题是从部份))
  2. 一旦我们有了配置,我们就可以很容易地查看“原始”数据可能在哪里。
  3. 查询原始数据,收集结果并进行分析->将其存储在“默认”数据库中。

现在,所有的30 (raw)和1个默认数据库都需要“同步”,因为我们在所有节点中都维护相同的数据abse结构。

现在,由于我们正在查看所有数据库上的CPU峰值,所以使用“从”数据库查询“原始”数据是有意义的。

因此,提出了using的要求。我无法想象路由器在这里会有什么帮助?

EN

回答 1

Stack Overflow用户

发布于 2014-11-13 18:48:55

你在正确的轨道上使用路由器。我假设您的两个db定义是相同的,这只是一个错误。

(FYI,我将使用the more sensitive master->follower引用数据库层次结构)

在您的db_for_read()函数中,您可以检查与您的追随者的连接性。这可能会带来更多的开销,但这是数据库自动故障转移的成本。数据库定义的一个例子是:

代码语言:javascript
复制
DATABASES = {
'follower': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'follower',
        'USER': 'root',
        'HOST': '54.34.65.24',
        'PORT': '3306',
    },
'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'application',
        'USER': 'root',
        'HOST': '54.34.65.23',
        'PORT': '3306',
    },
}  

您可以通过快速尝试/除了this example这样的方法来测试连接。使用它的路由器可以满足您的需要:

代码语言:javascript
复制
from django.conf import settings
import socket


def test_connection_to_db(database_name):
    try:
        db_definition = getattr(settings, 'DATABASES')[database_name]
        s = socket.create_connection((db_definition['HOST'], db_definition['PORT']), 5)
        s.close()
        return True
    except (AttributeError, socket.timeout) as e:
        return False


class FailoverRouter(object):
    """A router that defaults reads to the follower but provides a failover back to the default"""

    def db_for_read(self, model, **hints):
        if test_connection_to_db('follower'):
            return 'follower'
        return 'default'

    def db_for_write(self, model, **hints):
        "Point all writes to the default db"
        return 'default'

    def allow_syncdb(self, db, model):
        "Make sure only the default db allows syncdb"
        return db == 'default'

这仍然会像你想要的那样在主数据库中同步。此外,您还可以使db_for_read()db_for_write()的逻辑变得更加复杂(例如,只为查询报表的某些模型选择跟随数据库)。

我不知道这个test_connection()会给每次读取带来什么样的开销,因为这将取决于MySQL服务器和超时。也许一个更好的架构是使用memcached缓存这些报告,或者只需要解决从服务器出现的问题,并首先在设置中更新数据库定义。

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26608906

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档