故障转移组概述和最佳做法 - Azure SQL 托管实例

适用于:Azure SQL 托管实例

通过故障转移组功能,可以管理托管实例中所有用户数据库到另一区域的复制和故障转移。 本文章概述了故障转移组功能,以及将其与 Azure SQL 托管实例一起使用的最佳做法和建议。

要开始使用此功能,请参阅为 Azure SQL 托管实例配置故障转移组

概述

通过故障转移组功能,可以管理托管实例中到另一个 Azure 区域中的托管实例的用户数据库的复制和故障转移。 故障转移组旨在简化大规模异地复制数据库的部署和管理。

有关详细信息,请参阅 Azure SQL 托管实例的高可用性。 有关异地故障转移 RPO 和 RTO 的信息,请参阅业务连续性概述

终结点重定向

故障转移组提供在异地故障转移期间保持不变的读写和只读侦听器终结点。 在异地故障转移后无需更改应用程序的连接字符串,因为连接会自动路由到当前主副本。 异地故障转移都会将组中所有的辅助数据库切换为主角色。 异地故障转移完成后,会自动更新 DNS 记录,以便将终结点重定向到新的区域。

卸载只读工作负载

为了减少对主数据库的流量,还可以使用故障转移组中的辅助数据库来卸载只读工作负载。 使用只读侦听器将只读流量定向到可读辅助数据库。

恢复应用程序

为了实现完整的业务连续性,添加区域数据库冗余只是解决方案的一部分。 在发生灾难性故障后,端对端地恢复应用程序(服务)需要恢复构成该服务的所有组件以及所有依赖服务。 这些组件的示例包括客户端软件(例如,使用自定义 JavaScript 的浏览器)、Web 前端、存储和 DNS。 所有组件必须能够弹性应对相同的故障,并在应用程序的恢复时间目标 (RTO) 值内变为可用,这一点非常关键。 因此,需要识别所有依赖服务,并了解它们提供的保证和功能。 然后,必须执行适当的步骤来确保对用户的服务所依赖的服务执行故障转移期间,用户的服务能够正常运行。

故障转移策略

故障转移组支持两种故障转移策略:

  • 由客户管理(推荐使用) - 当客户注意到意外中断影响了故障转移组中的一个或多个数据库的时,可以对组执行故障转移。 使用命令行工具(如 PowerShell、Azure CLI 或 Rest API)时,由客户管理的故障转移策略值为 manual
  • Azure 托管 - 如果发生影响主要区域的普遍中断,Azure 会启动其故障转移策略配置为 Azure 托管的所有受影响的故障转移组的故障转移。 不会为单个故障转移组或区域中的故障转移组子集启动 Azure 托管故障转移。 使用命令行工具(如 PowerShell、Azure CLI 或 Rest API)时,Azure 托管的故障转移策略值为 automatic

每个故障转移策略都有一组独特的用例,以及对故障转移范围和数据丢失的相应预期,如下表汇总:

故障转移策略 故障转移范围 用例 可能丢失数据
由客户管理
(推荐使用)
故障转移组 故障转移组中的一个或多个数据库受中断的影响而离线。 可以选择故障转移。
Azure 托管 区域中的所有故障转移组 数据中心、可用性区域或区域中发生大范围中断,导致数据库离线,Microsoft Azure SQL 服务团队决定触发强制故障转移。
仅当想要将灾难恢复责任委托给 Azure 并且应用程序能够容忍至少一小时或以上的 RTO(停机时间)时,才使用此选项。

由客户管理

在极少数情况下,内置的可用性或高可用性不足以缓解停机,故障转移组中数据库的离线持续时间可能会达到使用数据库的应用程序服务级别协议 (SLA) 无法接受的程度。 数据库可能由于仅影响少数数据库的本地化问题,也可能由于位于数据中心、可用性区域或区域级别的问题而离线。 在上述任何一种情况下,若要还原业务连续性,可以启动强制故障转移。

强烈建议将故障转移策略设置为由客户管理,这样你就可以控制何时启动故障转移并还原业务连续性。 当你注意到意外中断影响了故障转移组中的一个或多个数据库时,就可以启动故障转移。

