AlwaysOn Group Listener


 

1.Listener是什么

Listener實際上是一個 VirtualNetworkName,客戶端通過這個VNN來連接的具體的sqlserver實例 .Listener包含了DNS名稱,portIPaddress

當客戶端通過Listener進行連接時,Listener會將請求自動導向到PrimaryReplica或者SecondaryReplica了。

 

 

SQL Server Management Studio對應的記錄

   

對應的VCO記錄

 

 

對應的DNS記錄

 

下面是一個ADO.NET的連接字符串Server=AgListener;Initial Catalog=agdb1;Integrated Security=SSPI;

在這個連接字符串中指定了要連接的Listener名稱,這樣客戶端就會自動連接到primaryreplica了。如果發生了failover,在新的primaryreplica上線后,listener會自動將連接導向到新的primaryreplica,無需人為的干預。

 

2.負載平衡

SecondaryReplica可以配置成readonly模式,這樣就可以將一些只讀的工作放置到secondaryreplica中進行(例如報表),這樣就可以實現一定程度的負載平衡。並且Listener可以將這些只讀的連接自動導向到SecondaryReplica

要實現這一功能,需要在SQLServer端和客戶端同時進行一些配置。

SQL Server端

1)Secondary replica要配置成read-intent only或者Yes

 

2)設置READ_ONLY_ROUTING_URL

 

下面是一個的READ_ONLY_ROUTING_URL的例子。 語句里指定了每個replica使用的端口,這里的端口號需要根據實際instance使用的端口號進行相應調整

alter availability group ag modify replica on 'SQL108W2K8R21' with (secondary_role(read_only_routing_url='tcp://SQL108W2K8R21.259442DOM.COM:1433'))

alter availability group ag modify replica on 'SQL108W2K8R22' with (secondary_role(read_only_routing_url='tcp://SQL108W2K8R22.259442DOM.COM:1433'))

alter availability group ag modify replica on 'SQL108W2K8R23' with (secondary_role(read_only_routing_url='tcp://SQL108W2K8R23.259442DOM.COM:1433'))

    

3) READ_ONLY_ROUTING_LIST

為三個replica分別設置readonly routing的順序。以SQL108W2K8R21為例,當SQL108W2K8R21成為Primary replica時,readonly routing的順序依次為SQL108W2K8R22->SQL108W2K8R23-> SQL108W2K8R21. Listener會將客戶端的請求導向到SQL108W2K8R22,如果SQL108W2K8R22不可用,導向到SQL108W2K8R23,以此類推。

 

alter availability group ag MODIFY REPLICA ON N'SQL108W2K8R21' WITH (PRIMARY_ROLE(READ_ONLY_ROUTING_LIST=(N'SQL108W2K8R22', N'SQL108W2K8R23', N'SQL108W2K8R21')))

alter availability group ag MODIFY REPLICA ON N'SQL108W2K8R22' WITH (PRIMARY_ROLE(READ_ONLY_ROUTING_LIST=(N'SQL108W2K8R21', N'SQL108W2K8R23', N'SQL108W2K8R22')))

alter availability group ag MODIFY REPLICA ON N'SQL108W2K8R23' WITH (PRIMARY_ROLE(READ_ONLY_ROUTING_LIST=(N'SQL108W2K8R21', N'SQL108W2K8R22', N'SQL108W2K8R23')))

 

 

客戶端的設置

 

需要在連接字符串內指定ApplicationIntent=Readonly 並且將database指定為AG內的數據庫

例如:

Server=AgListener;database=agdb1;Integrated Security=SSPI;ApplicationIntent=Readonly

 

 

3.Multiple Listener

默認情況下,一個Ag只支持一個listener,當嘗試創建第二個listener時會返回19477錯誤:

The availability group '%.*ls' already has a listener with DNS name '%.*ls'. Availability groups can have only one listener. Use the existing listener, or drop the existing listener and create a new one.

 

但實際上我們可以通過下面的方式為AG創建多個Listener

1)打開Failover Cluster Manager,右鍵ag->Add a resource->Client Access Point

 

2)填寫Listener名稱

 

3)右鍵為其分配IPAddress

 

4) 右鍵ag resource property,設置dependency. 將agListener2添加到Dependencies

 

5)為Listener分配port,此時portnull

select *from sys.availability_group_listeners

執行下面的語句創建port

alter availability group [ag]

modify listener 'agListener2'

(port = 1433)

 

7)新的Listener就可以使用了,我們在SSMS里也可以找到相應的記錄

 

 

4.MultiSubnetFailover

SQLServer2012開始支持Multi Site SQL Cluster。 一般而言,多個數據中心分布在不同的地理位置,例如在上海和北京分別建立了數據中心,這樣當一個數據中心出現故障后(例如地震等災害),備用的數據中心可以繼續提供服務

下面是一個多子網的Listener截圖

