我有Django的MySQL数据库后端的主 - 从复制设置 . 目前我只为Master DB阅读和写作,但我的仪表板非常查询 . 我正在寻找一个选项,我可以在其中定义如下DATABASES
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_slave
也就是说,如果slave已启动,则从slave数据库本身获取报告,如果没有从master数据库获取报告 .
Catch是,slave可以是up或down,我希望根据可重现性动态选择关于哪个数据库用于获取报告 .
这可能吗 ?我可以手动测试连接并继续前进吗?
有了这个,我会在Master中写和sync_db,并且如果slave已启动,它总是从Slave读取 .
需要一些解决方案/提示 raw queries
以及 orm queries
路由器的概念看起来不错,但是奴隶的后备不可达,我不知道这种可能性 .
UPDATE
如何进行MULTI-DATABASE
DATABASES
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'中,并将其复制到'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
:连接已启动:使用:<'query_on'>_slave
或 -
如果
<'query_on'>_slave
:连接已关闭:使用:<'query_on'>
怎么去那?
Further details for the application:
-
有一个数据库:默认(配置和分析数据库):用于维护配置数据和报告分析数据
-
有20个数据库(原始数据库):例如说:mac,linux,rhel,windows,pc ....(示例名称):用于收集原始数据,这不是分析流程
-
每个数据库都有一个或多个从属,命名约定为:default_slave_0,default_slave_1,default_slave_2等等,对于其他数据库也是如此
现在,需要首先每5分钟,30分钟,1小时查询分析数据....并且该查询需要发送到特定数据库,因为并非每个数据库都将携带分析所需的特定数据集 .
要做到这一点,我们需要
-
从中获取配置数据(默认或其任何一个从属(从属部分是问题))
-
一旦我们有了配置,我们就可以轻松查看"raw"数据的位置
-
查询原始数据,并收集结果并进行分析 - >将其存储在"default"数据库中 .
现在所有30个(原始)和1个默认数据库都需要“同步”,因为我们在所有节点中保持相同的数据abse结构 .
现在,由于我们正在查看所有数据库上的CPU峰值,因此使用“slave”数据库查询“原始”数据是有意义的 .
因此需要 using
. 我无法想象路由器在这里会有什么帮助?
1 回答
使用路由器,你在正确的轨道上 . 我假设您的两个数据库定义相同只是一个错字 .
(仅供参考,我将使用the more sensitive master->follower引用数据库层次结构)
在db_for_read()函数中,您可以检查与关注者的连接 . 这可能会产生更多的开销,但这是为数据库进行自动故障转移的成本 . 一个示例数据库定义是:
您可以通过快速尝试/例如this example来测试连接 . 使用它的路由器可以满足您的需求:
这仍然会像你想要的那样在master中同步 . 此外,您可以使
db_for_read()
和db_for_write()
的逻辑更复杂(例如,仅为查询报告的某些模型选择跟随者数据库 .我不知道
test_connection()
会为每次读取带来什么开销,因为这将取决于MySQL服务器和超时 . 也许更好的架构是使用memcached缓存这些报告,或者只是解决奴隶问题,并首先在设置中更新数据库定义 .