Azure 托管

凭借 Azure 托管故障转移策略,灾难恢复责任将委托给 Azure SQL 服务。 要使 Azure SQL 服务启动强制故障转移,必须满足以下条件:

  • 自然灾害事件、配置更改、软件错误或硬件组件故障引起了数据中心、可用性区域或区域级中断,并且该区域中的许多数据库都受到了影响。
  • 宽限期已经到期。 由于验证中断的规模和缓解中断取决于人为操作,因此不能将宽限期设置为一小时以下。

满足这些条件时,Azure SQL 服务会为区域中所有已将故障转移策略设置为 Azure 托管的故障转移组启动强制故障转移。

仅在以下情况下将故障转移策略设置为 Azure 托管:

  • 你希望将灾难恢复职责委派给 Azure SQL 服务。
  • 应用程序可以容忍你的数据库离线至少一小时或更长时间。
  • 可以接受在宽限期过期后一段时间触发强制故障转移,因为强制故障转移的实际时间可能会有很大差异。
  • 可以接受故障转移组中的所有数据库进行故障转移,无论其区域冗余配置或可用性状态如何。 尽管为区域冗余配置的数据库对区域故障具有弹性,并且可能不会受到停机的影响,但如果它们是与 Azure 托管故障转移策略中的故障转移组一起使用,则仍然会进行故障转移。
  • 可以接受故障转移组中数据库进行强制故障转移,而不考虑与应用程序使用的其他 Azure 服务或组件的应用程序依赖关系(这可能会导致应用程序的性能降低或离线)。
  • 可以接受发生未知数量的数据丢失,因为强制故障转移的确切时间无法控制,并且会忽略辅助数据库的同步状态。
  • 故障转移组中的所有主要和辅助数据库都具有相同的服务层级、计算层级(预调配或无服务器)和计算大小(DTU 或 vCore)。 如果故障转移组中的所有数据库的服务级别目标 (SLO) 不匹配,则故障转移策略最终将由 Azure SQL 服务从 Azure 托管更新到由客户管理。

Azure 触发故障转移时,故障转移 Azure SQL 故障转移组的操作名称条目会添加到 Azure Monitor 活动日志。 该条目包括“资源”下故障转移组的名称,启动的事件显示单个连字符 (-),以指示故障转移是由 Azure 启动的。 也可以在 Azure 门户中新主服务器或实例的活动日志页上找到此信息。

