Bu makalede Multi-Subnet Cluster yapısını detaylı bir şekilde görmüş olacağız. Gerçek sistem üzerinde nasıl aksiyonlar alınması gerektiğini uygulamalı bir şekilde göstermiş olacağız. Multi subnet Cluster yapısı farklı network’lerde olan sunucuların aynı cluster içerisine alınması işlemidir. Aynı lokasyonda veya başka bir lokasyonda cluster içerisine alınan sunucuların tek bir cluster içerisine eklenmesi işlemidir. Bu olay Disaster Recovery olarak karşımıza çıkmaktadır.
Aşağıdaki resimde Multi-Subnet Cluster yapısını görmekteyiz.

Multi-Subnet Cluster default olarak RegisterAllProvidersIP’ı enable eder. Offline ve online IP adresleri DNS’e kaydedilir. Uygulama kaydedilmiş bütün IP adreslerini dns server’dan alır ve sırayla bağlanmaya çalışır. Mevcut Cluster yapımıza farklı networkten bir Node eklenirse RegisterAllProvidersIP 1 olur. Genellikle windows sunucularında best practice olarak RegisterAllProvidersIP 1 görünür.
Kullanıcı Connection string’inde MultiSubNetFailover= True ifadesi yoksa ve RegisterAllProvidersIP 1 ise bağlantı sağlayan ortam veya kullanıcı sırasıyla hangi ip DNS sunucusunda sıralama olarak öndeyse ona bağlanmaya çalışır. Çünkü son kullanıcının bağlantı sağladığı listener yapısı altında farklı subnetlerde ip adresleri bulunmaktadır. Load balancer kullanılan ortamlarda son kullanıcının ip çözümlemesi için Dns sunucularına bağlanıp Listener ip adresini öğrenmeye çalıştığında hangi dns sunucusunda ip ilk sıradaysa ona bağlanmaya çalışır. Load balancer arkasında birden fazla dns sunucusu olabilir. MultiSubNetFailover= True ifadesi yoksa 2. sırada bulunan ip adresine bağlanmaya çalışmaz. Offline olan ip yapısını alırsa son kullanıcı bağlantı hatası almaktadır. Kısacası online olan veya offline olan ip adresi gelebilir. Rastgele olan bir işlemdir. Son kullanıcının connection string’inde MultiSubNetFailover yapısı yoksa ve cluster altında farklı networklerde node’lar bulunması dahilinde son kullanıcı tesadüfen online ve offline ip’lere bağlantı sağlamaktadır.
Yukarıdaki resimde görüldüğü gibi kullanıcıların connection string’inde MultiSubNetFailover= True değerini yazılması gerekmektedir. Kullanıcılar bu parametreyle bağlanmaya çalıştığında dns serverdan kaydedilmiş olan ip değerlerini okur. Sırasıyla bağlanmaya çalışır. Makalenin sonunda set ettiğimiz TTL değeri ile dns sunucusundan güncellenen ip değerlerini öğrenmektedir.
RegisterAllProvidersIP değerine nasıl bakıldığını ne gibi ayarlar yapıldığını görelim.
Windows PowerShell yönetici olarak çalıştırılır. İlk olarak sunucu üzerinde PowerShell’i açarak Get-ClusterResource komutunu çalıştırıyoruz. Aşağıda ekran görüntüsünü görebilirsiniz. Gerçek sistemde Multi Subnet yapılarında IP adress kısmında AG’ye bağlı ikinci bir ip adresi gözükür. Listener altına iki ip değeri set ettiğimiz içindir.
Get-ClusterResource komutu ile gelen ekranda 2. olarak görülen ip availability group üzerinde listener’a vermiş olduğum ikinci ip değeridir.
Get-ClusterResource

Failover cluster ekranında eklenen listener ip adresini görmek için aşağıdaki bölümden görülmektedir. Role bölümünden ilgili role(Availability Group) seçildikten sonra alt kısımda bulunan Server Name kısmında bulunan listener(SQLCLSTST) isminin altından görülebilir.

