Azure上にシステム構成をデザインする場合、可能な限り、データベースもマネージドのサービス (Azure SQL Database / SQL Managed Instance / Azure Database for PostgreSQL / Azure Cosmos DB など) を使いたいですよね。
しかしながら、要件によっては、Azure 仮想マシン上にSQL Serverをインストールして使用することを選択することもあると思います。(最近では、Active Directory フェデレーション サービス (AD FS)は、Azure SQL Database / SQL Managed Instance がサポートされていなかったため、Azure 仮想マシン上にSQL Server をインストールするという選択をしました。)
※ AWS EC2 でも同様の構成を組むことはできたのですが、AWS EC2の場合、Azure ハイブリッド特典(https://azure.microsoft.com/ja-jp/pricing/hybrid-benefit/)が使用できないため、コスト的にAzureが有利であり、Azureを選択しました。
Azure仮想マシン上にSQL Serverをインストールした場合、自身で冗長化構成を構築する必要があります。Premium ファイル共有機能がリリースされたため、以前と比べて、SQL Server フェールオーバー クラスタ インスタンス (FCI) を構築し易くはなったのですが、読み取り専用のセカンダリデータベースを使用したい場合など、SQL Server AlwaysOn 可用性グループで冗長化することのほうが多いかもしれません。
Premium ファイル共有の詳細については Premium ファイル共有を使用した SQL Server FCI - Azure Virtual Machines | Microsoft Docs を参照
今回は、Azure仮想マシン上にSQL Serverをインストールし、SQL Server AlwaysOn 可用性グループを構築した場合に、変更したほうがよい設定について紹介しようと思います。
Windows Server Failover Clustering (WSFC) 側の設定変更
フェールオーバー クラスタのハートビート間隔設定で SameSubnetDelay (単位:ミリ秒) * SameSubnetThreshold (単位:回数) の値が、30秒 (30000 ミリ秒) 以上になるようにパラメータ値を変更します。例えば、SameSubnetDelay = 1000、SameSubnetThreshold = 30 のように変更します。
Azure仮想マシンでは、セキュリティパッチの適用などで、可能な限り再起動が発生しないよう、ライブ移行("メモリ保護" 更新) テクノロジーが使用されています。
しかしながら、上記のテクノロジーを実現するにあたり、Azure仮想マシン側が一時的にフリーズ状態になります。(アーキテクチャとしては、30秒以内に再開されるらしいです。) そのため、フェールオーバー クラスタのハートビート設定が 30秒よりも短い場合、せっかくAzure仮想マシンで再起動が発生しないようにパッチの適用が実施できたとしても、不必要なフェールオーバーが発生し、ダウンタイムが発生する可能性があるため、事前にこのパラメータ値を延ばしておくと良いかと思います。
フェールオーバー クラスタのハートビート設定については Azure 上でフェールオーバー クラスターを構築する際の留意事項について | Microsoft Docs を参照
※ Windows Server 2019 では、新機能として Azure-aware clusters 機能が追加され、Azure仮想マシン上にクラスタリング機能が追加された場合、自動的に検知し、最適なパラメータ値に自動構成することができるもようです。この機能でハートビートの設定が変更されるのかについては、別途確認しようと思います。
Windows Server 2019の新機能については Windows Server でのフェールオーバークラスタリングの新機能 | Microsoft Docsを参照
ライブ移行("メモリ保護" 更新) テクノロジーについては Azure での VM のメンテナンスと更新 | Microsoft Docs を参照
※ 更新 : 2020/02/09
Azure 上に Windows Server 2019でWSFCを構築したところ、フェールオーバー クラスタのハートビート間隔設定が、SameSubnetDelay = 1000、SameSubnetThreshold = 30になっていました。
SQL Server AlwaysOn 可用性グループ側の設定変更
1) Lease Timeout 値を 30秒 (30000ミリ秒) 以上に設定する。(既定値: 20秒 : 20000ミリ秒)
フェールオーバー クラスタのハートビート設定と同様に、セキュリティパッチの適用時などでAzure仮想マシン側が一時的にフリーズ状態になった場合に、不必要な可用性グループのフェールオーバーの発生を防ぐという意味で、このパラメータ値を延ばすと良いかと思います。
※ Lease Timeout 値を設定する場合、Lease Timeout値 * 1/2 の値が WSFCのハートビート間隔 (SameSubnetDelay (単位:ミリ秒) * SameSubnetThreshold (単位:回数) ) の値よりも短くなるように設定する必要があります。
Lease Timeout値の変更方法については 可用性グループ リースの正常性チェック タイムアウト - SQL Server Always On | Microsoft Docs を参照
2) HealthCheckTimeout 値をLease Timeout 値に指定した値よりも長く設定する。(既定値: 30秒 : 30000ミリ秒)
HealthCheckTimeout 値は、Lease Timeout 値よりも長く設定する必要があるため、Lease Timeout 値を変更した場合は、HealthCheckTimeout 値も延ばします。
既定の設定では、HealthCheckTimeout 値は、Lease Timeout 値の1.5倍になっているため、Lease Timeout 値の1.5倍以上に設定すると良いかと思います。
HealthCheckTimeout値の変更方法については 可用性グループ リースの正常性チェック タイムアウト - SQL Server Always On | Microsoft Docs を参照
補足として、フェールオーバー クラスタのハートビート間隔、Lease Timeout、HealthCheckTimeout については、間隔を延ばすほど、本当に障害が発生した場合の検知が遅れることになる点を念頭において、設定値を検討されると良いかと思います。