16.3.4 使用复制进行横向扩展

您可以将复制用作横向扩展解决方案。也就是说,您希望在一些合理的限制内将数据库查询的负载分散到多个数据库服务器上。

由于复制是从一个源分发到一个或多个副本而进行的,因此使用复制进行横向扩展最适用于读取次数很多而写入/更新次数很少的环境。大多数网站都属于此类别,用户可以在其中浏览网站,阅读文章,post或查看产品。更新仅在会话 Management 期间,购买或向论坛添加 Comment/消息时发生。

在这种情况下,复制使您可以在副本上分发读取,同时在需要写入时仍允许 Web 服务器与源进行通信。您可以在图 16.1,“在横向扩展期间使用复制来提高性能”中看到此方案的示例复制布局。

图 16.1 在横向扩展期间使用复制提高性能

来自 Client 端的传入请求被定向到负载平衡器,该负载平衡器在多个 WebClient 端之间分配 Client 端数据。 WebClient 端进行的写操作被定向到单个 MySQL 源服务器,WebClient 端进行的读操作被定向到三个 MySQL 复制服务器之一。从 MySQL 源服务器复制到三个 MySQL 复制服务器。

如果负责数据库访问的代码部分已被正确地抽象/模块化,则将其转换为使用复制的设置运行将非常平滑和容易。更改数据库访问的实现,以将所有写入发送到源,并将读取发送到源或副本。如果您的代码没有这种抽象级别,则设置复制系统将为您提供清除它的机会和动力。首先创建一个实现以下功能的包装器库或模块:

  • safe_writer_connect()

  • safe_reader_connect()

  • safe_reader_statement()

  • safe_writer_statement()

每个函数名称中的safe_table 示该函数负责处理所有错误情况。您可以为函数使用不同的名称。重要的是要有一个用于读取,连接,写入,读取和写入的统一接口。

然后将您的 Client 端代码转换为使用包装器库。起初这可能是一个痛苦而令人恐惧的过程,但从长远来看,它是有回报的。使用上述方法的所有应用程序都可以利用源/副本配置,即使其中一个涉及多个副本。该代码更易于维护,并且添加故障排除选项很简单。您只需要修改一个或两个函数(例如,记录每个语句花费的时间,或者发出的语句中的哪个语句给您一个错误)。

如果您编写了很多代码,则可能要使用标准 MySQL 发行版随附的replaceUtil 来自动化转换任务,或者编写自己的转换脚本。理想情况下,您的代码使用一致的编程样式约定。如果没有,那么您最好还是重写它,或者至少经历一下并手动对其进行规范化以使用一致的样式。