使用 Azure Database for MySQL 构建应用程序的最佳做法

适用于:Azure Database for MySQL - 单一服务器 Azure Database for MySQL - 灵活服务器

重要

Azure Database for MySQL 单一服务器即将停用。 强烈建议升级到 Azure Database for MySQL 灵活服务器。 有关如何迁移到 Azure Database for MySQL 灵活服务器的详细信息,请参阅 Azure Database for MySQL 单一服务器发生了什么情况?

下面是一些可帮助你使用 Azure Database for MySQL 构建云就绪应用程序的最佳做法。 这些最佳做法可以减少应用开发时间。

应用程序和数据库资源的配置

使应用程序和数据库位于同一区域中

在 Azure 中部署应用程序时,请确保所有依赖项都位于同一区域中。 跨区域或可用性区域分布实例会造成网络延迟,这可能会影响应用程序的总体性能。

确保 MySQL 服务器的安全

将 MySQL 服务器配置为安全的不能公开访问的服务器。 使用以下选项之一来保护服务器:

为了安全起见,必须始终通过 SSL 连接到 MySQL 服务器,并将 MySQL 服务器和应用程序配置为使用 TLS 1.2。 了解如何配置 SSL/TLS

通过 AKS 使用高级网络

在 VM 上启用加速网络时,可以降低延迟、降低抖动和降低 VM 上的 CPU 利用率。 若要了解详细信息,请参阅 Azure Kubernetes 服务和 Azure Database for MySQL 的最佳做法

优化服务器参数

对于读取密集型工作负荷优化服务器参数,tmp_table_sizemax_heap_table_size 有助于优化性能。 若要计算这些变量所需的值,请查看每连接内存值总计和基本内存值。 每连接内存参数(不包括 tmp_table_size)的总和与基本内存一起构成了服务器的总内存。

若要计算 tmp_table_sizemax_heap_table_size 的最大可能大小,请使用以下公式:

