MySQL的扩展解决方案 (复制、集群)

86
在我工作的初创公司中,我们现在考虑为我们的数据库提供扩展解决方案。对于MySQL来说,事情有些令人困惑(至少对我来说),它有MySQL集群, 复制MySQL集群复制(从版本5.1.6开始),这是MySQL集群的异步版本。 MySQL手册在其集群FAQ中解释了一些差异,但很难确定何时使用其中的一个或另一个。
我将感激熟悉这些解决方案之间差异以及其优缺点的人的任何建议,并指导何时推荐使用每个解决方案。

4
2015年同样的问题的答案是什么? - Matical
你好,关于编程方面,如果我是为我的基于PHP的应用程序进行编程,是否有特定的事项需要注意?或者无所谓? - Salil Momin
在2017年,可以看看MariaDB、Galera和MariaDB MaxScale。 - MattBianco
9个回答

106
我已经阅读了很多关于可用选项的内容。我也拿到了《高性能MySQL第二版》的手,强烈推荐。
这是我整理出来的内容:

集群

一般来讲,集群是将负载分布在许多服务器上,对外表现为一个服务器。

MySQL NDB Cluster

MySQL NDB Cluster是一个分布式、内存中、共享无存储引擎,具有同步复制和自动数据分区(借用《高性能》书中的说法)。它可以成为某些应用程序的高性能解决方案,但 web 应用程序通常不适用于它。
主要问题是,在超出非常简单的查询(仅涉及一个表)之后,群集通常必须在多个节点上搜索数据,从而允许网络延迟渗入并显着减缓查询完成时间。由于应用程序将群集视为一台计算机,因此它无法告诉它从哪个节点获取数据。
此外,对于许多大型数据库来说,内存需求是不可行的。

Continuent Sequoia

这是另一种针对MySQL的集群解决方案,作为MySQL服务器顶部的中间件。它提供同步复制、负载平衡和故障转移。它还确保请求始终从最新的副本获取数据,自动选择具有新鲜数据的节点。
我阅读了一些好的内容,总体而言,它听起来非常有前途。

联合

联邦与群集类似,因此我也在这里提到它。MySQL通过联合存储引擎提供联邦功能。类似于NDB群集解决方案,它仅适用于简单查询——但对于复杂查询而言比群集更糟糕(因为网络延迟更高)。

复制和负载均衡

MySQL具有在不同服务器上创建数据库副本的内置能力。这可用于许多事情——在服务器之间分担负载、热备份、创建测试服务器和故障转移。

复制的基本设置涉及一个主服务器处理大部分写入操作,一个或多个从服务器仅处理读取操作。更先进的变体是主-主配置,允许同时有几个服务器进行写入,从而扩展写入。

每种配置都有其优缺点,但它们共享的一个问题是复制延迟——由于MySQL复制是异步的,因此并非所有节点始终具有最新数据。这要求应用程序意识到复制并合并具有复制感知的查询以正常工作。对于某些应用程序,这可能不是一个问题,但如果您总是需要最新的数据,则事情会变得相当复杂。

复制需要一些负载均衡来分担节点之间的负载。这可以简单地修改应用程序代码,也可以使用专用软件和硬件解决方案。

分片和分区

分片是一种常用的扩展数据库解决方案的方法。您将数据拆分为较小的片段并将其分布在不同的服务器节点上。这要求应用程序意识到数据存储的修改以有效地工作,因为它需要知道在哪里查找所需信息。

现有抽象框架可用于帮助处理数据分片,例如Hibernate Shards,它是Hibernate ORM的扩展(不幸的是,它是Java的。我使用PHP)。HiveDB是另一种解决方案,它还支持分片重新平衡。

其他

Sphinx

Sphinx是一个全文搜索引擎,可以用于远比测试搜索更多的内容。对于许多查询,它比MySQL快得多(特别是对于分组和排序),可以并行查询远程系统并聚合结果 - 这使得它在与分片一起使用时非常有用。

通常情况下,应该将sphinx与其他扩展解决方案一起使用,以获得更多的可用硬件和基础设施。缺点是,您需要让应用程序代码了解sphinx才能明智地使用它。

总结

扩展解决方案因所需应用程序而异。对于我们和大多数Web应用程序来说,我认为复制(可能是多主)是通过负载均衡器分配负载的方法。针对特定问题区域(巨大表格)进行分片也是水平扩展的必要条件。

我还将尝试Continuent Sequoia,看看它是否能够实现承诺,因为它将涉及对应用程序代码的最小更改。


