共计 4234 个字符,预计需要花费 11 分钟才能阅读完成。
1.Listener 是什么
Listener 实际上是一个 VirtualNetworkName, 客户端通过这个 VNN 来连接的具体的 sqlserver 实例 .Listener 包含了 DNS 名称,port和IPaddress。
当客户端通过 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, 此时port 为null
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 子网下的 listener 的IP会代替之前的 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,并修改 TTL 为300秒
更多信息
===
如果 Listener 使用过 T-SQL 语句或者 SSMS 创建的,RegisterAllProvidersIP为 1
如果是通过 ClusterFailovermanager 创建的, RegisterAllProvidersIP 为 0
可以通过 powershell 修改 RegisterAllProvidersIP 的值
Get-ClusterResource “SQL Network Name (SQLMULTISUBCLUS)” | Set-ClusterParameter RegisterAllProvidersIP 1/0
本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-01/139768.htm