术语和功能

  • 故障转移组 (FOG)

    故障转移组允许托管实例中的每个用户数据库作为单元故障转移到另一个 Azure 区域,以防主托管实例因主要区域中断而不可用。 由于 SQL 托管实例的故障转移组包含该实例中的所有用户数据库,因此,在一个实例上只能配置一个故障转移组。

    重要

    故障转移组的名称在 .database.chinacloudapi.cn 域中必须全局唯一。

  • 主要节点

    托管故障转移组中主数据库的托管实例。

  • 辅助节点

    托管故障转移组中辅助数据库的托管实例。 辅助数据库不能与主数据库位于相同的 Azure 区域。

    重要

    • 如果数据库包含内存中 OLTP 对象,则主和辅助异地副本实例必须具有匹配的服务层级,因为内存中 OLTP 对象驻留在内存中。 如果异地副本实例上的服务层级较低,可能会导致内存不足问题。 如果发生这种情况,次要副本可能无法恢复数据库,从而导致辅助数据库以及异地辅助数据库上的内存中 OLTP 对象不可用。 这反过来又可能导致故障转移失败。 为避免这种情况,请确保异地辅助实例的服务层级与主数据库的服务层级相匹配。 服务层级升级操作会针对不同的数据大小,可能需要一段时间才能完成。
  • 故障转移(无数据丢失)

    将辅助角色切换为主角色之前,故障转移在主数据库与辅助数据库之间执行完整数据同步。 这可以保证数据不会丢失。 只有当主数据库可访问时,才可能进行故障转移。 故障转移用于以下场景:

    • 不可接受数据丢失时在生产环境中执行灾难恢复 (DR) 演练
    • 将工作负载重新定位到不同的区域
    • 缓解服务中断(故障回复)后将工作负载恢复到主要区域
  • 强制故障转移(可能数据丢失)

    强制故障转移立即将辅助角色切换为主角色,而不会等待从主角色传播最近的更改。 此操作可能导致潜在的数据丢失。 在服务中断期间当主要节点不可访问时,强制故障转移将用作恢复方法。 缓解中断时,旧的主数据库将自动重新连接,并成为新的辅助数据库。 可以执行故障转移以进行故障回复,将副本返回到其原来的主和辅助角色。

  • 数据丢失宽限期

    由于数据使用异步复制复制到辅助数据库,因此使用 Azure 管理的故障转移策略对组进行强制故障转移可能会导致数据丢失。 可以自定义故障转移策略,以便反映应用程序对数据丢失的容错。 通过配置 GracePeriodWithDataLossHours,可以控制 Azure SQL 服务启动可能导致数据丢失的强制故障转移之前的等待时间。

  • DNS 区域

    创建新 SQL 托管实例时自动生成的唯一 ID。 将为此实例预配一个多域 (SAN) 证书,以便对与同一 DNS 区域中的任何实例建立的客户端连接进行身份验证。 同一故障转移组中的两个托管实例必须共享 DNS 区域。

  • 故障转移组读写侦听器

    DNS CNAME 记录,指向当前主要数据库。 此记录是创建故障转移组时自动创建的,可让读写工作负载在故障转移发生后主节点发生更改时,以透明方式重新连接到主数据库。 在 SQL 托管实例上创建故障转移组时,侦听器 URL 的 DNS CNAME 记录格式为 <fog-name>.<zone_id>.database.chinacloudapi.cn

  • 故障转移组只读侦听器

    DNS CNAME 记录,指向当前辅助数据库。 此记录是创建故障转移组时自动创建的,可让只读 SQL 工作负载在故障转移发生后辅助节点发生更改时,以透明方式连接到辅助数据库。 在 SQL 托管实例上创建故障转移组时,侦听器 URL 的 DNS CNAME 记录格式为 <fog-name>.secondary.<zone_id>.database.chinacloudapi.cn。 只读侦听器默认情况下会停用故障转移,因为这可以确保在辅助侦听器离线时不会影响主侦听器的性能。 但是,这也意味辅助数据库恢复前,只读会话将无法连接。 如果不能容忍只读会话停机,但能容忍以主数据库的潜在性能降级为代价将主数据库用于只读和读写流量,则可以通过配置 AllowReadOnlyFailoverToPrimary 属性为只读侦听器启用故障转移。 在这种情况下,如果辅助节点不可用,则会将只读流量自动重定向到主要节点。

    注意

    仅当已启用 Azure 托管故障转移策略,并触发强制故障转移时,该 AllowReadOnlyFailoverToPrimary 属性才有效。 在这种情况下,如果将该属性设置为 True,则新的主数据库将同时处理读写会话和只读会话。

故障转移组体系结构

故障转移组必须在主要实例上进行配置,需将其连接到不同 Azure 区域中的辅助实例。 实例中的所有用户数据库将复制到辅助实例。 不会复制 mastermsdb 这样的系统数据库。

下图演示了使用托管实例和故障转移组的异地冗余云应用程序的典型配置:

diagram of a failover group for Azure SQL Managed Instance.

如果应用程序使用 SQL 托管实例作为数据层,进行业务连续性设计时,请遵循以下一般准则和本文列出的最佳做法。

创建异地辅助实例

若要确保故障转移后与主要 SQL 托管实例的连接不中断,主要实例和辅助实例必须位于同一 DNS 区域。 这将确保可以使用同一多域 (SAN) 证书来验证客户端与故障转移组中两个实例中任一实例的连接。 准备好将应用程序部署到生产环境后,在不同的区域中创建一个辅助 SQL 托管实例,并确保它与主要 SQL 托管实例共享 DNS 区域。 可以通过在创建期间指定可选参数来实现。 如果使用 PowerShell 或 REST API,则可选参数的名称为 DNSZonePartner。 Azure 门户中相应可选字段的名称是主要托管实例。

重要