4
主-主复制不允许您扩展写入 - 两个主服务器都必须执行所有写操作以保持同步。此外,同时向两个服务器写入很可能(更或多或少保证)会创建复制冲突,MySQL 不会自动解决这些冲突。 - MarkR
1
注意到这个回复是在08年写的,现在已经过去了1年半了,你对Continuent Sequoia有什么结果? - Kerry Jones
1
能否分享一下使用Continuent Sequoia的结果/经验? - conandor
最终我没有使用Continuent Sequoia,而是设法持续扩展MySQL以适应我们的需求。 - Eran Galperin
Continuent Sequoia已经停止开发并被Continuent Tungsten所取代,后者是一系列免费产品的集合。请访问http://www.continuent.com/community/tungsten-overview。 - lo_fye

12

免责声明:本人未使用过MySQL Cluster,所以我只是根据听到的谈一下。

MySQL Cluster是一种高可用性(HA)解决方案。它很快,因为它全部在内存中,但它真正的卖点是可用性。没有单点故障。另一方面,使用复制,如果主服务器出现故障,则必须实际切换到副本,并且可能会有一小段时间的停机时间。(虽然 DRBD 解决方案是具有高可用性的另一种选择)

集群需要整个数据库都放在内存中。这意味着集群中的每台机器都需要足够的内存来存储整个数据库。因此,这对于非常大的数据库来说不是一个可行的解决方案(或者至少是一个非常昂贵的解决方案)。

我认为除非HA 非常重要(即基本不是),否则更多的麻烦(和金钱)不值得。 复制通常是更好的选择。

编辑: 我忘记还有一点,Cluster不允许外键,并且范围扫描比其他引擎慢。 这里是一个链接,介绍了 MySQL Cluster的已知限制


我想表达的意思是,如果你担心性能问题,那就选择复制。只有在高可用性是首要考虑因素时才选择集群。我不知道它们之间的比较情况,而且硬件要求也非常不同,可能根本无法进行比较。 - nathan
这是4-5年后的事了,但我想补充一下,MySQL Cluster现在不再需要将整个数据库保留在内存/RAM中:“从MySQL 5.1开始,数据不再需要完全存储在内存中。” http://dba.stackexchange.com/questions/9357/mysql-cluster-ram-requirement - Ted

4

关于维护drupal.org的人如何构建他们的数据库服务器,有一些很好的讨论:

这两篇文章都是来自2007年,因此现在可能对集群支持更强大,但当时他们选择了复制。


2

做复制的好处在于它很容易。只需要设置2个mysql盒子,更改第二个盒子上的serverID,然后使用change master to命令将第二个盒子指向第一个盒子即可。

以下是相关的从库my.cnf配置示例:

#
#       Log names
#

log-bin=binlog
relay-log=relaylog
log-error=errors.log

#
#       Log tuning
#

sync_binlog = 1
binlog_cache_size = 1M

#
#       Replication rules (what are we interested in listening for...)
#
#       In our replicants, we are interested in ANYTHING that isn't a permission table thing
#

replicate-ignore-db =      mysql
replicate-wild-ignore-table=mysql.%

#
#       Replication server ID
#

server-id      =        2

确保每个从服务器的serverID都增加了1(下一个从服务器是服务器3)。

设置一个用户名和密码,让从服务器可以连接,然后运行:

change master to MASTER_HOST = 'x.x.x.x'; change master to MASTER_PASSWORD = "xxxxx";

以此类推。最后,运行“start slave;”

你的从服务器就启动并开始复制了。不错吧!

这假设你从两个空服务器开始。然后你可以将数据库转储到主服务器上,在主服务器加载时,它也会加载到从服务器上。

你可以通过运行以下命令来检查从服务器的状态:

show slave status \G

玩得开心...太容易了...


1

在我看来,这里的混淆只会让我回到Mnesia。通过分片、处理索引的声明性和实用性方式、数据库副本的位置透明等等,我们可以使Mnesia更加高效。

在我们的设置中,我们同时运行MySQL Cluster和Mnesia。我们的数据有点季节性。所以经过一段时间后,我们会将不再使用的数据从Mnesia中移除并将其放入MYSQL Cluster中。这样可以保持我们的Mnesia高效。此外,我们还有使用主流语言(如Python、Clojure等)编写的应用程序,直接从MySQL中获取数据。

简而言之,我们在MySQL Cluster上运行Mnesia。MySQL Cluster可以处理大型数据集,一个数据库可以增长到50GB以上。我们使用Mnesia为Erlang/OTP应用程序提供支持。Java和PHP通过定制的REST(最近是Thrift)API使用JSON和XML作为交换格式从Mnesia中访问数据。

数据访问层已经将对Mnesia和旧版MySQL Cluster的数据访问进行了抽象处理,如果需要的话。Mnesia主要用于支持Erlang/OTP应用程序。一旦它被大量数据占用,我们就将其转移到MYSQL Cluster中。数据访问层可以代表所有应用程序访问Mnesia和MySQL中的数据。