SSMS arayüzünden ilgili Availability Group’umuzun listener altında bulunan ip adreslerimiz.

PowerShell üzerinden Availability Group ve listener üzerindeki parametreleri göreceğimiz komut ise aşağıda belirtilmiştir. Tırnak içerisine AG ismimiz ve alt tireden sonra listener ismimizin yazılması gerekmektedir.
Get-ClusterResource "SQLTSTCLSAG_SQLCLSTST" | Get-ClusterParameter
Yukarıdaki komut sonucunda hata mesajı alıyorsanız sadece listener ismimizi yazarakta aynı sonucu elde etmiş olursunuz.
Get-ClusterResource "SQLCLSTST" | Get-ClusterParameter

Gelen ekranda RegisterAllProvidersIP kısmından değerini görebilirsiniz. 1 değeri aktif olduğunu göstermektedir. Farklı subnetlerde cluster üzerinde node’larım bulunmasından dolayı değerini 1 olduğunu görmüş oluyoruz.
Yukarıda bulunan RegisterAllProvidersIP değerinde sıkıntı yaşamamak için son kullanıcının connection string’inde MultiSubNetFailover= True ifadesinin olması gerekmektedir. Bu özellik yapılmaz ise son kullanıcının Rastgele aktif veya pasif network adreslerine bağlanmasına sebep olacaktır. Multi subnet yapısı gereği listener altında 2 ip’miz bulunmaktadır.
Şimdi test işlemlerimize başlayalım:
RegisterAllProvidersIP değerimiz 1 iken Always on yapımız farklı bir subnet ortamına failover olursa kullanıcıların hangi network adresini göreceğini görelim. Son olarak listener altında görülen ip adreslerimizi görelim.

SSMS arayüzünde ilgili Availability group’un resmini görmekteyiz.

Failover yapılmadan önce nslookup’a listener üzerinde hangi ip’lerin aktif olduğunu görmüş olalım. Aşağıdaki komut ile kontrol işlemi yapıyoruz. Daha sonra listener ismimizin yazılması gerekmektedir.
nslookup
Gelen sonuç incelendiğinde listener altında olan iki ip değerimizin döndüğü görülmektedir. 10.202.0.56 ip bloğumuz yukarıdaki resimde Offline olduğu görülmektedir. Dns sunucuları Online olan ilk ip adresini almaktadır. Eğer 10.202 bloklu ip ilk sırada olsaydı son kullanıcılar bağlantı sağlayamayacaktı.
Not: NET10 dns sunucumuzu göstermektedir. Farklı dns sunucularında farklı sırada ip değerleri alabilirsiniz.

10.202.0.56 bloklu farklı bir subnette olan sunucumuza failover işlemi gerçekleştirelim. Disaster Recovery işlemi gerçekleştirilir.

Failover işlemi gerçekleştikten sonra cluster üzerinde kontrol yaptığımızda yeni ip değerinin set edildiğini görmüş oluyoruz.

Powershell üzerinden tekrardan nslookup çekildiğinde iki ip değerimizin görüldüğü ilk ip değerinin sıralamada öncelikle olması son kullanıcının Offline olan ip adresine bağlanmasına sebep olacaktır. Kullanıcının Connection String’inde MultiSubNetFailover olmaması 10.202.0.56 ip bloğunun denenmemesine sebep olacaktır. Sadece ilk ip adresi alınır. İster aktif olsun ister pasif olsun. Son kullanıcının sorunsuz bağlanması için Connection String’inde MultiSubNetFailover= True yapılması aşağıdaki resimde görülen iki ip değerine sırasıyla bağlanmasına sebep olacaktır. Hangisi Online ise ona bağlanır.
Eğer Connection string’inde MultiSubNetFailover ifadesi yoksa kapalı olan 10.3.0.185 bloğa bağlanmaya çalışacaktır.

