在 Compute Engine 上配置 MySQL


Compute Engine 提供一系列不同的实例类型和存储选项,用于从 MySQL 数据库读取和写入数据。为确保数据库工作负载获得最佳性能和成本效益,我们建议您在较新的基础设施即服务 (IaaS) 产品上运行。

以下配置建议考虑到 MySQL 工作负载通常用于读取繁重的系统,例如联机事务处理 (OLTP) 或支持典型 Web 应用的数据库。它们还考虑了常见的配置选择,例如使用 MySQL 8.0 版或更高版本以及使用 InnoDB 存储引擎。对于对性能敏感的工作负载,您可能需要调整配置以适应。我们建议您先参考本指南进行部署,然后使用实际工作负载进行测试,以验证您的配置是否满足需求。

选择虚拟机 (VM)

对于 MySQL 工作负载,我们建议使用最新一代的 C 和 N 机器家族,因为它们包含的配置非常适合大多数实际的 MySQL 配置。如需了解这些机器系列的简介,请参阅以下Google Cloud 博文。 这些机器家族使用 Titanium,并基于最新一代的 Intel、AMD 和 Axion 处理器

关注性能

对于对性能要求较高的工作负载(例如业务关键型 MySQL 数据库),我们建议使用最新的 C4C4A 实例(如果这些实例在您的区域中可用)。如果您无法访问这些实例,不妨考虑使用 C3C3D 实例,它们同样侧重于性能。

这些实例可为计算密集型操作提供最低且最稳定的延迟时间,并包含以下有用的功能,可用于注重性能的工作负载:

  • 通过提前通知控制主机维护事件
  • 控制单核 Turbo 模式,以提高性能一致性
  • Tier_1 网络,可实现更高的网络带宽

如果您使用的是 C4A、C3 或 C3D 实例,还可以使用本地固态硬盘 (Local SSD) 来满足特定的性能要求。

优化费用

对于主要优先事项是优化成本的工作负载(例如流量为低到中等水平的 MySQL 数据库,或在测试或开发环境中使用的数据库),我们建议您使用最新的 N4 实例。这些实例使用 Compute Engine 的下一代动态资源管理功能来优化总费用,同时保持出色的性能,但没有 C4、C4A、C3 和 C3D 提供的强大保证。如需了解详情,请参阅新一代动态资源管理

配置虚拟机的大小

对于您使用的任何虚拟机,请务必根据您期望的 MySQL 性能水平选择合适的虚拟机大小。

如果您希望获得较高的每秒写入事务数 (TPS) 性能,则需要考虑的主要因素是块存储。如需了解详情,请参阅本页面下文的配置块存储

如果您希望获得较高的每秒读取查询次数 (QPS) 性能,我们强烈建议您使用 MySQL 基于 RAM 的缓冲池来缓存热门数据并减少磁盘访问次数。如需最大限度地发挥这些优势,请按以下步骤操作:

  • 选择的虚拟机大小应确保工作集(即数据库一次处理的数据总量)适合缓冲区池。
  • 调整缓冲池的大小,使其能够使用虚拟机上的大部分 RAM。

为了尽可能降低这种调整虚拟机大小的费用,我们建议使用 RAM 与虚拟 CPU (vCPU) 的比率较高的虚拟机,以免为未使用的 vCPU 付费。

为了在大多数 MySQL 工作负载中实现理想的平衡,请确定工作负载的工作集,然后选择适合该工作集的最小 highmem 实例规格(以 RAM 为单位)。highmem 实例规格为每个 vCPU 分配了约 8 GB 的 RAM。这样一来,您便有足够的内存来缓存大型工作集,同时也有足够的 CPU 来处理高查询负载。

对于工作集较大但查询速率较低的工作负载,使用 N4 实例时,您可以使用自定义机器类型搭配扩展内存来进一步提高 RAM 与 vCPU 的比率,从而进一步优化总费用。

配置虚拟机的网络带宽

对于大多数 MySQL 用例,您可以坚持使用实例的默认网络带宽限制。如果此功能符合您的需求,则无需升级到 Tier_1 网络。

配置块存储

Google Cloud Hyperdisk 是唯一一代可用于最新 Compute Engine 虚拟机系列的持久性块存储。我们认为,Hyperdisk Balanced 最适合绝大多数 MySQL 工作负载。如需详细了解 Hyperdisk,请参阅 Hyperdisk 文档

