我为Django设置了MySQL数据库后端的主从复制。 目前,我仅对主数据库进行读写,但我的仪表板需要进行相当多的查询。 我正在寻找一个选项,可以像下面这样定义: 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
,否则使用default
也就是说,如果从数据库启动,则从从数据库本身获取报告,否则从主数据库获取报告。
关键是,从数据库可能正常或异常,并且我希望基于可达性动态选择要使用哪个数据库来获取报告。
这可能吗?我能事先测试连接然后继续吗?
有了这个,我会在主库中编写和同步数据库,并始终从从库中读取(如果从库处于启动状态)。
需要一些原始查询
和ORM查询
的解决方案/提示
路由器的概念似乎不错,但是无法回退到无法访问从库,我不知道是否可能。
更新
如何处理多个数据库
数据库
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',
},
}
现在我有以下两种数据:
- 静态数据
- 动态数据
静态数据必须存储在“default”中,然后会被复制到“default_slave”中。
对于动态数据,查询首先需要确定它可能位于哪里:在“mac”、“pc”或“linux”中。
为此,我在“static table”中添加了一个字段:“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'>
如何处理呢?
应用程序的进一步细节如下:
- 有一个数据库:默认(配置和分析数据库):用于维护配置数据和报告分析数据
- 有20个数据库(原始数据库):例如mac,linux,rhel,windows,pc(示例名称):用于收集未经过分析的原始数据
- 每个数据库都有一个或多个从属节点,命名约定为:default_slave_0,default_slave_1,default_slave_2等
现在需要每5分钟、30分钟、1小时查询一次分析数据,并将查询发送到特定的数据库,因为不是每个数据库都将包含所需的特定数据集。
为了实现这一点,我们需要:
- 从默认(或任何一个从属节点)获取配置数据
- 一旦获取了配置信息,就可以轻松查找“原始”数据可能位于哪里
- 查询原始数据,收集结果并进行分析 --> 存储在“default”数据库中。
现在所有30个(原始)和1个默认数据库都需要同步,因为我们在所有节点上维护相同的数据结构。
现在,在所有数据库上查看CPU峰值是有意义的,因此使用“从属”数据库查询“原始”数据是有帮助的。因此需要使用using
。在这里,我无法想象路由器如何有所帮助?
.using(alias = defualt_slave)
如果连接成功,很好,如果不行,就用using= default
(与 _slave 分开)。这将是一个快速的解决方案。 - Joddyget_queryset
和using
调用时对服务器进行 ping 测试,是吗? - Alexander Klimenko