85

在我工作的初创公司,我们现在正在考虑为我们的数据库扩展解决方案。事情变得有点混乱(至少对我来说)MySQL,它有MySQL 集群复制MySQL 集群复制(从版本 5.1.6 开始),这是 MySQL 集群的异步版本。MySQL 手册在其集群常见问题解答中解释了一些差异,但很难从中确定何时使用其中一种。

如果熟悉这些解决方案之间的差异以及利弊,以及您何时建议使用每种解决方案,我将不胜感激。

4

9 回答 9

104

我一直在阅读有关可用选项的大量内容。我还获得了我强烈推荐的高性能 MySQL 第 2 版。

这是我设法拼凑起来的:

聚类

一般意义上的集群是在许多服务器上分配负载,这些服务器在外部应用程序中表现为一台服务器。

MySQL NDB 集群

MySQL NDB Cluster 是一个分布式的、内存中的、无共享的存储引擎,具有同步复制和自动数据分区(对不起,我从《高性能》一书中借用了字面意思,但他们把它放在那里很好)。对于某些应用程序来说,它可能是一个高性能的解决方案,但 Web 应用程序通常不能很好地在它上面运行。

主要问题是,除了非常简单的查询(仅涉及一张表)之外,集群通常必须在多个节点上搜索数据,从而导致网络延迟蔓延并显着减慢查询的完成时间。由于应用程序将集群视为一台计算机,它无法告诉它从哪个节点获取数据。

此外,对于许多大型数据库来说,内存中的要求是不可行的。

连续红杉

这是 MySQL 的另一个集群解决方案,它充当 MySQL 服务器之上的中间件。它提供同步复制、负载平衡和故障转移。它还确保请求始终从最新副本中获取数据,自动选择具有新数据的节点。

我已经阅读了一些关于它的好东西,总的来说它听起来很有希望。

联邦

联邦类似于集群,所以我也把它拖到这里。MySQL 通过联合存储引擎提供联合。与 NDB 集群解决方案类似,它仅适用于简单查询 - 但对于复杂查询的集群更糟糕(因为网络延迟要高得多)。

复制和负载平衡

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

复制的基本设置包括一台主服务器处理主要是写入,而一台或多台从服务器只处理读取。一个更高级的变体是master-master配置,它允许通过同时写入多个服务器来扩展写入。

每种配置都有其优点和缺点,但它们都有一个共同的问题是复制滞后——由于 MySQL 复制是异步的,并非所有节点都始终拥有最新的数据。这要求应用程序知道复制并结合复制感知查询以按预期工作。对于某些应用程序,这可能不是问题,但如果您总是需要最新的数据,事情就会变得有些复杂。

复制需要一些负载平衡来分配节点之间的负载。这可以像对应用程序代码的一些修改一样简单,或者使用专用的软件和硬件解决方案。

分片和分区

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

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

其他

狮身人面像

Sphinx是一个全文搜索引擎,它不仅可以用于测试搜索。对于许多查询,它比 MySQL 快得多(尤其是对于分组和排序),并且可以并行查询远程系统并聚合结果——这使得它在使用分片时非常有用。

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

概括

扩展解决方案根据需要它的应用程序的需求而有所不同。对于我们和大多数 Web 应用程序,我相信复制(可能是多主机)是使用负载均衡器分配负载的方式。特定问题区域(巨大的表)的分片也是能够水平扩展的必要条件。

我还将试一试Continuent Sequoia,看看它是否真的能做到它所承诺的,因为它将涉及对应用程序代码的最少更改。

于 2008-10-12T05:23:19.140 回答
12

免责声明:我没有使用过 MySQL Cluster,所以我只是根据我所听到的。

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

集群要求您的整个数据库适合内存。这意味着集群中的每台机器都需要有足够的内存来存储整个数据库。所以这对于非常大的数据库来说不是一个可行的解决方案(或者至少它是一个非常昂贵的解决方案)。

我认为除非 HA 非常重要(阅读:可能不是),否则它比它的价值更麻烦(和金钱)。复制通常是更好的方法。

编辑:我也忘了提到集群不允许外键,并且范围扫描比其他引擎慢。这是一个关于MySQL 集群的已知限制的链接

于 2008-10-10T04:03:00.283 回答
4

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

两者都是从 2007 年开始的,所以现在集群支持可能更强,但当时他们选择了复制。

于 2008-10-10T03:54:14.793 回答
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