Google Cloud Hyperdisk

Hyperdisk Balanced 提供以下功能:

  • 以低成本实现固态硬盘 (SSD) 延迟
  • 为需要高性能的应用提供高性能配置
  • 高于 99.999% 的持久性,可防范行业范围内的硬件故障和静默数据损坏风险
  • 使用 Google 管理的加密密钥或客户管理的加密密钥对所有 Hyperdisk 静态数据进行加密

选择性能级别

借助 Hyperdisk Balanced,您可以独立于磁盘的存储大小来选择性能级别,从而优化数据库的性能,同时仅需为工作负载所需的输入/输出 (I/O) 资源付费。如果 MySQL 数据库的缓冲池大于其工作集,那么在稳态运行期间,它可以从缓冲池中处理几乎所有读取查询,而无需访问磁盘。

如需为 Hyperdisk 卷选择性能级别,请考虑 MySQL 写入工作负载,尤其要重点考虑以下因素:

  • InnoDB 重做日志的访问权限
  • 后续更新 InnoDB 数据文件和索引

除了稳定状态的运行之外,数据库维护事件也可能会导致磁盘性能出现更明显的波动。这种情况发生的频率往往会随着数据库的写入工作负载而增加,因此在以下情况下更有可能发生:使用重做日志进行崩溃后恢复,或者备份系统通过读取自上次备份以来所有数据库更改来复制自身。

确定磁盘大小

以下是三种用于确定磁盘性能限制的常见策略:

  1. 使用默认配置。每个磁盘至少具有每秒 3,000 次输入/输出 (IOPS) 和 140 MiBps 的吞吐量。这足以满足基本 MySQL 工作负载和操作系统 (OS) 启动卷的需求。如果您的使用情形超出此范围,您可以根据需要修改预配的 I/O 性能,而无需停止工作负载。
  2. 衡量现有使用情况。如果您的数据库已在其他环境中运行,请以一分钟或更短的时间粒度记录其磁盘 IOPS 和吞吐量。在您获得一到两周的数据后(以便您的样本集包含一些负载波动和正常维护事件),请从该数据集中选择一个高百分位数值,并添加一个小的缓冲值,以应对自然增长或意外使用情况。
  3. 先估算您的需求,然后再进行修改。如果您没有现有数据源,可能需要先估计性能需求,然后在部署后进一步调整。我们建议您最初预置比您认为需要的更高的值,这样您的工作负载就不会遇到性能瓶颈,然后最终减少预置的性能以适应您的工作负载。

提高磁盘性能

您可以将每个 Hyperdisk Balanced 磁盘的性能提升到最高 160,000 IOPS 和 2,400 MBps 的吞吐量。虚拟机的大小有助于确定 Hyperdisk 的最高性能限制,因此如果您希望获得非常高的 Hyperdisk 性能,可能需要增加虚拟机的核心数。如果最需要高磁盘性能的工作负载所需的性能高于单个 Hyperdisk Balanced 磁盘所能提供的性能,您可以采用以下任一方法将多个 Hyperdisk Balanced 磁盘条带化:

  • 升级到 Hyperdisk Extreme
  • 使用其他软件独立磁盘冗余阵列 (RAID) 机制,例如 mdadm

在扩缩 MySQL 数据库时,您可以动态增加磁盘的容量和性能,而不会造成停机。这有助于提升在线分析处理 (OLAP) 风格的工作负载的性能,此类工作负载会执行无法放入 RAM 并溢出到磁盘的大型复杂联接。在极少数情况下,需要极低存储延迟时间且可以容忍数据丢失的 MySQL 工作负载可以将完整的数据集存储在本地 SSD 上。您还可以使用以下混合解决方案来缩短读取延迟时间并限制耐久性降低:

  • 在 Hyperdisk 和本地 SSD 之间镜像数据集。
  • 使用卷管理器将本地 SSD 配置为存储在底层 Hyperdisk 上的数据的缓存。

利用其他 Hyperdisk 功能

Hyperdisk 还提供以下功能,可增强或简化本地高可用性和灾难恢复工作流:

如需详细了解如何使用 MySQL for Compute Engine 配置这些功能,请参阅本页面后面的高可用性部分。

本地 SSD

