我一直在阅读有关可用选项的大量信息。我还获得了我强烈推荐的高性能 MySQL 第 2 版。
这是我设法拼凑起来的:
聚类
一般意义上的集群是将负载分布在许多服务器上,这些服务器在外部应用程序中表现为一台服务器。
MySQL NDB 集群
MySQL NDB Cluster 是一个分布式的、内存中的、无共享的存储引擎,具有同步复制和自动数据分区功能(对不起,我从《高性能》一书中借用了字面意思,但他们把它写得很好)。对于某些应用程序来说,它可能是一个高性能的解决方案,但 Web 应用程序通常不能很好地在它上面运行。
主要问题在于,除了非常简单的查询(仅涉及一张表)之外,集群通常还必须在多个节点上搜索数据,从而导致网络延迟蔓延并显着减慢查询的完成时间。由于应用程序将集群视为一台计算机,因此无法告诉它从哪个节点获取数据。
此外,内存要求不适用于许多大型数据库。
连续红杉
这是 MySQL 的另一个集群解决方案,它充当 MySQL 服务器之上的中间件。它提供同步复制、负载平衡和故障转移。它还确保请求始终从最新副本中获取数据,自动选择具有新数据的节点。
我读过一些关于它的good things,总的来说它听起来很有希望。
联邦
Federation 类似于集群,所以我也将它拖到这里。 MySQL 通过联合存储引擎提供联合。与 NDB 集群解决方案类似,它仅适用于简单查询 - 但对于复杂查询的集群更糟糕(因为网络延迟要高得多)。
复制和负载平衡
MySQL 具有在不同服务器上创建数据库复制的内置能力。这可以用于许多事情 - 在服务器之间分配负载、热备份、创建测试服务器和故障转移。
复制的基本设置包括一台主服务器主要处理写入,而一台或多台从服务器仅处理读取。一个更高级的变体是master-master 配置,它允许通过同时写入多个服务器来扩展写入。
每种配置都有其优点和缺点,但它们都有一个共同的问题是复制滞后 - 由于 MySQL 复制是异步的,并非所有节点都始终拥有最新的数据。这要求应用程序知道复制并结合复制感知查询以按预期工作。对于某些应用程序,这可能不是问题,但如果您总是需要最新数据,事情就会变得有些复杂。
复制需要一些负载平衡来在节点之间分配负载。这可以简单到对应用程序代码进行一些修改,或者使用专用的软件和硬件解决方案。
分片和分区
分片是扩展数据库解决方案的常用方法。您将数据拆分为更小的碎片,并将它们分布在不同的服务器节点上。这需要应用程序意识到对数据存储的修改才能有效地工作,因为它需要知道在哪里可以找到所需的信息。
有一些抽象框架可用于帮助处理数据分片,例如 Hibernate Shards,它是 Hibernate ORM 的扩展(不幸的是,它在 Java 中。我正在使用 PHP)。 HiveDB 是另一个这样的解决方案,它也支持分片重新平衡。
其他
狮身人面像
Sphinx 是一个全文搜索引擎,它不仅可以用于测试搜索。对于许多查询,它比 MySQL 快得多(特别是对于分组和排序),并且可以并行查询远程系统并聚合结果 - 这使得它在使用分片时非常有用。
一般而言,sphinx 应与其他扩展解决方案一起使用,以获得更多可用的硬件和基础架构。缺点是您需要应用程序代码再次了解 sphinx 才能明智地使用它。
总结
扩展解决方案根据需要它的应用程序的需求而有所不同。对于我们和大多数 Web 应用程序,我相信复制(可能是多主机)是使用负载均衡器分配负载的方式。对特定问题区域(巨大的表)进行分片也是能够水平扩展的必要条件。
我还将试一试Continuent Sequoia,看看它是否真的能做到它所承诺的,因为它只需要对应用程序代码进行最少的更改。