因此,请确保每个从站都获得一个加 1 的 serverID(因此下一个从站是服务器 3)

设置slave可以连接的用户名和密码,然后运行change master to MASTER_HOST = 'xxxx'; 将 master 更改为 MASTER_PASSWORD = "xxxxx";

等等。

最后,运行“start slave;”

你的奴隶出现并开始复制。甜啊!

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

您可以通过运行检查从站状态:

显示从属状态 \G

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

于 2008-10-21T18:04:01.270 回答
1

在进行高可用性研究时,我遇到了许多解决方案,在我们的案例中可能是写入密集型系统,我发现 DRBD 集群比 NDB 集群更好,因为它每秒提供更多的事务数。

Mysql Replication 可以为您提供一个备份机器,它既可以用作读取从机,也可以用于灾难恢复。

通过 DRBD 提供的不同事务管理模式,您可以降低网络上设备级数据复制对性能的影响。对于在失败的情况下不应该丢失任何事务的可靠系统,使用 C 模式,否则使用 B。

我试图在http://www.techiegyan.com/?p=132上列出我在设置 DRBD 集群期间所做的一些学习

它在用于复制的专用连接上非常有效,即在两台机器上保留单独的高速接口仅用于 drbd 复制。Heartbeat 可以很好的控制集群的所有服务,IP 地址、分区、drbd 和mysql。

我还没有发现 DRBD 上的 Master-Master 配置。当我在这方面取得成功时会更新。

谢谢。

于 2010-01-27T17:34:57.100 回答
1

在我看来,这里的混乱只会让我回到 Mnesia。具有碎片化、声明式和实用的索引处理方式、数据库副本的位置透明性等

在我们的设置中,我们同时运行 MySQL Cluster 和 Mnesia。我们的数据有点季节性。所以会发生什么,在某个时间之后,我们解除不再使用的数据的记忆错误并将其放入 MYSQL 集群中。这使我们的记忆保持高效。此外,我们还有使用直接来自 MySQL 的数据的主流语言(Python、Clojure 等)实现的应用程序。

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

如果需要,数据访问层已经抽象了对 Mnesia 中的数据和 MySQL Cluster 中的旧数据的访问。Mnesia 本质上是为 Erlang/OTP 应用程序提供动力。一旦它被数据占用,我们将其放入 MYSQL 集群中。数据访问层可以代表所有应用程序以抽象的 API 访问 mnesia 和 MySQL 中的数据。

我在这里可以说的是,Mnesia 一直是我们的最佳选择。这些表是高度碎片化和索引的,查询执行得非常好,并且数据库在 2 个位置复制,通过隧道连接。

早些时候,我们担心由于表大小的限制,mnesia 可能无法处理尽可能多的记录。但我们发现这个说法是错误的。通过良好的调整(碎片化),我们的 mnesia 数据库确实每年平均保存约 2.5 亿条记录。

我们受益于 Erlang 复杂的数据结构以及 Mnesia 可以原封不动地吞并它的事实。Erlang /OTP 应用程序是传统语言中所有其他应用程序中效率最高的,我们计划通过我们的系统将其全部迁移到 Erlang/OTP 技术。从Erlang我们可以无缝地访问MySQL Cluster的数据,并非常奇妙地在其服务器上执行查询,事实上,我们推断出它的Erlang/OTP可以充分利用MySQL服务器资源,因为它的(Erlang)海量并发。

Mnesia 非常适合我们。Mnesia 因其令人兴奋的性能而彻底改变了我们看待数据库的方式。我们的 Solaris 服务器 CPU 内核在高峰时段保持繁忙,平均使用率约为 48%。

我建议您查看 mnesia,谁知道呢,它可能会满足您的许多分发或复制需求。

于 2011-05-03T16:43:04.263 回答
0

我没有使用它们,但是从文档中我会说如果最大的负载是从数据库中读取,那么复制是首选的解决方案。

于 2008-10-10T03:25:23.090 回答
0

“内存中”的限制使我们无法使用 MySQL 集群来处理近 50Gb 的数据,因此我们使用DRBD 和 linux Heartbeat

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

于 2008-10-10T04:21:27.547 回答
0

MySQL 集群是一个奇怪的野兽,每次我们评估它时,要么性能很差,要么不可靠。

设置起来非常复杂(您至少需要三个节点,可能更多)。此外,没有规定让客户端进行故障转移,因此您必须自己做(或使用其他东西充当代理等)。

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

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

于 2009-08-21T21:51:07.297 回答