某些 Compute Engine 机器家族允许您使用本地 SSD 而不是 Hyperdisk。这些不是持久性存储空间,但 MySQL 工作负载通常使用它们来存储临时表空间

如需了解如何使用本地 SSD 扩缩 MySQL 数据库,请参阅本页中的动态调整磁盘大小

其他 Compute Engine 功能

您可以使用以下 Compute Engine 功能来帮助优化 MySQL 部署。

Cloud Monitoring

如需监控虚拟机的性能和基础架构服务使用情况,请使用Google Cloud 控制台。在虚拟机实例页面的可观测性标签页中,您可以监控与性能相关的指标,例如 CPU 和内存利用率、网络带宽以及实例的预配性能。同样,在磁盘页面的可观测性标签页中,您可以监控磁盘卷的吞吐量和 IOPS。

如需自定义看到的性能指标,请使用 Cloud Monitoring 构建查询。您可以选择要查看的基础设施服务的具体效果指标。对于特定于 MySQL 的指标,Compute Engine 提供 MySQL 工作负载插件

配置操作系统的最佳实践

  • 使用适当的文件系统。Google 专注于针对 Linux 的 ext4 和 XFS 文件系统进行优化;不过,大多数文件系统都适合与 MySQL 搭配使用。
  • 在基本操作系统配置中关闭透明大内存页 (THP)。如需了解关闭 THP 的步骤,请参阅 THP 文档
  • 如果您使用的是 Linux,请使用 relatimelazytime 标志进行文件系统装载配置。这样可以减少与在读取、修改文件或更改文件元数据时更新文件上的 atimemtimectime 值相关的性能开销。

配置 MySQL 的最佳实践

我们建议您为 MySQL 使用以下配置设置。

  • 使用新近版本的 MySQL。Google 专注于针对 MySQL 版本 8.0 及更高版本进行优化。
  • 增加缓冲池的大小。MySQL 通过在 RAM 中缓存数据来提高读取性能,从而减少磁盘访问次数。默认情况下,MySQL 的缓冲池大小为 128MiB,对于大多数实际应用场景来说,这个大小太小了。我们建议您增加 innodb_buffer_pool_size 的大小,使其大于应用在数据库中访问的工作集的大小。这通常包括以下步骤:

    1. 衡量或估算正在运行的 MySQL 实例副本上的工作集大小。
    2. 选择具有足够 RAM 来容纳该工作集的虚拟机 (VM) 大小和配置。
    3. 配置虚拟机上的缓冲区池大小,使其占用大部分可用 RAM。
  • 开启双写缓冲区。MySQL 具有双写缓冲区,可帮助防止写入撕裂。写入撕裂是一种故障模式,如果写入覆盖了磁盘上的多个块,但在写入过程中发生硬件或电源故障,则可能只会部分提交写入。如需享受此保护,请开启 innodb_doublewrite

  • innodb_flush_log_at_trx_commit的值设置为1 这样可确保写入事务在提交时在磁盘上持久存在。

  • 为了减少性能开销,请为 innodb_flush_method 指定值。 对于 MySQL 8.0.14 及更高版本,请将 innodb_flush_method 的值设置为 O_DIRECT_NO_FSYNC,这是最佳值,但仅在这些版本中提供。对于低于 8.0.14 的 MySQL 版本,请将 innodb_flush_method 的值设置为 O_DIRECT

  • 在高可用性复制方案中,将主数据库实例的 sync_binlog 值设置为 1MySQL 使用其二进制日志来传达从主数据库到辅助数据库的更改,因此这可确保在事务提交时提交二进制日志,从而尽可能缩短数据库之间的复制延迟时间并实现恢复点目标 (RPO)。

  • 在 C 系列机器家族上使用 MySQL 时,请开启 innodb_numa_interleave 这样可确保 MySQL 的缓冲池能够利用非一致内存访问 (NUMA) 政策。

何时关闭双写缓冲区

MySQL 的双重写入缓冲区可防止写入中断,但会使 MySQL 写入事务的性能开销增加最多 25%,这可能会影响事务延迟时间。Google Cloud Hyperdisk 还提供撕裂写入保护,因此如果您使用 MySQL 直接写入在 Hyperdisk 上运行的 ext4 文件系统,可以安全地关闭双写缓冲区。