在子网中创建的第一个托管实例确定同一子网中所有后续实例的 DNS 区域。 因此同一子网中的两个实例不能属于不同的 DNS 区域。

有关在主要实例所在 DNS 区域中创建辅助 SQL 托管实例的详细信息,请参阅为 Azure SQL 托管实例配置故障转移组

使用配对区域

出于性能方面的考虑,将两个托管实例部署到配对区域。 与非配对区域相比,配对区域中的 SQL 托管实例故障转移组具有更好的性能。

Azure SQL 托管实例遵循安全部署做法,通常不会同时部署到 Azure 配对区域。 但是,无法预测将首先升级哪个区域,因此无法保证部署顺序。 有时,主实例先升级,有时辅助实例先升级。

如果 Azure SQL 托管实例是故障转移组的一部分,并且组中的实例不在 Azure 配对区域中,请为主数据库和辅助数据库选择不同的维护时段计划。 例如,可以为异地辅助数据库选择“工作日”维护时段,为异地主数据库选择“周末”维护时段。

启用和优化实例之间的异地复制通信流

必须建立和维护托管主实例和辅助实例的虚拟网络子网之间的连接,确保异地复制通信流不间断。 有多种方法可以在实例之间提供连接,你可以根据网络拓扑和策略从中进行选择:

建议使用全局虚拟网络对等互连(VNet 对等互连),在故障转移组中的两个实例之间建立连接。 它使用 Microsoft 主干基础结构,在对等互连的虚拟网络之间提供低延迟、高带宽的专用连接。 在对等互连的虚拟网络之间通信不需公共 Internet、网关或额外加密。

初始种子设定

在托管实例之间建立故障转移组时,在数据复制开始之前,会有一个初始种子设定阶段。 初始种子设定阶段是操作过程中耗时最长且开销最大的阶段。 初始种子设定完成后,数据将会同步,但只会复制后续的数据更改。 完成初始种子设定所需的时间取决于数据大小、复制的数据库数、主数据库的工作负荷强度,以及托管主实例和辅助实例的虚拟网络之间的链接速度,该速度主要取决于建立连接的方式。 在正常情况下,使用推荐的全局虚拟网络对等互连建立连接时,SQL 托管实例的种子设定速度高达每小时 360 GB。 为一批用户数据库并行执行种子设定,不必同时为所有数据库执行种子设定。 如果实例上托管了许多数据库,可能需要多个批次。

如果两个实例之间的链接速度比所需速度慢,则种子设定时间可能会受到明显影响。 可以根据所述种子设定速度、数据库数量、数据总大小和链接速度,来估算在数据复制开始之前初始种子设定阶段花费的时间。 例如,对于单个 100 GB 的数据库,如果链路每小时能够推送 84 GB 数据,并且没有其他数据库正在进行种子设定,则初始种子设定阶段大约需要 1.2 小时。 如果链路每小时只能传输 10 GB,则为 100 GB 数据库设定种子需要大约 10 小时。 如果有多个数据库要复制,则种子设定将会并行执行,在链接速度较慢的情况下,初始种子设定阶段可能需要相当长的时间,尤其是为所有数据库中的数据并行设定种子超过可用的链接带宽时。

重要

如果由于链接速度极慢或繁忙而导致初始种子设定阶段需要花费数天时间,则故障转移组创建可能超时。创建过程将在 6 天后自动取消。

管理到异地辅助实例的异地故障转移

故障转移组将管理主要托管实例上所有数据库的异地故障转移。 创建某个组后,实例中的每个数据库将自动异地复制到异地辅助实例。 无法使用故障转移组针对一部分数据库启动部分故障转移。

重要

如果从主要托管实例中删除了某个数据库,该数据库也会在异地辅助托管实例上自动删除。

使用读写侦听器(主 MI)

对于读写工作负载,使用 <fog-name>.zone_id.database.chinacloudapi.cn 作为服务器名称。 连接会自动定向到主数据库。 此名称在故障转移后不会更改。 异地故障转移涉及更新 DNS 记录,因此,仅在刷新客户端 DNS 缓存后,新客户端连接才会路由到新的主数据库。 由于辅助实例与主要实例共享 DNS 区域,客户端应用程序可以使用相同的服务器端 SAN 证书重新连接到辅助实例。 需要终止现有客户端连接,然后重新创建它们,然后才能将它们路由到新的主数据库。 无法通过托管实例的公共终结点访问读写侦听器和只读侦听器。

