如何在 3 个或更多地理位置分散的服务器之间集中 MySQL 数据?

如何在 3 个或更多地理位置分散的服务器之间集中 MySQL 数据?

解释一下这个问题的背景:

我们有一个自主开发的 PHP 应用程序(用于运行在线语言学习课程),运行在 Linux 服务器之上,并在本地主机上使用 MySQL 来保存用户数据(例如,参加测试的结果、提交的作业的分数、在课程的不同页面上花费的时间等)。

由于我们的学生来自不同的地理位置,我们目前在这些地点附近托管了 3 台虚拟服务器(西班牙、英国和香港),并将用户添加到距离他们最近的服务器(他们通过不同的 URL 访问,例如 europe.domain.com、uk.domain.com 和 asia.domain.com)。这很有效,但管理起来很麻烦,因为我们必须记住特定用户在哪个服务器上,并且用户只能连接到一台服务器。我们希望以某种方式集中信息,以便所有用户都可以在任何一台服务器上看到,并且用户可以连接到 3 台服务器中的任何一台。

问题是,我们应该使用什么方法来实现这一点。这肯定是很多人都遇到过的问题,但我在谷歌上搜索了一番后,还是没有找到任何结论。我见过的最接近的解决方案是:

  • 类似于主-主复制的东西,但是我读过很多帖子表明这不是一个好主意,因为像 auto_increment 字段这样的东西可能会被破坏。

  • 循环复制,这听起来很完美,但引用 O'Reilly 的《高性能 MySQL》中的一句话,“一般来说,环很脆弱,最好避免”

我们并不反对重写应用程序中的代码以使其与所需的任何解决方案一起工作,但我不确定复制是否是正确的做法。

谢谢,

安迪

PS我应该补充一点,我们尝试将数据写入中央数据库,然后从本地数据库读取,但不同服务器之间的写入响应时间非常糟糕,而且写入的数据必须立即可供读取,这一点也很重要,所以如果复制太慢,这可能会导致返回过时的数据。

编辑:我一直在考虑编写自己的基本复制脚本,该脚本将涉及为每位用户提供一个服务器 ID 来表明哪个是他的“主服务器”,例如,亚洲的用户将被标记为拥有香港服务器作为自己的服务器。然后,复制脚本(将是一个设置为以 cron 作业的形式合理频繁运行的 PHP 脚本,例如每 15 分钟左右)将在系统中的每个服务器上独立运行。它们将检查数据库,并将有关“主服务器”设置为脚本正在运行的服务器的用户的任何信息分发到系统中的所有其他数据库。它们还需要提取已添加到系统中任何其他数据库中的新信息,其中“主服务器”标志是脚本正在运行的服务器。我需要制定细节并建立处理冲突的逻辑,但我认为这是可能的,但是我想确保没有正确的这个问题已经有了解决方案,因为看起来这肯定是许多人已经遇到过的问题。

答案1

循环复制(在您的情况下,即简单的主/主/主)将起作用。尽管有些人声称这有时会稍微“脆弱”,但任何多服务器设置都是如此。一个像样的监控系统(无论如何都应该是您整体软件包的一部分)将有助于尽早发现任何问题,以便在问题变得严重之前得到解决。

自动递增“问题”很容易被规避,我简直不敢相信人们仍然把它当作一个问题。只需在每台服务器上以不同的数字启动计数器,并使用至少与服务器数量一样大的步长,为将来可能的添加留出足够的空间。

答案2

对于您的应用程序,听起来循环复制(多主复制是一种特殊情况)不应该是一个大问题。

auto_increment 问题可以通过以下方式轻松解决auto_increment_increment自动增量偏移量

以相对较高的频率监控所有实例上的复制,并修复来源任何导致复制中断或数据漂移的因素。 马特吉特的 mk-table-checksum 和 mk-table-sync 适用于识别漂移的数据。必须查看二进制日志和代码才能确定来源... :)

答案3

我们并不反对重写应用程序中的代码以使其与所需的任何解决方案一起工作,但我不确定复制是否是正确的做法。

您所描述的问题实际上听起来像是按需用户转移的案例。

听起来,对于以下情况来说,造成延迟(由于服务器地理位置分散,延迟是不可避免的)似乎是不可接受的:全部用户,因此为您的用户提供“导出配置文件”或“传输”选项,并编写一个根据需要将用户数据从一台服务器推送到下一台服务器的功能。

编辑:...并且在您这样做的同时,也许您可​​以在每个实例的用户名上添加一个后缀,以便用户在请求帮助时可以指示(通过提供他们的用户名)他们的帐户在哪个服务器上注册。

答案4

如果您愿意重新设计数据访问层和数据模型,并且愿意将数据存储在服务器之外的某个地方,那么您可以尝试分布式数据库服务,例如http://aws.amazon.com/simpledb/

相关内容