我可以说的是,Mnesia对我们来说是最好的选择。表高度分片和索引,查询性能非常好,并且数据库在通过隧道连接的2个位置上进行复制。

早些时候,我们担心由于表大小限制,Mnesia可能无法处理尽可能多的记录。但我们发现这种说法是错误的。通过良好的调整(分片),我们的Mnesia数据库每年可以容纳约2.5亿条记录。

我们从Erlang的复杂数据结构中受益,而且Mnesia可以不加修改地接受它。与其他遗留语言的应用程序相比,Erlang/OTP应用程序最为高效。我们计划将所有系统迁移到Erlang/OTP技术。从Erlang中,我们可以轻松地访问MySQL Cluster中的数据,并在其服务器上执行查询,事实上,我们得出结论:正是由于Erlang的大规模并发性,才能充分利用MySQL服务器资源。

Mnesia在我们的项目中表现非常出色。由于其惊人的性能,Mnesia已经彻底改变了我们看待数据库的方式。在高峰时段,我们的Solaris服务器CPU核心的平均使用率约为48%。

我建议您尝试一下Mnesia,说不定它可以满足您的分发或复制需求。


1
在进行高可用性研究时,我发现了许多解决方案,而对于我们更注重写入的系统来说,我发现 DRBD 群集比 NDB 群集更好,因为它提供了更多的每秒事务数。
Mysql 复制可以提供一个备份机器,该备份机器可以用作读取从服务器或在灾难恢复时使用。
通过 DRBD 提供的不同的事务管理模式,您可以在设备级别数据复制过程中在某种程度上降低性能损失。对于不应在故障情况下丢失任何事务的可靠系统,请使用 C 模式,否则选择 B 模式。
我尝试列出一些在设置 DRBD 群集时所学到的经验,在http://www.techiegyan.com/?p=132 上可以找到。
在专用连接上进行复制(即在两台计算机上分别保留高速接口以进行 DRBD 复制)效果非常好。心跳可以控制群集得心应手,包括 IP 地址、分区、DRBD 和 mysql。
我仍然需要发现 DRBD 的主-主配置。如有成功后,将进行更新。
谢谢。

0

MySQL集群是一个奇怪的生物,每次我们评估它时,要么表现非常糟糕,要么不可靠。

它的设置非常复杂(至少需要三个节点,可能需要更多)。此外,它没有提供客户端故障转移的功能,因此您必须自己处理(或使用其他代理等作为代理)。

它非常聪明,因为它对主键进行自动哈希分区,从而允许您扩展写入,并且因为它没有单点故障。

但我真的认为它更适合设计用于非常特殊的用途。在大多数情况下,它不能替换另一个数据库引擎(例如InnoDB)的性能或功能。


Several Nines提供了一种解决方案,使设置变得更加容易:http://support.severalnines.com/entries/20916823-installing-on-amazon-ec2 ...但是我同意,在我的公司中正在评估MySQL Cluster,它非常适合分散写入,但读取速度要慢得多,并且没有外键支持等。 - Suman
外键支持自v7.3版本开始提供(http://dev.mysql.com/doc/relnotes/mysql-cluster/7.3/en/mysql-cluster-news-5-6-10-ndb-7-3-1.html)。这里有一个很好的比较[InnoDB vs NDB](https://dev.mysql.com/doc/refman/5.6/en/mysql-cluster-ndb-innodb-engines.html)。 - lennartvdd

0

我没有使用过它们,但从文档中可以看出,如果最大的负载来自于数据库的读取,那么复制是首选的解决方案。


1
你是怎么得出这个结论的呢?如果你能具体说明一下就更好了。此外,文档似乎表明聚类更可靠。 - Eran Galperin

0

“内存”限制阻止我们将MySQL集群用于近50GB的数据,因此我们使用DRBD加Linux Heartbeat

这有点像在两个(或更多)盒子之间保持数据库/日志/配置同步的RAID阵列(但仅一个服务器可以处于“活动”状态)。故障转移是自动的,使用相同的IP地址,并且像mysql重新启动一样快,因此这对我们来说是一个好解决方案。


1
它是否有助于性能,还是仅用于冗余? - Eran Galperin
DRBD在一切正常的情况下都很好,但是如果出现文件系统故障并损坏了您的表格,那么您将拥有两个节点的故障而不仅仅是一个。我不信任它。 - Jon Topper
+1 @Eric Galperin故障转移/冗余是我访问此问题页面的主要原因,为了寻求在我们公司内部安排每个站点一个mysql服务器的想法。 - therobyouknow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接