使用只读侦听器(辅助 MI)

如果逻辑上隔离的只读工作负载可以容忍数据延迟,则可以在异地辅助数据库上运行。 若要直接连接到异地辅助数据库,请使用 <fog-name>.secondary.<zone_id>.database.chinacloudapi.cn 作为服务器名称。

在业务关键层级中,SQL 托管实例支持通过只读副本,使用连接字符串中的 ApplicationIntent=ReadOnly 参数卸载只读查询工作负载。 如果配置了异地复制的辅助节点,则可以使用此功能连接到主要位置或异地复制位置中的只读副本:

  • 若要连接到主要位置中的只读副本,请使用 ApplicationIntent=ReadOnly<fog-name>.<zone_id>.database.chinacloudapi.cn
  • 若要连接到辅助位置中的只读副本,请使用 ApplicationIntent=ReadOnly<fog-name>.secondary.<zone_id>.database.chinacloudapi.cn

无法通过托管实例的公共终结点访问读写侦听器和只读侦听器。

故障转移后性能可能下降

典型的 Azure 应用程序使用多个 Azure 服务,并由多个组件构成。 是否对故障转移组进行异地故障转移仅根据 Azure SQL 组件的状态来决定。 主要区域中的其他 Azure 服务可能不受中断的影响,其组件可能仍在该区域中可用。 将主数据库切换到次要区域后,依赖组件之间的延迟可能会增大。 请确保对次要区域中的所有应用程序组件采用冗余配置,并对应用程序组件和数据库进行故障转移,这样应用程序的性能就不会受到较高的跨区域延迟的影响。

强制故障转移后潜在数据丢失

如果主要区域发生中断,则最近的事务可能尚未复制到异地辅助数据库,此时如果执行强制故障转移,则可能会丢失数据。

DNS 更新

启动故障转移后,读写侦听器的 DNS 更新会立即发生。 此操作不会导致数据丢失。 但是,在正常情况下,切换数据库角色的过程可能需要 5 分钟时间。 在完成之前,新主实例中的某些数据库仍是只读的。 如果使用 PowerShell 发起故障转移,则切换主要副本角色的操作是同步的。 如果使用 Azure 门户启动故障转移,UI 会指示完成状态。 如果使用 REST API 启动故障转移,请使用标准 Azure 资源管理器的轮询机制来监视完成情况。

重要

缓解引发异地故障转移的服务中断后,使用手动计划故障转移将主数据库移回初始位置。

借助无需支付许可费用的 DR 副本节省成本

通过将辅助托管实例配置为仅用于灾难恢复 (DR) 的实例,可以节省 SQL Server 许可成本。 要设置此功能,请参阅为 Azure SQL 托管实例配置免许可备用副本

只要辅助实例不用于读取工作负载,Azure 就免费提供与主实例匹配的 vCore 数量。 辅助实例使用的计算和存储依然是付费的。 故障转移组仅支持一个副本,该副本必须为可读副本或者被指定为仅限 DR。

启用依赖于系统数据库中的对象的方案

系统数据库不会复制到故障转移组中的辅助实例。 若要启用依赖于系统数据库中的对象的方案,请确保在辅助实例上创建相同的对象并让辅助实例与主实例保持同步。

例如,如果你计划在辅助实例上使用相同的登录名,请确保使用相同的 SID 创建它们。

-- Code to create login on the secondary instance
CREATE LOGIN foo WITH PASSWORD = '<enterStrongPasswordHere>', SID = <login_sid>;

有关详细信息,请参阅复制登录名和代理作业

同步实例属性和保留策略实例

故障转移组中的实例保持独立的 Azure 资源,对主实例配置所做的任何更改都不会自动复制到辅助实例。 确保同时在主要和辅助实例上执行所有相关更改。 例如,如果在主实例上更改备份存储冗余或长期备份保留策略,请确保在辅助实例上也进行更改。

缩放实例