不过,为了使 Hyperdisk 的撕裂写入保护功能有效,您必须配置数据库和磁盘之间的文件系统及其他中间软件层,以避免在磁盘层之上引入撕裂写入。以下列表提供了一些可能会在 Hyperdisk 层之上引入撕裂写入的配置示例:

  • 在容器(例如 Google Kubernetes Engine 或自托管 Kubernetes)内运行 MySQL 实例。
  • 将 MySQL 文件存储在 XFS 文件系统上,该文件系统在大多数 Linux 内核配置中不支持足够大的块大小。
  • 将 MySQL 文件存储在会导致磁盘条带化的独立磁盘冗余阵列 (RAID) 配置中,例如 Linux 的 mdadm 或 Windows 的存储空间存储空间直连
  • 将 MySQL 文件存储在卷管理器(例如适用于 Linux 的 Logical Volume Manager (LVM) 或适用于 Windows 的存储空间和存储空间直连)之上。
  • 将 MySQL 文件存储在 Hyperdisk 上,并配置本地固态硬盘 (SSD) 作为缓存,例如使用 lvmcachedm-cachebcache(对于 Linux)或存储空间(对于 Windows)。

  • 使用嵌套虚拟化在虚拟机内运行 MySQL 实例。

虽然您可以设置上述配置,使其不会引入写入撕裂,但我们不建议在使用这些配置时关闭双写缓冲区,因为很难验证给定配置是否安全。

(可选)关闭双写缓冲区

如需关闭双写缓冲区,请完成以下步骤:

  1. 在 ext4 文件系统上,您必须启用 bigalloc 功能,并将文件系统的集群大小配置为 16KiB 或更大的 16KiB 的 2 的幂次方倍数。这可确保 MySQL 的写入操作在发送到 Hyperdisk 之前不会被文件系统拆分为单独的 IO。如果未能提高该限制或使用的任何值小于 16KiB,则无法防范写入撕裂。以 16KiB 集群大小为例,此设置是在创建文件系统时配置的:

    mkfs.ext4 -O bigalloc -C 16384 /dev/<device-name>
    
  2. 停用 innodb_doublewrite 并将 innodb_flush_method 设置为 O_DIRECTO_DIRECT_NO_FSYNC(具体取决于您的 MySQL 版本,如上所述)。

配置高可用性 (HA) 和备份解决方案

我们强烈建议您为所有关键 MySQL 工作负载配置高可用性 (HA) 和备份解决方案,以保护这些工作负载。对于高可用性和备份,以下因素最为重要:

高可用性解决方案通常以接近零的 RTO 和 RPO 为目标,但仅针对基础架构故障提供保护。备份解决方案的目标是更长的 RTO 和 RPO 窗口期,但可涵盖更多故障情形,例如:

  • 意外删除数据
  • 勒索软件攻击
  • 自然灾害

配置高可用性 (HA)

HA 功能使用存储和计算冗余来确保 MySQL 数据库在发生主机故障或中断时减少停机时间,从而让客户端应用即使在实例或可用区不可用时也能访问其数据。

MySQL 允许在以下模式下进行复制:

  • 异步模式。在异步模式下,主节点会在写入事务提交到本地后立即确认,因此如果主节点发生中断,则在故障切换期间可能会丢失少量最近写入的数据,因为 RPO 接近于零,但实际上不为零。
  • 半同步模式。在半同步模式下,主服务器会等待,直到可配置数量的副本确认收到事务后,才会确认事务。这样一来,在发生意外故障切换时,数据丢失的几率会大大降低,因为 RPO 实际上为零。

对于这两种模式,RTO 取决于健康检查执行以下操作的速度:

  1. 识别失败的实例。
  2. 触发故障切换。
  3. 使用域名系统 (DNS) 或其他数据库服务器标识方式,通知客户端故障切换实例现在是主实例。

无论采用哪种复制模式,您都必须拥有一个故障切换实例来复制到该实例。 您可以在以下任一位置找到该实例:

  • 与主实例位于同一可用区
  • 主实例所在区域内的其他可用区
  • 与主实例所在的区域不同

