扩展MySQL解决scheme(复制,集群)

在我开始工作的时候,我们正在考虑为我们的数据库扩展解决scheme。 事情有点令人困惑(至less对我来说),MySQL具有MySQL集群 , 复制和MySQL集群复制 (从版本5.1.6开始),它是MySQL集群的asynchronous版本。 MySQL手册解释了其集群FAQ中的一些差异,但很难确定何时使用其中的一个或另一个。

对于那些熟悉这些解决scheme之间的差异的人们的build议,以及什么是利弊,以及您何时build议使用这些解决scheme,我将不胜感激。

我已经在可用选项上做了很多的阅读。 我也强烈推荐高性能MySQL第二版。

这是我设法拼凑起来的:

聚类

一般意义上的集群是将作为外部应用程序出现的许多服务器的负载分配为一台服务器。

MySQL NDB集群

MySQL NDB集群是一个分布式,内存中,无共享的存储引擎,具有同步复制和自动数据分区function(对不起,我从高性能书中借用,但是它们在那里非常好)。 对于某些应用程序来说,它可能是一个高性能的解决scheme,但是Web应用程序通常不能很好地工作。

主要的问题是,除了非常简单的查询(只接触一个表)之外,集群通常必须在多个节点上search数据,从而使networking延迟变慢并显着减慢查询的完成时间。 由于应用程序将集群视为一台计算机,因此无法告诉它要从哪个节点获取数据。

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

继续红杉

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

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

联邦

联邦类似于集群,所以我也在这里拉扯它。 MySQL通过联邦存储引擎提供联邦。 类似于NDB集群解决scheme,它只适用于简单的查询 – 但是对于复杂集群来说更是如此(因为networking延迟要高得多)。

复制和负载平衡

MySQL具有在不同服务器上创build数据库复制的内置function。 这可以用于许多事情 – 拆分服务器之间的负载,热备份,创buildtesting服务器和故障转移。

复制的基本设置涉及一个主服务器主要处理写操作,一个或多个从服务器处理只读操作。 更高级的变化是主 – 主configuration,允许通过同时写入多个服务器来扩展写入。

每种configuration都有其优点和缺点,但是他们共享的一个问题是复制滞后 – 因为MySQL复制是asynchronous的,所以并不是所有节点都有最新的数据。 这要求应用程序知道复制,并包含复制感知查询以按预期方式工作。 对于某些应用程序来说,这可能不成问题,但如果你总是需要最新的数据,那么事情会变得复杂一些。

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

分片和分配

分片是常用的方法来扩展数据库解决scheme。 将数据拆分成更小的碎片,并将其分散到不同的服务器节点中。 这就要求应用程序知道对数据存储的修改是否有效地工作,因为它需要知道在哪里find所需的信息。

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

其他

狮身人面像

狮身人面像是一个全文search引擎,可以远远超过testingsearch。 对于许多查询来说,它比MySQL更快(特别是对于分组和sorting),并且可以并行地查询远程系统并汇总结果 – 这使得在使用分片时非常有用。

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

概要

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

我也要给Continuent Sequoia一个镜头,看看它能否真正做到它所承诺的,因为它将涉及对应用程序代码的最less量的更改。

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

MySQL Cluster是一个HA(高可用性)解决scheme。 速度很快,因为它全部在内存中,但它的真正卖点在于可用性。 没有单一的失败点。 另一方面,使用复制时,如果主站closures,则必须切换到副本,并且可能会有less量停机时间。 (尽pipeDRBD解决scheme是具有高可用性的另一种替代scheme)

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

我认为,除非医pipe局是非常重要的(可能不是),否则它的价值(和金钱)比它更有价值。 复制通常是更好的方法。

编辑:我忘了还提到,群集不允许外键,范围扫描比其他引擎慢。 这里是一个链接,介绍MySQL簇的已知限制

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

  • Dries Buytaert的博客
  • WorkHabits博客

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

做复制很酷的事情是,这很容易。 只需要设置2个mysql盒子,在第二个盒子上改变serverID,然后在第一个盒子上使用change master来命令。

这里是相关的示例从属my.cnfconfiguration

# # 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)

设置从机可以连接的用户名和密码,然后运行更改主机到MASTER_HOST ='xxxx'; 将主人更改为MASTER_PASSWORD =“xxxxx”;

等等。

最后,运行“开始奴隶”

起来你的奴隶,并开始复制。 甜心吧!

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

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

显示从站状态\ G

玩得开心。soooo easy …

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

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

在进行高可用性研究时,我遇到了很多解决scheme,可能在我们的情况下,这是写密集型系统,我发现DRBD集群比NDB集群更好,因为它提供了更多的每秒事务数量。

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

通过DRBD提供的不同交易pipe理模式,您可以减less通过networking进行设备级数据复制的性能。 对于失败时使用C模式不会丢失任何事务的可靠系统,否则转到B.

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

它在复制的专用连接上运行得非常好,即为了drbd复制而在两台机器上保留独立的高速接口。 心跳可以很好地控制集群,所有的服务,即IP地址,分区,drbd和MySQL。

我还没有发现DRBD上的Master-Masterconfiguration。 将更新,当我成功在那。

谢谢。

在我看来,这里的困惑只是把我送回了Mnesia。 具有碎片化,声明式和实用的索引处理方式,数据库副本的位置透明等

在我们的设置中,我们运行MySQL Cluster和Mnesia。 我们的数据有点季节性。 所以发生什么事情是在一段时间后,我们释放了不再使用的数据,并把它扔到MYSQL集群中。 这使我们的mnesia高效。 另外,我们还有使用直接从MySQL使用数据的主stream语言(Python,Clojure等)实现的应用程序。

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

数据访问层已经抽象地访问Mnesia中的数据,以及MySQL Cluster中的旧发布数据(如果需要的话)。 Mnesia在这里主要是为Erlang / OTP应用程序提供支持。一旦它被数据占据,我们就把它扔到MYSQL集群中。 数据访问层可以代表所有应用程序在抽象API中访问mnesia和MySQL中的数据。

我可以在这里说的是,Mnesia一直是我们最好的select。 这些表高度分散和索引,查询执行得非常好,数据库跨2个位置复制,通过隧道连接。

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

我们已经从Erlang的复杂数据结构中受益,而且Mnesia可以不变地吞噬它。 Erlang / OTP应用程序在遗留语言中的所有其他应用程序中效率最高,我们计划将其全部迁移到Erlang / OTP技术。 从Erlang我们无缝地访问MySQL Cluster中的数据,并且非常奇妙地在它的服务器上执行查询。事实上,我们推断出它的Erlang / OTP可以充分利用MySQL服务器资源,因为它的(Erlang)大规模并发性。

Mnesia已经为我们工作得非常好。由于其惊人的性能,Mnesia完全改变了我们对数据库的看法。 我们的Solaris服务器CPU内核在繁忙时间平均保持在48%左右的繁忙状态。

我build议你检查mnesia,谁知道,它可能会回答您的分发或复制需求。

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

MySQL集群是一个奇怪的怪物,每次我们评估它或者performance非常糟糕,或者是不可靠的。

设置起来非常复杂(至less需要三个节点,可能更多)。 也没有规定让客户端故障,所以你必须自己做(或使用别的东西作为代理等)。

这是非常聪明的,因为它在主键上进行自动散列分区,允许您扩展写入,也因为它没有单点故障。

但是我真的认为它更适合于它所devise的特殊用途的情况。 在大多数情况下,无论是性能还是特性,都不能replace另一个数据库引擎(如InnoDB)。