可以在同一 服务层级 内将主实例和辅助实例纵向扩展或缩减到不同的计算大小,或纵向扩展或缩减到不同的服务层级。 在同一服务层级内纵向扩展时,建议先纵向扩展异地辅助数据库,然后再纵向扩展主数据库。 在同一服务层级内纵向缩减时,按相反顺序操作:先纵向缩减主数据库,再纵向缩减辅助数据库。 将实例缩放到不同服务层级时,将强制执行此建议操作。 在缩放服务层级和 vCore 以及存储时,会强制执行操作序列。

特别建议按此顺序进行,以避免出现以下问题:较低 SKU 的异地辅助数据库过载,并且必须在升级或降级过程中重新设定种子。

注意

存在已知问题,即使用关联故障转移组侦听器缩放的实例的可访问性会受到影响。

防止关键数据丢失

由于广域网的延迟时间较长,异地复制使用了异步复制机制。 如果主数据库发生故障,异步复制会导致数据丢失不可避免。 为了防止这些关键事务数据丢失,应用程序开发人员可以在提交事务后立即调用 sp_wait_for_database_copy_sync 存储过程。 调用 sp_wait_for_database_copy_sync 会阻止调用线程,直到最后提交的事务已传输并强制执行到辅助数据库的事务日志中。 但是,它不会等待传输的事务在辅助数据库上进行重播(恢复)。 sp_wait_for_database_copy_sync 范围限定为特定异地复制链接。 对主数据库具有连接权限的任何用户都可以调用此过程。

为了防止在用户发起的计划性异地故障转移过程中丢失数据,复制会自动临时更改为同步复制,然后执行故障转移。 然后,复制在异地故障转移完成后返回到异步模式。

注意

sp_wait_for_database_copy_sync 可防止特定事务异地故障转移后数据丢失,但不保证完全同步进行读取访问。 sp_wait_for_database_copy_sync 过程调用导致的延迟可能很明显,具体取决于调用时主数据库上尚未传输的事务日志大小。

故障转移组状态

故障转移组报告其状态,描述数据复制的当前状态:

  • 正在设定种子 - 初始种子设定是在创建故障转移组后进行,直到在辅助实例上初始化所有用户数据库。 当故障转移组的状态为“种子设定”时,无法启动故障转移过程,因为用户数据库尚未复制到辅助实例。
  • 正在同步 - 故障转移组的常规状态。 这意味着主要实例上的数据更改正在异步复制到辅助实例。 该状态不能保证数据在每个时刻都完全同步。 因为故障转移组中实例之间的复制过程存在异步性质,所以主要实例中的一些数据更改可能仍然需要复制到辅助实例。 自动和手动故障转移都可以在故障转移组的状态为“同步”时启动。
  • 正在进行故障转移 - 此状态指示自动或手动启动的故障转移过程正在进行。 当故障转移组位于此状态时,无法启动对故障转移组或其他故障转移的更改。

故障回复

使用 Azure 托管故障转移策略配置故障转移组时,会根据定义的宽限期在灾难方案中启动到异地辅助服务器的强制故障转移。 必须手动启动故障回复到旧的主服务器。

使用事务复制功能的故障转移组

支持对故障转移组中的实例使用事务复制。 但是,如果在将 SQL 托管实例添加到故障转移组之前配置复制,则复制会在你开始创建故障转移组时暂停,并且复制监视器显示状态 Replicated transactions are waiting for the next log backup or for mirroring partner to catch up。 一旦成功创建故障转移组,复制就会恢复。

如果“发布者”或“分发者”SQL 托管实例位于故障转移组中,则 SQL 托管实例管理员必须清理旧的主实例上的所有发布内容,然后在故障转移后,在新的主实例上重新配置这些发布内容。 有关此场景中所需的活动步骤,请参阅事务复制指南

权限、限制和先决条件

请首先查看故障转移组配置指南,了解相关“权限”、“限制”和“先决条件”的列表,然后再开始配置故障转移组。

以编程方式管理故障转移组

也可以使用 Azure PowerShell、Azure CLI 和 REST API 以编程方式管理故障转移组。 若要了解详细信息,请参阅配置故障转移组