详细介绍参照官网详细文档,我就不在这里赘述了:
https://learn.microsoft.com/zh-cn/sql/database-engine/availability-groups/windows/overview-of-always-on-availability-groups-sql-server?view=sql-server-ver16
下图显示的是一个包含一个主要副本和四个次要副本的可用性组。支持最多八个次要副本,包括一个主要副本和四个同步提交次要副本。
为了部署方便,我以接下来的部署中,关闭了所有服务器的windows主机防火墙。
开始菜单—>管理工具—>高级安全 Windows 防火墙。右键属性。
关闭包括“域配置文件”、“专用置文件”、“公用置文件”中的防火墙设置。
如果是安全要求较高的生产环境,注意打开防火墙配置,并配置打开域间通通讯策略,具体开放端口参照微软官方文档:
https://learn.microsoft.com/zh-cn/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd772723(v=ws.10)?redirectedfrom=MSDN
准备基础环境
1、操作系统Windows均为Windows server 2012R2标准版
2、数据库版本为sql server 2016 企业版本
3、各节点基本 配置如下表:
AD域 控制器/DNS |
SQL节点1 |
SQL节点2 |
SQL节点3 |
|
硬件配置 |
4VCPU 8G内存 80G磁盘 1块网卡 |
4VCPU 16G内存 300G磁盘 2块网卡 |
4VCPU 16G内存 300G磁盘 2块网卡 |
4VCPU 16G内存 300G磁盘 2块网卡 |
主机IP |
192.168.0.111 |
192.168.0.112 1.1.1.112 |
192.168.0.113 1.1.1.113 |
192.168.0.114 1.1.1.114 |
主机网关 |
192.168.0.1 |
192.168.0.1 |
192.168.0.1 |
192.168.0.1 |
主机DNS |
192.168.0.111 |
192.168.0.111 |
192.168.0.111 |
192.168.0.111 |
CLUSER-VIP |
192.168.0.200 |
|||
Sql 监听器IP |
192.168.0.202 |
4、分别到每台主机上执行whoadmi /user确认SID值。
注意4台主机的用户SID不能一样(虚拟化中克隆主机SID可能相同),因为要加域环境,如果都是克隆的同一台虚拟机需要手动sysprep修改下SID,修改方法进入c:\windows\system32\sysprep目录下运行sysprep.exe修改一下(需要重启主机)。
部署流程图
在192.168.0.111主机运行服务器管理器,选择本地服务器、管理、添加角色和功能
安装完成后,点击下图“将此服务器提升为域控制器”
安装完毕后,主机会自动重启。
之后登录需要使用[email protected]做为用户名
配置私有IP的做为心跳网络的网卡,取消DNS注册,并禁用netbios
测评ping域名sqlnet是否可以正常解析
可以的话,进行加域
输入192.168.0.111的主机域管理员密码进行验证
加域成功后,需要重启服务器。
重复以上操作,分别把3个节点都加入到域环境。
说明一下,SQLserver2016的安装DVD包里没有管理工具,需要单独下载安装。
https://learn.microsoft.com/zh-cn/sql/ssms/download-sql-server-management-studio-ssms?redirectedfrom=MSDN&view=sql-server-ver16
另外需要.net安装包
https://support.microsoft.com/zh-cn/topic/%E9%80%82%E7%94%A8%E4%BA%8E-windows-%E7%9A%84-microsoft-net-framework-4-8-%E8%84%B1%E6%9C%BA%E5%AE%89%E8%A3%85%E7%A8%8B%E5%BA%8F-9d23f658-3b97-68ab-d013-aa3c3e7495e0
数据库服务器安装部分内容如下:
使用域管理员[email protected]登录服务器,进行安装
安装需要在各个节点进行安装,域控服务器不需要安装。
打开windows窗口管理工具故障转移群集管理器
输入3个节点名称
测试无错误即可,对于相关的报警可以行查看。
查看sql01节点己启动CLUSTERVIP
继续为集群添加仲裁见证,这里采用共享文件夹的方式来进行,共享文件夹创建在域控制器主机中。
在192.168.0.111主机C盘创建votedisk目录,右键属性
在192.168.0.112 SQL01主机上,打开故障转移集群,右键集群,更多操作,配置集群仲裁设置
运行SQL配置管理器
勾选启动alwayson
之后重启sqlserver服务生效。依次修改其它节点。
修改之后连上各个数据库节点,右键属性,查看HADR是否为true。
在sql01主机上创建备份目录,并共享该目录,对现有数据库进行备份。
任务-备份
先删除默认的备份位置,再添加
新建可用性组向导
添加监听器
配置完成后查看sql01节点增加监听IP
监听器读写默认只连接到主副本,
要想实现读写分离,需要配置客户端连接串时写applicatiopn=readonly
同时配置只读路由,监听器会根据配置转发到只读副本
官方文档描述:
https://learn.microsoft.com/zh-cn/sql/database-engine/availability-groups/windows/about-client-connection-access-to-availability-replicas-sql-server?view=sql-server-ver16
以下摘取自原文:
默认情况下,可用性组侦听器将传入连接定向到主副本。不过,您可以对可用性组进行配置以便支持只读路由,这使其可用性组侦听器能够将读意向应用程序的连接请求重定向到可读取的辅助副本。
在故障转移期间,辅助副本转换为主角色,以前的主副本转换为辅助角色。在故障转移过程中,所有到主副本或辅助副本的客户端连接都将终止。故障转移之后,在将客户端重新连接到可用性组侦听器时,侦听器将客户端重新连接到新的主副本,只有读意向连接请求除外。如果在承载新的主副本以及至少一个可读取辅助副本的客户端和服务器实例上配置了只读路由,则读意向连接请求将被重新路由到支持客户端要求的连接访问类型的辅助副本。若要确保在故障转移之后获得良好的客户端体验,务必为每个可用性副本的辅助角色和主角色配置连接访问。
连接访问配置如何影响客户端连接:
副本的连接访问设置决定连接尝试是失败还是成功。下表简要说明对于每个连接访问设置,给定连接尝试是失败还是成功。
副本角色 |
副本上支持的连接访问 |
连接意向 |
连接尝试结果 |
---|---|---|---|
辅助副本 |
全部 |
指定了读意向、读写意向或未指定连接意向 |
成功 |
辅助副本 |
无(这是默认辅助行为。) |
指定了读意向、读写意向或未指定连接意向 |
失败 |
辅助副本 |
仅限读意向 |
读意向 |
成功 |
辅助副本 |
仅限读意向 |
指定了读写意向或未指定连接意向 |
失败 |
主要 |
所有(这是默认主要行为。) |
指定了只读意向、读写意向或未指定连接意向 |
成功 |
主要 |
读写 |
仅限读意向 |
失败 |
主要 |
读写 |
指定了读写意向或未指定连接意向 |
成功 |
针对客户端连接字符串的要求和建议
对于要使用只读路由的客户端应用程序,其连接字符串必须满足以下要求:
使用 TCP 协议。
将应用程序意向特性/属性设置为只读。
引用配置为支持只读路由的可用性组的侦听器。
引用该可用性组中的数据库。
此外,建议连接字符串启用多子网故障转移,这将支持每个子网上的每个副本的并行客户端线程。这将最大程度地减小故障转移后的客户端重新连接时间。
连接字符串的语法取决于应用程序正在使用的 SQL Server 提供程序。以下用于 SQL Server 的 .NET Framework 数据访问接口 4.0.2 的示例连接字符串说明了使用只读路由时所需的和建议的连接字符串的部分。
Server=tcp:MyAgListener,1433;Database=Db1;IntegratedSecurity=SSPI;ApplicationIntent=ReadOnly;MultiSubnetFailover=True
官方说法是默认SQL2016以前的版本只读第1条只读路由
SQL2016以后版本可以在括号内写多个路由,自动实现读负载均衡
官方文档描述:
https://learn.microsoft.com/zh-cn/sql/database-engine/availability-groups/windows/configure-read-only-routing-for-an-availability-group-sql-server?view=sql-server-ver16
以下摘取自原文:
从 SQL Server 2016 (13.x)开始,可以在一组只读副本间配置负载平衡。以前,只读路由始终都将流量定向到路由列表中第一个可用的副本。若要利用此功能,请使用一个级别的嵌套括号将 CREATE AVAILABILITY GROUP 或 ALTER AVAILABILITY GROUP 命令中的 READ_ONLY_ROUTING_LIST 服务器实例括起来。
例如,以下路由列表在两个只读副本 Server1 和 Server2之间的读意向连接请求实现负载平衡。括住这些服务器的嵌套圆括号可以标识已实现负载平衡的组。如果该组中没有副本,则它将继续尝试按顺序连接到只读路由列表中的其他副本:Server3 和 Server4。
READ_ONLY_ROUTING_LIST = (('Server1','Server2'), 'Server3', 'Server4')
请注意,路由列表中的每项本身也可以是一组负载平衡的只读副本。下面的示例演示这一操作。
READ_ONLY_ROUTING_LIST = (('Server1','Server2'), ('Server3', 'Server4', 'Server5'), 'Server6')
示例:
以下示例将修改现有可用性组 AG1 的两个可用性副本以支持只读路由(如果其中一个副本拥有主角色)。为了标识承载可用性副本的服务器实例,此示例指定了实例名称 COMPUTER01 和 COMPUTER02。
ALTER AVAILABILITY GROUP [AG1]
MODIFY REPLICA ON
N'COMPUTER01' WITH
(SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));
ALTER AVAILABILITY GROUP [AG1]
MODIFY REPLICA ON
N'COMPUTER01' WITH
(SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://COMPUTER01.contoso.com:1433'));
ALTER AVAILABILITY GROUP [AG1]
MODIFY REPLICA ON
N'COMPUTER02' WITH
(SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));
ALTER AVAILABILITY GROUP [AG1]
MODIFY REPLICA ON
N'COMPUTER02' WITH
(SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://COMPUTER02.contoso.com:1433'));
ALTER AVAILABILITY GROUP [AG1]
MODIFY REPLICA ON
N'COMPUTER01' WITH
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('COMPUTER02','COMPUTER01')));
ALTER AVAILABILITY GROUP [AG1]
MODIFY REPLICA ON
N'COMPUTER02' WITH
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('COMPUTER01','COMPUTER02')));
GO
①配置A副本的只读路由属性(ReadOnly代表‘只读意向’)
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N'WIN-14VNU7CGQO1' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));
②配置A副本的只读路由URL
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N'WIN-14VNU7CGQO1' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'tcp://WIN-14VNU7CGQO1.fnst.com:1433'));
③配置B副本的只读路由属性
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N'WIN-14VNU7CGQO2' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));
④配置B副本的只读路由URL
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N'WIN-14VNU7CGQO2' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'tcp://WIN-14VNU7CGQO2.fnst.com:1433'));
⑤配置A副本作为主副本时候的只读路由表
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N'WIN-14VNU7CGQO1' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('WIN-14VNU7CGQO2','WIN-14VNU7CGQO1')));
⑥配置B副本作为主副本时候的只读路由表
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N'WIN-14VNU7CGQO2' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('WIN-14VNU7CGQO1','WIN-14VNU7CGQO2')));
配置完成后,使用如下SQL查看路由表
SELECT * FROM sys.availability_read_only_routing_lists
确认一下应该是下面的形式 :
A B
A A
B A
B B
为什么这么配置请分析如下过程
1.正常运行时候,A作为主副本,B作为辅助副本,客户端连接字符串指定数据源是侦听器地址
2.此时发送只读请求
3.侦听器收到只读数据请求,有主副本A来处理,主副本A发现是ReadOnly,就查询路由表,发现第一条符合,就把只读请求交给辅助副本B来处理
4.此时主副本A失效了,那么由AlwaysOn的高可用可知,会让辅助B作为了主副本,等原来的主副本A恢复之后,让A成为新的辅助副本(当然这些对客户端是透明的)
5.副本A恢复之后,再发送一条只读请求
6.此时侦听器使用主副本B来处理这个请求,如果不像上面的设置方法,就找不到B到A的路由,也就不能实现所谓的高可用
经过上面的12次测试连接监听器IP,进行一下总结:
No. |
主角色中的连接 |
可读辅助角色 |
客户端行为 |
读请求 |
写请求 |
1 |
允许所有 |
否 |
不设置ReadOnly |
主副本 |
主副本 |
2 |
允许所有 |
仅读意向 |
不设置ReadOnly |
主副本 |
主副本 |
3 |
允许所有 |
是 |
不设置ReadOnly |
主副本 |
主副本 |
4 |
允许所有 |
否 |
设置ReadOnly |
主副本 |
主副本 |
5 |
允许所有 |
仅读意向 |
设置ReadOnly |
辅助副本 |
异常 |
6 |
允许所有 |
是 |
设置ReadOnly |
辅助副本 |
异常 |
7 |
允许读写 |
否 |
不设置ReadOnly |
主副本 |
主副本 |
8 |
允许读写 |
仅读意向 |
不设置ReadOnly |
主副本 |
主副本 |
9 |
允许读写 |
是 |
不设置ReadOnly |
主副本 |
主副本 |
10 |
允许读写 |
否 |
设置ReadOnly |
异常 |
异常 |
11 |
允许读写 |
仅读意向 |
设置ReadOnly |
辅助副本 |
异常 |
12 |
允许读写 |
是 |
设置ReadOnly |
辅助副本 |
异常 |
结论一:客户端配置ApplicationIntent=ReadOnly;启用只读路由功能,所有的请求先交给辅助副本来处理
结论二:客户端不配置ApplicationIntent=ReadOnly;那么读和写请求处理,都是主副本进行处理的,如1、2、3、7、8、9
结论三:在4中,主副本处理只读请求先交给辅助路由,因为所有的辅助副本都是不可写的,所以再由自己来处理只读路由
在10中,所有的辅助副本都是不可写,但是主副本又不处理ReadOnly的请求,所以就异常了
官方链接:
https://learn.microsoft.com/zh-cn/sql/database-engine/availability-groups/windows/listeners-client-connectivity-application-failover?view=sql-server-ver16
连接到主要副本
在连接字符串中指定可用性组侦听器 DNS 名称,可连接到主要副本以进行读写访问。
例如,若要通过侦听器连接到 SQL Server Management Studio 中的主要副本,请在服务器名称字段中输入侦听器 DNS 名称:
在故障转移期间,当主要副本变化时,与侦听器的现有连接将会断开,新的连接将路由到新的主要副本。
下面是 ADO.NET 提供程序 (System.Data.SqlClient) 的基本连接字符串的一个示例:
Server=tcp: AGListener,1433;Database=MyDB;Integrated Security=SSPI
可以通过运行以下 Transact-SQL (T-SQL) 命令来验证当前通过侦听器连接到的副本:
SELECT @@SERVERNAME
例如,SQLVM1 是主要副本时:
仍可使用主要副本或次要副本的实例名称(而不使用可用性组侦听器)直接连接到 SQL Server 的实例。但是,这样就无法享受将新连接自动路由到当前新主要副本的好处。此外,还无法享受只读路由的好处,即让用 read-intent 指定的连接自动路由到可读次要副本。
连接到只读副本
“只读路由”是指将传入的侦听器连接自动路由到配置为允许只读工作负荷的可读次要副本 。
如果满足以下条件,则连接将自动路由到只读副本:
至少一个次要副本设置为只读访问,并且每个只读次要副本和主要副本都配置为支持只读路由。
连接字符串引用可用性组中涉及的数据库。替代方法是连接中使用的登录帐户将该数据库配置为其默认数据库。有关详细信息,请参阅此有关如何使用算法处理只读路由的文章。
连接字符串引用某一可用性组侦听器,并且将传入连接的应用程序意向设置为只读(例如,使用 ODBC 或 OLEDB 连接字符串或连接特性或属性中的 Application Intent=ReadOnly 关键字)。
在登录期间,应用程序意向属性存储在客户端的会话中,然后 SQL Server 实例将处理该意向,并按照可用性组的配置和辅助副本中目标数据库的当前读写状态来确定执行什么操作。
例如,若要使用 SQL Server Management Studio 连接到只读副本,请选择“连接到服务器”对话框上的“选项”,选择“附加连接参数”选项卡,然后在文本框中指定 ApplicationIntent=ReadOnly :
针对指定只读应用程序意向的 ADO.NET 访问接口 (System.Data.SqlClient) 的连接字符串的一个示例:
Server=tcp:AGListener;Database=AdventureWorks;Integrated Security=SSPI;ApplicationIntent=ReadOnly
有关详细信息,请参阅配置对可用性副本的只读访问 (SQL Server)
https://learn.microsoft.com/zh-cn/windows-server/failover-clustering/file-share-witness
https://learn.microsoft.com/zh-cn/sql/database-engine/availability-groups/windows/prereqs-restrictions-recommendations-always-on-availability?view=sql-server-ver16
https://blog.csdn.net/cxu123321/article/details/108714305
https://blog.51cto.com/jimshu/1420526
https://www.cnblogs.com/DannielZhang/p/6070611.html
https://blog.csdn.net/mu_sang/article/details/129820539#:~:text=SQL%20Server%20Always%20On%E7%89%B9%E6%80%A7%E6%94%AF%E6%8C%81%20%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB%20%EF%BC%8C%E8%BF%99%E6%98%AF%E4%B8%80%E7%A7%8D%20%E6%95%B0%E6%8D%AE%E5%BA%93%20%E8%B4%9F%E8%BD%BD%E5%88%86%E6%8B%85%E7%9A%84%E6%96%B9%E5%BC%8F%EF%BC%8C%E8%83%BD%E5%A4%9F%E4%BC%98%E5%8C%96,%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB%20%E5%B0%86%E8%AF%BB%E6%93%8D%E4%BD%9C%E5%92%8C%E5%86%99%E6%93%8D%E4%BD%9C%E5%88%86%E5%88%AB%E5%88%86%E9%85%8D%E5%88%B0%E4%B8%8D%E5%90%8C%E7%9A%84%20%E6%95%B0%E6%8D%AE%E5%BA%93%E6%9C%8D%E5%8A%A1%E5%99%A8%20%E4%B8%8A%EF%BC%8C%E4%BB%8E%E8%80%8C%E9%99%8D%E4%BD%8E%E4%BA%86%E6%AF%8F%E4%B8%AA%20%E6%95%B0%E6%8D%AE%E5%BA%93%E6%9C%8D%E5%8A%A1%E5%99%A8%20%E7%9A%84%E8%B4%9F%E8%BD%BD%E5%92%8C%E5%8E%8B%E5%8A%9B%EF%BC%8C%E6%8F%90%E9%AB%98%E4%BA%86%E6%95%B4%E4%B8%AA%20%E6%95%B0%E6%8D%AE%E5%BA%93%20%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%93%8D%E5%BA%94%E9%80%9F%E5%BA%A6%E3%80%82