gpt4 book ai didi

mysql - 如果 Slave 关闭,Django 多个数据库回退到 Master

转载 作者:IT老高 更新时间:2023-10-29 00:04:18 25 4
gpt4 key购买 nike

我为 Django 的 MySQL 数据库后端设置了主从复制设置。目前我只为 Master 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

也就是说,如果slave启动了,就从slave数据库自己获取reports,如果没有从master数据库获取reports。

Catch 是,slave 可以打开或关闭,我希望它可以根据可重复性动态选择用于获取报告的数据库。

这可能吗?我可以事先测试连接并继续前进吗?

有了这个,我将在 Master 中写入和 sync_db,如果 slave 启动,则始终从 Slave 读取。

需要一些解决方案/提示 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' 中,这将被复制到 '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 :连接已建立:使用:<'query_on'>_slave
  2. 如果 <'query_on'>_slave :连接断开:使用:<'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 个(原始)和 1 个默认数据库都需要“同步”,因为我们在所有节点中都保持相同的数据结构。

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

因此需要 using .我无法想象路由器在这里会有什么帮助?

最佳答案

您在使用路由器方面走在正确的轨道上。我假设您的两个数据库定义相同只是一个拼写错误。

(仅供引用,我将使用 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',
},
}

您可以通过快速尝试/异常(exception)来测试连接,例如 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'

这仍然会像你想要的那样在 master 中同步数据库。此外,您可以使 db_for_read()db_for_write() 的逻辑更复杂(例如仅为为您的报告查询的某些模型选择关注者数据库。

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

关于mysql - 如果 Slave 关闭,Django 多个数据库回退到 Master,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26608906/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com