我已经为Django的MySQL db后端设置了主从复制设置。目前,我只为主数据库读写,但我的仪表板是相当密集的查询。我在寻找一个选项,在其中我可以定义如下数据库
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 queries和orm queries的解决方案/提示
路由器的概念看上去不错,但我不知道是否有可能在从上掉头。
更新
如何进行多数据库
数据库
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)
这很好,查询路由到它需要执行的数据库,这里我需要判断:
<'query_on'>_slave:connection已启动:使用:<'query_on'>_slave或<'query_on'>_slave:connection关闭:使用:<'query_on'>怎么做呢?
应用程序的详细信息:
现在需要每5分钟、30分钟、1小时先查询分析数据.这个查询需要发送到特定的数据库,因为并不是每个数据库都包含分析所需的特定数据集。
要做到这一点,我们需要
现在,所有的30 (raw)和1个默认数据库都需要“同步”,因为我们在所有节点中都维护相同的数据abse结构。
现在,由于我们正在查看所有数据库上的CPU峰值,所以使用“从”数据库查询“原始”数据是有意义的。
因此,提出了using的要求。我无法想象路由器在这里会有什么帮助?
发布于 2014-11-13 18:48:55
你在正确的轨道上使用路由器。我假设您的两个db定义是相同的,这只是一个错误。
(FYI,我将使用the more sensitive master->follower引用数据库层次结构)
在您的db_for_read()函数中,您可以检查与您的追随者的连接性。这可能会带来更多的开销,但这是数据库自动故障转移的成本。数据库定义的一个例子是:
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这样的方法来测试连接。使用它的路由器可以满足您的需要:
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缓存这些报告,或者只需要解决从服务器出现的问题,并首先在设置中更新数据库定义。
https://stackoverflow.com/questions/26608906
复制相似问题