(total memory - (base memory + (sum of per-connection memory * # of connections)) / # of connections

注意

总内存指的是服务器在预配的 Vcore 中具有的内存总量。 例如,在常规用途的双 vCore Azure Database for MySQL 服务器中,总内存为 5 GB * 2。 可以在定价层文档中找到有关每个层的内存的更多详细信息。

基本内存指的是 MySQL 在服务器启动时将初始化和分配的内存变量,例如 query_cache_sizeinnodb_buffer_pool_size。 每连接内存(例如 sort_buffer_sizejoin_buffer_size)是仅当查询需要时才分配的内存。

创建非管理员用户

为每个数据库创建非管理员用户。 通常,用户名被标识为数据库名称。

重置密码

可以使用 Azure 门户为 MySQL 服务器重置密码

重置生产数据库的服务器密码可能会导致应用程序关闭。 对于任何生产工作负荷,最好是在非高峰时间为其重置密码,将其对应用程序用户的影响降到最低。

性能和复原能力

下面是一些可以帮助调试应用程序性能问题的工具和做法。

启用慢查询日志来查明性能问题

可以在服务器上启用慢查询日志审核日志。 对慢查询日志进行分析有助于查明性能瓶颈以进行故障排除。

还可通过 Azure Monitor 日志、Azure 事件中心和存储帐户中的 Azure 诊断日志获得审核日志。 请参阅如何排查查询性能问题

使用连接池

管理数据库连接可能会对整个应用程序的性能造成很大的影响。 若要优化性能,必须减少建立连接的次数,以及在关键代码路径中建立连接的时间。 使用连接池连接到 Azure Database for MySQL 以提高复原能力和性能。

你可以使用 ProxySQL 连接池程序来有效地管理连接。 使用连接池程序可以减少空闲连接并重用现有连接,这有助于避免问题。 有关详细信息,请参阅如何设置 ProxySQL

用来处理暂时性错误的重试逻辑

你的应用程序可能会遇到暂时性错误:到数据库的连接间歇性断开或丢失。 在这种情况下,服务器在 5 到 10 秒内重试一两次后就会启动并运行。

良好的做法是在第一次重试前等待 5 秒。 然后,每次重试都逐步延长等待时间,最多 60 秒。 限制最大重试次数。达到该次数时,应用程序会认为操作失败,因此你可以进一步进行调查。 有关详细信息,请参阅如何排查连接错误

启用读取复制以缓解故障转移问题

对于故障转移方案,可以使用数据传入复制。 使用只读副本时,在源服务器与副本服务器之间无法自动进行故障转移。

由于复制是异步的,因此你会注意到在源服务器与副本之间存在延迟。 网络延迟可能受许多因素影响,例如,在源服务器上运行的工作负荷的大小,以及数据中心之间的延迟。 大多数情况下,副本延迟在几秒钟到几分钟之间。

数据库部署

使用有效的过程手动部署数据库

在手动部署数据库的过程中,请执行以下步骤以最大程度地减少停机时间或降低部署失败的风险:

  1. 使用 mysqldumpMySQL Workbench,在新数据库上创建生产数据库的副本。
  2. 使用数据库所需的新架构更改或更新来更新新数据库。
  3. 将生产数据库置于只读状态。 在部署完成之前,最好不要对生产数据库执行写入操作。
  4. 使用步骤 1 中新更新的数据库测试你的应用程序。
  5. 部署你的应用程序更改,并确保应用程序目前正在使用具有最新更新的新数据库。
  6. 保留旧的生产数据库,以便回滚更改。 然后,你可以评估是删除旧的生产数据库,还是根据需要将其导出到 Azure 存储。

注意

如果应用程序类似于电子商务应用,并且不能将其置于只读状态,请在进行备份后直接在生产数据库上部署更改。 这些更改应在非高峰时间(此时发往应用的流量较小)进行,以最大程度地降低影响,因为某些用户可能会遇到请求失败的情况。

请确保应用程序代码还处理所有失败的请求。

使用 MySQL 原生指标来查看工作负荷是否超出内存中临时表的大小

使用读取密集型工作负荷时,针对 MySQL 服务器的查询可能会超出内存中临时表的大小。 读取密集型工作负荷可能会导致服务器改将临时表写入到磁盘,这会影响应用程序的性能。 若要确定服务器是否由于超出临时表大小而写入到磁盘,请查看以下指标:

show global status like 'created_tmp_disk_tables';
show global status like 'created_tmp_tables';

created_tmp_disk_tables 指标指明在磁盘上创建了多少表。 created_tmp_table 指标告诉你必须在内存中生成多少临时表,具体取决于你的工作负荷。 若要确定特定查询是否会使用临时表,请对查询运行 EXPLAIN 语句。 如果查询使用临时表运行,则 extra 列中的详细信息会指示 Using temporary

若要计算查询溢出到磁盘的工作负荷所占百分比,请在以下公式中使用指标值:

(created_tmp_disk_tables / (created_tmp_disk_tables + created_tmp_tables)) * 100

理想情况下,此百分比应小于 25%。 如果百分比为 25% 或更大,则建议修改两个服务器参数:tmp_table_size 和 max_heap_table_size。

数据库架构和查询

下面是构建数据库架构和查询时要记住的一些技巧。

为表列使用正确的数据类型

根据要存储的数据的类型使用正确的数据类型可以优化存储,并减少由于数据类型不正确而发生的错误。

使用索引

若要避免慢速查询,可以使用索引。 索引有助于快速查找具有特定列的行。 请参阅如何在 MySQL 中使用索引

对你的 SELECT 查询使用 EXPLAIN

使用 EXPLAIN 语句可以深入了解 MySQL 正在执行什么操作来运行查询。 它可以帮助你检测查询中的瓶颈或问题。 请参阅如何使用 EXPLAIN 分析查询性能