Yukarıda belirtilen sorunlarla karşılaşmamak için veritabanına bağlanan tüm uygulama sunucuları connection string’lerini bu yapıya dönüştürene kadar RegisterAllProvidersIP değerinin 0 değerinin set edilmesi daha pratik bir çözüm olacaktır. Bu değerinin 0’a set edilmesi listener altında 2 ip adresi set edilse de sadece Online olan ip adresi görülmektedir. Bu değerler veritabanı sunucuları üzerinde set edilmesi gerekmektedir.
Aşağıdaki komutlarla bu RegisterAllProvidersIP değeri 0 değerine set edilir.
Get-ClusterResource "SQLTSTCLSAG_SQLCLSTST" | Set-ClusterParameter RegisterAllProvidersIP 0
Get-ClusterResource "SQLCLSTST" | Set-ClusterParameter RegisterAllProvidersIP 0
Yukarıdaki komutlarla bu değer 0’a set edilmiş olur.

İlgili değer set edildikten sonra listener yapımızın start stop işleminin yapılması gerekmektedir. Uyarı olarak bizlere listener yapımızı start stop yapmamız gerektiğini söylemektedir.

Powershell üzerinden start stop yapılması gerekmektedir.
Stop-ClusterResource "SQLCLSTST"
Start-ClusterResource "SQLCLSTST"

Yukarıdaki komutlarla yapmayıp Failover Cluster ekranında Ag altında bulunan listener seçilip Stop-Start yapılabilir.

Yukarıda yapmış olduğumuz start-stop işlemlerinden sonra ilgili AG yapımız resolving moduna düşer. Failover cluster üzerinde ilgili role yapımız Start Role yapılması gerekmektedir.

RegisterAllProvidersIP değerini 0 yaptıktan sonra tekrardan nslookup komutu çalıştırdıktan sonra tek ip değerinin geldiğini görmüş oluyoruz. RegisterAllProvidersIP değerinin 0 olması sadece Online olan ip değerlerinin görülmesine sebep olacaktır. Buda Disaster Recovery işleminin sorunsuz bir şekilde yapılması demektedir.

RegisterAllProvidersIP değeri 0 iken tekrardan Failover işlemi yapıldığında failover olunan subnetteki network adresinin geldiği görülmüştür.

Failover cluster ekranında ip online ve offline ip değerleri görülmektedir.

İlgili bölümden de start stop yapılabilir. Start stop işleminden sonra AG yapımız resolving modundan çıkarılması gerekmektedir.

Bazen cluster yapımızda herhangi bir farklı networkten bir sunucu yani multi subnet yapısı olmamasına rağmen RegisterAllProvidersIP değerinin 1 olduğu görünüyor. Bunun sebebi sunucularımızın üzerinde AlwaysOn Availability Group yapımızın kurulu olması veya sunucu üzerinde default’ta açık gelmesidir.
Multi subnet yapısının olmaması RegisterAllProvidersIP değerinin 1 gözükmesi bazen cluster’ımızı validate ettiğimizde bize uyarı mesajının dönmesine sebep olabilir. Son kullanıcıların ise hata almasına sebep olacaktır. Eğer sistemimizde farklı network’da bir node yoksa bu değerin 0 yapılması gerekmektedir.
Validate Cluster yaptıktan sonra gelen sonucu göstermek için View Validation Report kısmına tıkladığımızda bize aşağıdaki hatayı veriyor.


Bu hatanın önüne geçmek için aşağıdaki RegisterAllProvidersIP değeri 0 olarak yapılması gerekmektedir. Bunun için aşağıdaki komutlar kullanılır.
“The RegisterAllProvidersIP property for network name ‘Name: ‘ is set to 1. For the current cluster configuration this value should be set to 0.”
RegisterAllProvidersIP 0 yapılması son kullanıcının dns sunucusunda sadece Online olan ip’adresini görmüş olacaktır. Yukarıda detaylı bir şekilde bahsetmiştik.
RegisterAllProvidersIP değeri aşağıdaki komutla 1 veya 0 yapılabilir.
Get-ClusterResource "SQLTSTCLSAG_SQLCLSTST" | Set-ClusterParameter RegisterAllProvidersIP 1
Get-ClusterResource "SQLTSTCLSAG_SQLCLSTST" | Set-ClusterParameter RegisterAllProvidersIP 0
Yukarıdaki komutun hata vermesi dahilinde aşağıdaki komutta olduğu gibi sadece Listener isminin belirtilmesi gerekmektedir.
Get-ClusterResource "SQLCLSTST" | Set-ClusterParameter RegisterAllProvidersIP 1
Get-ClusterResource "SQLCLSTST" | Set-ClusterParameter RegisterAllProvidersIP 0
İlgili değer set edildikten sonra listener yapımızın start stop işleminin yapılması gerekmektedir.