为了即使在可用区服务中断期间也能保持高可用性,我们建议采用以下配置:

  • 将主实例和故障切换实例放置在不同的可用区中,无论它们是否位于同一区域。
  • 使用异步复制。这是因为,如果您使用半同步复制,将主实例和故障切换实例放置在不同的可用区中可能会导致写入事务提交的延迟时间较长。
  • 如果您需要零 RPO,请使用 Hyperdisk Balanced 高可用性,这种磁盘可在同一区域中的两个可用区之间同步复制。如需了解详情,请参阅 Google 关于使用 Hyperdisk 高可用性提供 HA 服务的指南。 配置 Hyperdisk Balanced 高可用性时,建议您与有状态的托管式实例组集成,以便诊断实例健康状况问题并自动执行恢复操作。

配置备份和数据恢复能力方案

备份和数据恢复能力计划有助于防止在发生意外数据删除、勒索软件攻击和自然灾害等故障时丢失数据。您还可以根据合规性和审核要求,将它们用作冷存储。对于 MySQL,您可以选择多种备份方法,其中一些方法在数据库级别运行,而另一些方法在存储卷级别运行。选择方法时,您应主要考虑 RTO 和 RPO 要求。

在数据库级别进行备份

对于数据库级备份,请考虑使用 MySQL 提供的以下选项:

如需详细了解 MySQL 的数据库级备份选项,请参阅 MySQL 文档中的备份和恢复

对于上述任何选项,您都必须拥有一个辅助存储系统来复制备份数据。我们推荐以下工具:

使用 Hyperdisk 在存储层级截取快照以及进行克隆

对于存储级备份,我们建议使用 Hyperdisk 产品来截取快照、进行克隆、以其他方式捕获 MySQL 数据库的时间点视图。此方法的 RPO 取决于您截取数据库快照的频率,而 RTO 则取决于您使用的具体解决方案。

如果您非常重视快速恢复,并且只需要在可用区内进行备份覆盖,我们建议您使用 Hyperdisk 的即时快照。即时快照以增量方式捕获特定时间点的数据,并且可以通过磁盘克隆将数据快速恢复到新的 Hyperdisk 卷,从而实现分钟级的 RTO。当磁盘的内容被覆盖、删除或损坏时,您可以使用它们来恢复数据,并且它们在与源磁盘相同的可用区或区域中本地可用。如需了解详情,请参阅即时快照简介

对于灾难恢复场景,其中数据必须以比原始磁盘更高的冗余度存储在单独的位置,以确保单个灾难不会影响所有数据副本,我们建议您使用 Hyperdisk 的归档和标准磁盘快照。归档快照和标准磁盘快照会在某个时间点创建磁盘中数据的副本,并以不可变格式将其存储在具有高冗余度的存储空间中。当您创建磁盘的多个快照(例如使用快照时间表)时,Hyperdisk 只会存储增量更改。如果您可以接受较高的 RTO,那么归档磁盘快照和标准磁盘快照就非常适合,因为从快照存储空间将数据复制回虚拟机存储空间可能意味着恢复时间会更长。如需了解详情,请参阅创建归档磁盘快照和标准磁盘快照

Hyperdisk 的即时快照及其归档快照和标准快照在单个磁盘中都是崩溃一致的。这意味着,当您从快照进行恢复时,MySQL 数据库必须运行正常的 InnoDB 恢复步骤,以使其日志和数据文件恢复到一致状态。根据 InnoDB 重做日志的配置,这可能会延长 RTO。以下模式可能会进一步加大创建一致的数据库快照的难度:

  • 您的 MySQL 数据库文件分布在多个卷中。
  • 您使用的是 Linux 软件 RAID 实用程序,例如 mdadm
  • 您已将 MySQL 的配置存储位置分隔到不同磁盘上的文件系统中。

如需创建在快照恢复后无需恢复的快照,请完成以下步骤:

  1. 暂时锁定对 MySQL 数据库的写入访问权限。
  2. 使用 LOCK INSTANCE FOR BACKUPFLUSH TABLES WITH READ LOCK 命令将所有正在进行的缓冲区刷新到磁盘。
  3. 启动快照操作。
  4. 对于多磁盘场景,在 MySQL 级别刷新后,在服务器上执行 syncfsfreeze 命令,以将所有正在进行的写入刷新到磁盘,并在文件系统级别暂停新的传入写入。

捕获数据库的初始快照后,您无需继续锁定磁盘,因为 Hyperdisk 可以快速捕获时间点视图,然后异步处理任何后续存储复制步骤。如果您需要这些步骤来确保快照一致性,并且想要消除这种写入对主数据库的影响,您还可以针对数据库副本(而非主数据库)运行备份。

后续步骤