SQL Server 2016 RC (製品候補版) で機能追加されたようなのですが、SQL Server 2016 では、分散可用性グループ (Distributed Availability Group) を設定できるようになりました。
Distributed Availability Groups (AlwaysOn Availability Groups)
分散可用性グループの設定について軽くまとめてみたいと思います。
通常の可用性グループは、
- 同一の WSFC に参加しているノード間で可用性グループを構築する
構成となります。
分散可用性グループは異なる WSFC の可用性グループ間でデータの同期を行うものとなります。
これにより、遠隔地とデータ同期を行う際に、単一の WSFC ではなく、各拠点で独立した WSFC を構築し、そのクラスター間でデータの同期ができるようになりますので、構成の柔軟性が増す形になります。
# 非対称ストレージのような構成をとらなくてもよくなります。
今回は、クラスターを構築する手間を抑えるため、Windows Server 2016 TP4 のワークグループクラスターを使用していますが、仕組みとしては、ドメイン環境のクラスターでも問題はないはずです。
この機能を使用する場合は、ワークグループクラスターの方が取り回しがよいかと思いますが。
本投稿の環境としては、以下の構成を使用しています。
ag1 と ag2 間を分散可用性グループにより、データの同期を行います。
今回の環境ですが、機能を動作させたかっただけですので、ベースの環境は以下のような設定を行い構築しています。
- DNS を使用しない、hosts ベースでワークグループクラスターを構築
- SQL Server のサービスアカウントはすべて同一のユーザー名/パスワードを設定し、各可用性レプリカで以下のクエリを実行して、エンドポイントへの接続を許可。
CREATE LOGIN [<コンピューター名>\<サービスアカウント>] FROM WINDOWS GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [<コンピューター名>\<サービスアカウント>]
それでは、実際の構築の流れを見ていきたいと思います。
まずは、ag1 側の設定を行うために、以下のクエリを実行します。
CREATE DATABASE db1 BACKUP DATABASE db1 TO DISK=N'NUL' CREATE DATABASE db2 BACKUP DATABASE db2 TO DISK=N'NUL' CREATE AVAILABILITY GROUP [ag1] FOR DATABASE db1 REPLICA ON N'SQL-01' WITH (ENDPOINT_URL = N'TCP://SQL-01.cluster1.local:5022', FAILOVER_MODE = AUTOMATIC, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SECONDARY_ROLE(ALLOW_CONNECTIONS = NO), SEEDING_MODE = AUTOMATIC), N'SQL-02' WITH (ENDPOINT_URL = N'TCP://SQL-02.cluster1.local:5022', FAILOVER_MODE = AUTOMATIC, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SECONDARY_ROLE(ALLOW_CONNECTIONS = NO), SEEDING_MODE = AUTOMATIC); GO ALTER AVAILABILITY GROUP [ag1] ADD LISTENER N'SQL-LN-01' (WITH DHCP ON (N'10.0.0.0', N'255.0.0.0'), PORT=1433); GO :CONNECT SQL-02 ALTER AVAILABILITY GROUP [ag1] JOIN ALTER AVAILABILITY GROUP [ag1] GRANT CREATE ANY DATABASE GO
これについては、通常の可用性グループの作成と変わりません。
- db1 を可用性グループに追加
- リスナーとしては 1433 を使用
- データ同期のエンドポイントとしては 5022 を使用
という構成となっています。
Direct seeding を使用していますので、上記のような構文を実行すれば、SQL-02 側でも DB が作成された状態となります。
次に、ag2 を設定するために、対向のクラスターで以下のクエリを実行します。
CREATE AVAILABILITY GROUP [ag2] FOR REPLICA ON N'SQL-03' WITH (ENDPOINT_URL = N'TCP://SQL-03.cluster2.local:5022', FAILOVER_MODE = AUTOMATIC, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL), SEEDING_MODE = AUTOMATIC), N'SQL-04' WITH (ENDPOINT_URL = N'TCP://SQL-04.cluster2.local:5022', FAILOVER_MODE = AUTOMATIC, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL), SEEDING_MODE = AUTOMATIC); GO ALTER AVAILABILITY GROUP [ag2] ADD LISTENER N'SQL-LN-02' (WITH DHCP ON (N'10.0.0.0', N'255.0.0.0'), PORT=1433); GO :CONNECT SQL-04 ALTER AVAILABILITY GROUP [ag2] JOIN ALTER AVAILABILITY GROUP [ag2] GRANT CREATE ANY DATABASE GO
分散可用性グループを設定する場合、対向の可用性グループは DB を含めない状態にする必要があるようです。
そのため、ag2 に関しては空の可用性グループが作成された状態となります。
次に ag1 と ag2 間を、分散可用性グループで接続させます。
まずは、ag1 側のプライマリサーバーで以下のクエリを実行します。
分散可用性データベースの制限として、以下の内容があるため、自動フェールオーバーは、設定することができません。
Automatic failover to the secondary availability group is not supported.
CREATE AVAILABILITY GROUP [distributedag] ?? WITH (DISTRIBUTED) ?? AVAILABILITY GROUP ON ??????'ag1' WITH ???( ???????? LISTENER_URL = 'tcp://SQL-LN-01.cluster1.local:5022', ???????? ?AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, ???????? FAILOVER_MODE = MANUAL, ???????? SEEDING_MODE = AUTOMATIC ????? ), ????? 'ag2' WITH ??????( ???????? LISTENER_URL = 'tcp://SQL-LN-02.cluster2.local:5022', ???????? AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, ???????? FAILOVER_MODE = MANUAL, ???????? SEEDING_MODE = AUTOMATIC ????? ); GO
これで、ag1 側で、分散可用性グループが作成された状態となります。
分散可用性グループは、可用性グループ間を保護するものとなるため、設定の中身に可用性データベースやリスナーは含まれていません。
設定のポイントとしては、
- LISTENER_URL = ‘tcp://SQL-LN-01.cluster1.local:5022’
- LISTENER_URL = ‘tcp://SQL-LN-02.cluster2.local:5022’
となっていることでしょうか。
分散可用性グループは、「可用性グループと可用性グループを接続する」ものとなりますので、接続先としては、可用性グループ内のサーバーではなく、可用性グループのリスナーを指定することになります。
また、指定時のポートですが、リスナーの接続ポートではなく、エンドポイントのポートを指定する必要があります。
これは、リスナーを使用する目的が「SQL Server の接続」ではなく、「データの同期」を行うためになるからかと。
リスナーを指定することで、対向の可用性グループのプライマリに自動的に接続できますので、ここで設定している内容はデータ同期先の設定として認識しておくとよさそうです。
ここまでの状態で、ag1 側の設定は完了なのですが、ag2 側には分散可用性グループの設定はまだ反映されていない状態となります。
そのため、ag2 のプライマリのサーバーで以下を実行し、分散可用性グループに参加をさせます。
ALTER AVAILABILITY GROUP [distributedag] ?? JOIN ?? AVAILABILITY GROUP ON ??????'ag1' WITH ???( ???????? LISTENER_URL = 'tcp://SQL-LN-01.cluster1.local:5022', ?????????AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, ???????? FAILOVER_MODE = MANUAL, ???????? SEEDING_MODE = AUTOMATIC ????? ), ????? 'ag2' WITH ??????( ???????? LISTENER_URL = 'tcp://SQL-LN-02.cluster2.local:5022', ???????? AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, ???????? FAILOVER_MODE = MANUAL, ???????? SEEDING_MODE = AUTOMATIC ????? ); GO
これで、ag2 側でも分散可用性グループが設定され、DB の復元も自動的に行われた状態となります。
# Direct seeding の仕組みが使用されているのかと思います。Direct seeding を無効にしていても動作するのかまでは検証できていません。
分散可用性グループについての基本的な動作としては以下のようになるようです。
- それぞれの可用性グループのプライマリ側でのみ設定された状態となる
# セカンダリ側では表示されず、フェールオーバーしプライマリに昇格すると表示が行われる。 - 分散可用性グループのセカンダリになっている環境では、データベースは読み取りとなる
- 分散可用性グループの切り替えについては手動で実施する
Basic Availability Groups (AlwaysOn Availability Groups) で、使えるかどうかがわからないのですが、製品版が出たタイミングで確認はしてみたいですね。
# Standard Edition の AlwaysOn のドキュメントに、制限としてリスナーが作成できないというのが書かれておらず、CTP でリスナーが作成できなかった制限が緩和されるのかについてもよくわかっていないのですよね。現状の RC は Enterprise Evaluation のため、Standard の可用性グループが作成できず、実装が確認できないのですよね。
SQL Server 2016 の AlwaysOn、いろいろと機能が追加されていますので、製品版がリリースされたタイミングで情報を整理しないとと思いました。