Start stop yapıldıktan sonra ilgili AG’miz resolving modunda olmaktadır. Failover cluster ekranında start etmemiz gerekmektedir.

Makelenin başında belirtilen TTL süresini açıklamak gerekirse: Sql serverın dns sunucundan sürekli bağlantı sağlayıp aktif olan listener ip değerini öğrenmek ister. Bu yapı aşağıdaki ilgili powershell scriptiyle gördüğümüz HostRecordTTL süresidir. Bu süre sql server’ın 1200 saniye bekledikten sonra DNS sunucusu üzerinden gerçek ip değerini öğrendiği yapı olarak karşımıza çıkmaktadır. Bu değerin gerçek sistemlerde 300 saniye olması önerilmektedir.
Şöyle dememiz daha iyi olur. Dns sunucusu bu süre zarfında her zaman aynı ip sonucunu döndürmektedir. Bu süre zarfından sonra yeni bir ip set edilmişse son kullanıcıya güncel ip değerini bu süre zarfından sonra dönmektedir. Minumum 60 saniye olarak ayarlanabilir. Buda sürekli dns üzerinde güncellemeye sebebiyet vereceği için performans anlamında bizlere sıkıntı verecektir. Çünkü sadece sizin ip adresiniz yok. Milyonlarca ip değerinin set edilmesi demektir.
Get-ClusterResource "SQLCLSTST" | Get-ClusterParameter

Get-ClusterResource "SQLCLSTST" | Set-ClusterParameter HostRecordTTL 300

Son kullanıcının güncel olan ip değerini set edilen 300 saniye boyunca güncel tutmasına sebep olacaktır..
Yukarıdaki senaryoları SSMS arayüzünden yaparak son kullanıcının Nasıl sorunlarla karşılaştığını görmüş olalım. Sunucu üzerinde yukarıda bahsedilen yapılarda nelerin aktif olduğunu Resimlerle teyit edelim.
10.3.0.185 ip yapısının Online olduğu görülmektedir.

RegisterAllProvidersIP değerinin 1 olduğu görülmektedir.

nslookup komutu ile Listener üzerinde bulunan ip adreslerini öğrenelim.

Son kullanıcı yukarıda resimlerde belirtilen durumlarda sql server bağlantısında herhangi bir sorun yaşamaz.
Failover işlemi gerçekleştirelim. 10.202.0.56 ip bloğunu failover işlemini gerçekleştirelim.

nslookup komutuyla hangi ip değerlerinin olduğunu ayrıca hangi ip bloğumuzun online olduğunu gözlemlemiş olalım.


SSMS arayüzünden ve ping üzerinden bağlantı gerçekleştirelim. Bağlantı işlemlerimizin başarısız olduğu gözlemlenmektedir.


SSMS arayüzünden MultiSubNetFailover= True yapıldığında bağlantımızın başarılı bir şekilde gerçekleştiği görülmektedir.


Başarılı bir şekilde bağlantı gerçekleştirmiş oluruz.

Not: Güncel ip değerlerini almak için ipconfig /flushdns yapılması gerekmektedir.
Bu makalede multi subnet yapısına bir nebzede olsa değinmiş olduk. Başka bir makalede görüşmek dileğiyle.
“Allah yolunda infak edin ve kendinizi kendi ellerinizle tehlikeye atmayın. İyilik edin. Şüphesiz Allah, iyilik edenleri sever.” Bakara Suresi, 195. Ayet