在阿里云ECS上轻松实现无域控的SQL Server AlwaysOn可用性组
在阿里云ECS上轻松实现无域控的SQL Server AlwaysOn可用性组
前言
SQL Server AlwaysOn功能在SQL Server 2012版本就已经出来了,AlwaysOn 可用性组功能是一个提供替代数据库镜像的企业级方案的高可用性和灾难恢复解决方案,可最大程度地提高一组用户数据库对企业的可用性。从我的角度来看,这个功能提供的是革命性的改变,首先他实现了多个副本并且可读,非常方便实现读写分离方案,比起使用Database Mirroring +Relication实现读写分离在可用性和可靠性更胜一筹。SQL Server 2016之前的版本功能上会有些限制,但在2016这个版本出来后,使用更亲民,更遵循“客户第一”的价值。比如,可实现无域控部署,增加到9个可用副本。言归正传,看看如何在阿里云ECS实现无域控的AlwasyOn可用性组。 如果你对AlwaysOn感兴趣,可以参考这个联机帮助,全面介绍了相关技术。https://msdn.microsoft.com/zh-CN/library/hh510230.aspx
架构图
下图是在ECS实现的简单架构图,演示了一个典型的SQL Server AlwaysOn可用性组的软件解决方案,读者可以先大致阅读,稍后详细介绍:
核心组件概述
1.** 架构概述 **
这个图是一个2+3的高可用并具备灾备功能的解决方案,2是主备数据库副本,主备之间使用sync方式,也就是同步方式,这是为了保证数据库可用性组可以实现自动故障转移,自动故障转移的条件必须是同步复制模式,并且需要设置为可自动转移故障。3是只读副本,是async,也就是异步复制, 这是考虑到多个复制部分的性能。作为写数据,2个主备副本已经足够,其他副本都可以设置为异步复制,再者由于ECS部署侦听器存在访问问题,为了满足解决方案,也只允许两个同步副本。实际上,AlwaysOn可用性组最多也只能有3个同步副本,这足以证明微软其实挺在乎这个性能问题。
2.** VPC **
基于VPC是一个基本的网络环境要求,如果在经典网络下部署,因为没有私有IP可用,是会遇到很大问题的,如果在VPC下,这个问题就可以解决掉。因为部署AlwaysOn会产生2个Virtual IP,这两个IP一定要私有的,不能被占用,否则将会出现群集和侦听器无法正常工作,HA也无法正确切换。
3.** HAVIP **
为何需要HAVIP?目前在ECS部署AlwaysOn的同学都会遇到侦听器无法工作的问题,其原因是无法使用侦听器IP在非Primary节点访问数据库实例,这是阻止上云的一个难点,实际上这个与VPC的网络实现有关,因为无法解析ARP协议,而侦听器恰好走的是ARP协议。HAVIP是VPC下面一个主备高可用架构的HA解决方案,他提供了一种可能:可在主备之间无需切换IP,只需要用VIP访问实例。但是HA和心跳检查需要自己去实现,这恰好契合了AlwaysOn故障转移的检测诊断切换机制,HAVIP+AlwaysOn可解决由于侦听器无法工作的问题,只不过,只能有2个节点可以使用HAVIP,但这无关紧要,因为从上面的架构看很清楚,我们使用2个主备同步节点来实现写HA,3个异步只读副本实现读,也正好适合这种场景,当然只读副本可能有1个或者2个或者7个,但实现故障转移的节点数必须大于或者等于3的投票权(有域控的可以使用share folder来充当一个VOTE)。那么多个只读副本如何访问呢,请往下看。
4.** SLB **
SLB是解决只读节点而设定,如果你不需要SLB来自动分配权重或者实现负载均衡,也可以直连只读副本的IP地址。特别是在WEB应用,可能会这样来做,因为WEB部署是分布式的,那么不同WEB应用连接到不同的只读,当然是可以的。但是写就不可以这样做的,因为写入仅有一个副本,特地说明一下。
5.** EIP **
EIP是可要可不要的,如果你想在VPC外访问数据库实例,可以绑定一个EIP,绑定到HAVIP和ECS IP或者SLB上都是可以的,不过,建议不要使用EIP,在VPC访问是比较安全的。
6.** ECS **
ECS是最基本的容器,没有特殊的要求。
7.** Windows Cluster **
Windows Cluster是特殊的,因为是在无域控创建Cluster,很多操作不一样,甚至无DNS服务器。这是Windows Server 2016出现的新的特性,他的好处是不依赖域控的复杂性,但也会给AlwaysOn部署带来复杂性。域控不仅要考虑部署、HA问题,还需要考虑运维问题,所以是一件很麻烦的事。去掉域控的Windows Cluster功能虽然受限,但足够满足部署AlwaysOn条件。详细参见部署计划。
8.** AlwaysOn可用性组 **
AlwaysOn部署会采用SQL Server 2016, 这个版本才支持无域控部署,因此,差异在于有无域控,同时相应的节点安全认证方式会发生变化,需要使用安全证书相互认证,域控就相对简单,依赖域控的安全验证机制。这个体现在部署时的复杂度。另外一个不得不说的是侦听器,侦听器在VPC是无法正常工作的,因此需要使用HAVIP+SLB实现是只读分离。关于侦听器来访问数据库实例问题,实际上没有想象那么美好,首先如果是只读访问,在连接字符串上会有一个read only的OPTION,因此,你就认为读是一个字符串,写是一个字符串。跟HAVIP+SLB是一样的道理。很多人会误认为一个字符串搞定,那是不可能的。
部署计划
下列描述了部署基于Windows Server 2016+SQL Server 2016的无域控的环境,是Step By Step手把手方式,希望读者可以轻松实现。
1.** 前提条件**
1.1 硬件条件
容器ECS, CPU 建议4核以上,内存建议8G以上。ECS请选用SSD云盘挂载
1.2 软件条件
.NET Framework 4.0 及以上
Powershell 5.0 及以上
Windows Server 2016 64位数据中心版(中文,英文随意)
SQL Server 2016 64位企业版(一定要求企业版,标准版只能实现Basic Availability)
1.3 网络要求
这里特别指出,AlwaysOn不要求双网卡,有双网卡也不能做Windows Cluster与AlwaysOn网络连接分离,因为有客户要求双网卡,原因是做心跳什么的,这个是没有理由的。有双网卡能够冗余是比较好的,但不是用于心跳。可以看看微软官方文档:https://msdn.microsoft.com/zh-cn/library/ff878487.aspx
1.3 DEMO环境
.NET Framework 4.0
Powershell 5.1
Windows Server 2016 64位数据中心英文版
SQL Server 2016 64位英文企业版 + SP1
基于VPC的ECS
高性能SSD云盘
2.** 环境部署准备**
申请一个规格的ECS,注意建议内存8G以上,CPU 4 核以上,DEMO环境是2核CPU,4G内存。网络类型必须在专有网络(VPC)中。
3.** 修改主机名**
ECS的实例是从镜像生产出来的,因此有可能名称存在相同的问题,VPC一般不会出现,但为了保证绝对的安全性,请修改一个15个字符以内规则的主机名称,并马上重启主机。可手动修改,也可参考Powershell指令:
Rename-Computer -NewName "ServerName" -restart -force
4.** 安装SQL Server实例**
安装时,请注意设置合理的启动帐户,启动帐户可以是network service, 也可以是本地账户,但本地账户在每个ECS都需要设置为统一密码,建议直接使用network service,安装完成后,将 network service加入到SQL Server账户中,并且设置服务器角色为sysadmin。另外,每个ECS安装实例的至少用户数据库数据和日志文件路径保持完全一致,这是做AlwaysOn必须要求的,否则在后期创建数据库时会发生错误。建议所有安装的行为都保持一致,这是最佳实践。如何安装数据库你可以点击NETX STEP或者静默安装也可以的。
5.** 安装SQL Server management Studio **
这个建议必须安装,SSMS在SQL Server 2016已经独立出来安装,没有统一在引擎的安装介质中,需要单独下载的,安装SSMS的原因是有可能用到SQLPS(Powershell的SQL对象支持)
6.** 创建Windows统一账号 **
因为本方案中不会有域控,因此为了保证成功部署Windows Cluster,需要增加一个相同账户和相同密码的账户,并且将账户加入到administrators组中,当然,你可使用administrator,但建议不要使用这账户来作为统一密码。你可以手动创建,也是使用下列cmd指令:
net user Win_Account " xxxxxx" /add
net localgroup administrators Win_Account /add
WMIC.EXE Path Win32_UserAccount Where Name="Win_Account" Set PasswordExpires="FALSE"
7.** 禁用 UAC 远程限制 **
powershell指令:
new-itemproperty -path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name LocalAccountTokenFilterPolicy -Value 1
8.** 安装Windows Failover Cluster Feature **
这个是必须要安装的,基础结构。AlwaysOn必须生长在Windows Cluster上。
powershell指令:
Install-WindowsFeature –Name Failover-Clustering –IncludeManagementTools
9.** 更改Windows 主机的DNS后缀名称**
这个方案是未加入域控的,所以为了能够在Windows Cluster下成功运行,需要将主机名加入统一标识的后缀名。你可以通过UI修改,也可以通过powershell指令:
$ParentKeyPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
$DnsSuffix="aliyunrds.com"
New-ItemProperty -Path $ParentKeyPath -Name "NV Domain" -Value $DnsSuffix -PropertyType String
10.** 更改主机的静态IP**
严格讲,Windows Server 2008 开始,可以使用DHCP来配置,不过,建议还是使用静态IP来配置主机的网络连接。你可以使用UI配置,也可以使用Powershell指令,不过请检查一下DNS配置,需要再调整下,脚本请自行修改或者你手动去调整:
$IPType = "IPv4"
$Adapter = Get-NetAdapter | Where-Object {$_.Status -eq 'up' -and $_.name -ne 'loopback'}
$IpAddress=((($Adapter | Get-NetIPConfiguration).IPv4Address) | Where InterfaceAlias -ne "loopback").IPAddress
$PrefixLength=((($Adapter | Get-NetIPConfiguration).IPv4Address) | Where InterfaceAlias -ne "loopback").PrefixLength
$Gateway=((Get-NetIPConfiguration).Ipv4DefaultGateway).NextHop
If (($adapter | Get-NetIPConfiguration).IPv4Address.IPAddress)
{
$adapter | Remove-NetIPAddress -AddressFamily $IPType -Confirm:$false
}
If (($adapter | Get-NetIPConfiguration).Ipv4DefaultGateway)
{
$adapter | Remove-NetRoute -AddressFamily $IPType -Confirm:$false
}
# config static ip address
$Adapter | New-NetIPAddress -AddressFamily $IPType -PrefixLength $PrefixLength -IPAddress $IpAddress -DefaultGateway $Gateway
11.** 修改主机的host文件**
文件位于C:\Windows\System32\drivers\etc下的hosts,需要将每个主机的带有DNS后缀的名称与IP映射起来, 你可使用cmd命令完成:
copy C:\Windows\System32\drivers\etc\hosts C:\Windows\System32\drivers\etc\hosts_2017033141131
echo 172.16.18.247 iZbp1ehi2dopyqC.aliyunrds.com >> C:\Windows\System32\drivers\etc\hosts
echo 172.16.18.246 iZbp1ehi2dopyqZ.aliyunrds.com >> C:\Windows\System32\drivers\etc\hosts
echo 172.16.18.248 iZbp1ehi2dopyqA.aliyunrds.com >> C:\Windows\System32\drivers\etc\hosts
12.**创建Windows Cluster **
最新版本的Windows Server 2016是可以通过UI来创建群集的,但你也可以通过powershell命令来创建,创建时需要指定StaticAddress,这个IP是VPC里面的地址,注意不要占用:
New-Cluster –Name clus-aliyun0001 -Node iZbp1ehi2dopyqC.aliyunrds.com,iZbp1ehi2dopyqZ.aliyunrds.com,iZbp1ehi2dopyqA.aliyunrds.com -AdministrativeAccessPoint DNS -StaticAddress 172.16.18.101
13.**设置Windows Cluster 仲裁机制**
基于无域控的AlwaysOn可用性组只能通过多数节点或者基于微软云文件仲裁,那么在阿里云只能通过多数节点,所以你部署的Winodws Cluster至少要3个节点,如果4个节点时,需要将一个节点设置为没有投票权,如果你只需要两个数据库副本时,你可以用两个ECS组成AlwaysOn节点,另一个只加入到Windows Cluster中。
设置VOTE:
$node = “Always OnSrv1”
(Get-ClusterNode $node).NodeWeight = 0
设置无WITNESS:
Set-ClusterQuorum -NoWitness
设置多数节点仲裁(默认):
Set-ClusterQuorum –NodeMajority
14.**设置Windows Cluster 故障转移的次数间隔**
这个设置非常重要,特别是在你测试过程可能会发现,转移几次后,不能自动转移了,这是因为Windows Cluster对资源组的自动故障转移在某段时间是有限制的。需要将次数更改多一点,比如30次。
(Get-ClusterGroup "Cluster Group").FailoverThreshold = 30
15.**开启数据库的AlwaysOn 功能**
如图,你可以使用配置管理器配置,也可以用Powershell指令配置:
Import-Module SQLPS
Enable-SqlAlwaysOn -Path SQLSERVER:\SQL\LocalHost\Default -Force
16.**配置AlwaysOn的安全设置**
这个需要在所有实例证书创建后,相互拷贝到每个ECS目录下,然后再运行,比如有3个主机实例001/002/003。在001上,需要创建002,003备份出来的证书;那么在002,需要创建001,003;同理在003上,需要再创建001,002的证书。实例之间需要相互认证才可通信 。SQL语句:
--step1
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'xxxxxx'
CREATE CERTIFICATE cer_alwayson_001
WITH SUBJECT='alwayson 001 local certificate',
EXPIRY_DATE='9999-12-31'
EXEC xp_create_subdir 'C:\software\cerficates'
BACKUP CERTIFICATE cer_alwayson_001
TO FILE='C:\software\cerficates\cer_alwayson_001.cer'
CREATE ENDPOINT Endpoint_Mirroring
STATE = STARTED
AS TCP (LISTENER_PORT = 5022, LISTENER_IP = ALL)
FOR DATABASE_MIRRORING (AUTHENTICATION = CERTIFICATE cer_alwayson_001,
ENCRYPTION = REQUIRED ALGORITHM AES,
ROLE = ALL)
--step2:
CREATE LOGIN alwayson_user
WITH PASSWORD='xxxxxx',
CHECK_POLICY=OFF
USE MASTER
GO
CREATE USER alwayson_user FOR LOGIN alwayson_user
--step3: create trusted certificate
/*
这个需要在所有实例证书创建后,相互拷贝到每个ECS目录下,然后再运行,
比如在001上,需要创建002,003备份出来的证书,那么在002,需要创建001,003
同理在003上,需要再创建001,002的证书。
*/
CREATE CERTIFICATE cer_alwayson_002
AUTHORIZATION alwayson_user
FROM FILE='C:\software\cerficates\cer_alwayson_002.cer'
CREATE CERTIFICATE cer_alwayson_003
AUTHORIZATION alwayson_user
FROM FILE='C:\software\cerficates\cer_alwayson_003.cer'
--step4:grant connection right
GRANT CONNECT ON ENDPOINT:: Endpoint_Mirroring TO alwayson_user
17.**在实例上创建一个数据库并做全备份**
创建数据库是因为后面创建AG需要的,备份是做副本复制时必要的工作,因为没有事务日志点是没有办法搭建副本复制的。
CREATE DATABASE rdsystem
BACKUP DATABASE rdsystem TO DISK='C:\software\rdsystem.bak.full.first'
18.**在主副本上创建AG**
建议初学者用UI创建,通过向导创建比较容易,然后根据提示操作,不再把所有图片贴出来了:
也可以使用SQL指令:
CREATE AVAILABILITY GROUP [ag-aliyun0001]
WITH (AUTOMATED_BACKUP_PREFERENCE = SECONDARY,
DB_FAILOVER = OFF,
DTC_SUPPORT = NONE)
FOR DATABASE [db1]
REPLICA ON N'IZBP1EHI2DOPYQA' WITH (ENDPOINT_URL = N'TCP://iZbp1ehi2dopyqA.aliyunrds.com:5022', FAILOVER_MODE = AUTOMATIC, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL)),
N'IZBP1EHI2DOPYQC' WITH (ENDPOINT_URL = N'TCP://iZbp1ehi2dopyqC.aliyunrds.com:5022', FAILOVER_MODE = AUTOMATIC, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL)),
N'iZbp1ehi2dopyqZ' WITH (ENDPOINT_URL = N'TCP://iZbp1ehi2dopyqZ.aliyunrds.com:5022', FAILOVER_MODE = AUTOMATIC, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL));
如果要需要将数据库手动还原到辅助副本,那么需要备份数据库和日志,接着在辅助副本还原到前滚状态。或者你可以共享一个文件夹,让向导完成。最后推荐一种方法,创建AG,将SEEDING_MODE = AUTOMATIC选项加入到上面脚本中的每个副本中,即:
N'iZbp1ehi2dopyqZ' WITH (ENDPOINT_URL = N'TCP://iZbp1ehi2dopyqZ.aliyunrds.com:5022', FAILOVER_MODE = AUTOMATIC, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50,SEEDING_MODE = AUTOMATIC, SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL))
然后再每个辅助副本节点运行一下命令:
SECONDARY ALTER AVAILABILITY GROUP [ag-aliyun0001] GRANT CREATE ANY DATABASE
19.**在辅助副本加入AG并且让该数据库加入进来**
ALTER AVAILABILITY GROUP [ag-aliyun0001] JOIN;
ALTER DATABASE [db1] SET HADR AVAILABILITY GROUP = [ag-aliyun0001];
这样,AlwaysOn可用性组就创建好了:
20.**创建侦听器**
这个侦听器创建好了后,是不可以在非Primary节点之外访问的,但可利用HAVIP来解决。请用UI创建就好了,直接NEXT STEP:
至此,AlwaysOn可用性组就全部创建成功,请读者看看,这三个图,在不同的副本上截取的,有些地方是不同的,这体现了主副本和辅助副本,同步和异步的复制关系:
20.**创建HAVIP**
请咨询VPC/HAVIP产品经理开通HAVIP白名单,然后在用户控制台上关联到两个同步的ECS上,注意,一定是同步复制的数据库副本上的ECS,HAVIP(高可用虚拟IP)必须与侦听器的IP一致,监听的端口也是和侦听器的端口一致:
20.**创建只读的SLB**
这个就很简单了,将只读的ECS绑定到SLB,指定权重就好了,不再累述。
注意事项
1. 这个解决方案中是没有域控的,所以在配置上有很多安全上的要求
2. 如果需要加入域控,那么配置AlwaysOn的安全就不再需要
3. 该方案将是产品化方案的一个雏形,产品化将会在不久的将来推出,产品化的方案会在权限方面有所控制,同时自动化能力会非常高,将是一种PaaS服务
最后更新:2017-05-11 14:31:12