在多子網環境中,一個Listener下會注冊多個IP Address(之間為OR關系),但只有primary replica所在子網的IP是處於Online狀態的,其余的均為Offline。如果發生failover,這些IPAddress的狀態會依據對應的replica的角色發生變化。

 

那么多子網環境會對Listener有什么影響呢?

首先要介紹一下RegisterAllProvidersIP屬性。如果值為1,那么Listener對應的DNS就會出現同名的多條記錄,每個記錄地應一個IP Address

 

如果RegisterAllProvidersIP的值為0,那么只會存在一條DNS記錄,也就是Primary replica所在子網的IP。

 

如果存在多條重名的DNS(RegisterAllProvidersIP=1)記錄,客戶端會依次請求這些IP Address,如果得到的IP是offline的,那么會繼續請求一下條記錄.這樣就增加了連接時間,您的應用也可能會出現連接問題。

為了解決這個問題,ADO.NET(.NET 3.5.1)引入了MultiSubnetFailover關鍵字,如果MultiSubnetFailover

為True,那么客戶端會同時嘗試連接所有子網的IPAddress使用最先響應的那個IP地址來作為最終使用的地址,這樣就極大地縮短了連接時間.

 

如果RegisterAllProvidersIP=0,那只有PrimaryReplica子網下的IP會注冊到DNS,當failover發生時,新的primaryreplica子網下的listenerIP會代替之前的IP。這樣就避免的之前的情況。

但在實際環境中,我們還需要考慮DNS的TTL值(Time-To-Live),TTL默認值是1200秒。也就是說當failover發生后,失效的DNS記錄要在客戶端可能要保持20分鍾才會失效,在此期間,客戶端無法通過listener進行連接。

當然我們可以手工執行ipconfig /flushdns才更新記錄,但這樣畢竟需要人工介入。

或者縮短TTL,但TTL值越小,DNSServer的性能消耗就嚴重。需要權衡兩者。微軟的建議值是300秒(5分鍾).

 

1 OR 0

那么是什么時候應當將RegisterAllProvidersIP這是為1,而什么時候為0呢? 如果您的客戶端支持MultiSubnetFailover關鍵字,那么建議設置成1,並且在連接字符串將MultiSubnetFailover設置為true.

如果客戶端不支持MultiSubnetFailover關鍵字,那么就設置成0,並修改TTL300

 

更多信息

===

如果Listener使用過T-SQL語句或者SSMS創建的,RegisterAllProvidersIP為1

如果是通過ClusterFailovermanager創建的, RegisterAllProvidersIP為0

 

可以通過powershell修改RegisterAllProvidersIP的值

Get-ClusterResource "SQL Network Name (SQLMULTISUBCLUS)" | Set-ClusterParameter RegisterAllProvidersIP 1/0

 

 

update 20190104

===

starting from SQL Server 2016, it supports loadbalance readonly feature

https://blogs.msdn.microsoft.com/alwaysonpro/2016/05/02/sql-server-2016-alwayson-availability-group-enhancements-load-balance-read-only-routing/

 

alter availability group pubag modify replica on 'liweiy744VM\sql17' with (secondary_role(read_only_routing_url='tcp://liweiy744VM.liweiyin1.lab:58896')) 
alter availability group pubag modify replica on 'liweiy745VM\sql17' with (secondary_role(read_only_routing_url='tcp://liweiy745VM.liweiyin1.lab:58896')) 
alter availability group pubag modify replica on 'liweiy746VM\sql17' with (secondary_role(read_only_routing_url='tcp://liweiy746VM.liweiyin1.lab:58896')) 
alter availability group pubag modify replica on 'liweiy747VM\sql17' with (secondary_role(read_only_routing_url='tcp://liweiy747VM.liweiyin1.lab:58896')) 

     


alter availability group pubag MODIFY REPLICA ON N'liweiy744VM\sql17' WITH (PRIMARY_ROLE(READ_ONLY_ROUTING_LIST=((N'liweiy745VM\sql17', N'liweiy746VM\sql17', N'liweiy747VM\sql17'),'liweiy744VM\sql17'))) 
alter availability group pubag MODIFY REPLICA ON N'liweiy745VM\sql17' WITH (PRIMARY_ROLE(READ_ONLY_ROUTING_LIST=((N'liweiy746VM\sql17', N'liweiy747VM\sql17',N'liweiy744VM\sql17'),'liweiy745VM\sql17'))) 
alter availability group pubag MODIFY REPLICA ON N'liweiy746VM\sql17' WITH (PRIMARY_ROLE(READ_ONLY_ROUTING_LIST=((N'liweiy744VM\sql17', N'liweiy745VM\sql17', N'liweiy747VM\sql17'),'liweiy746VM\sql17'))) 
alter availability group pubag MODIFY REPLICA ON N'liweiy747VM\sql17' WITH (PRIMARY_ROLE(READ_ONLY_ROUTING_LIST=((N'liweiy744VM\sql17', N'liweiy745VM\sql17', N'liweiy746VM\sql17'),'liweiy747VM\sql17'))) 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM