概述
Azure 高级 SSD 是下一代存储,可提供低延迟和高吞吐量 IO。 它最适合关键 IO 密集型工作负荷,例如 IaaS 上的 SQL Server 虚拟机。
重要
Azure 具有用于创建和处理资源的两个不同的部署模型:资源管理器部署模型和经典部署模型。 本文介绍如何使用经典部署模型。 Microsoft 建议大多数新部署使用 Resource Manager 模型。
本文提供有关迁移运行 SQL Server 的虚拟机以使用高级存储的规划和指南。 这包括 Azure 基础结构(网络、存储)和客户机 Windows 虚拟机步骤。 附录 中的示例展示了使用 PowerShell 借助改进的本地 SSD 存储,全面演示从头到尾如何迁移更大的 VM。
了解将 Azure 高级存储与 IAAS VM 上的 SQL Server 配合使用的端到端过程非常重要。 这包括:
- 标识使用高级存储的先决条件。
- 将 IaaS 上的 SQL Server 部署到高级存储以用于新部署的示例。
- 迁移现有部署的示例,包括独立服务器和使用 SQL 始终在线可用性组的部署。
- 可能的迁移方法。
- 显示用于迁移现有 AlwaysOn 实现的 Azure、Windows 和 SQL Server 步骤的完整端到端示例。
有关 Azure 虚拟机中 SQL Server 的详细信息,请参阅 Azure 虚拟机中的 SQL Server。
作者: 丹尼尔·索尔 技术审阅者: 路易斯·卡洛斯·巴尔加斯·赫林、桑贾伊·米什拉、普拉文·米斯塔、朱尔根·托马斯、冈萨洛·鲁伊斯。
高级存储的先决条件
使用高级存储有几个先决条件。
计算机大小
若要使用高级存储,需要使用 DS 系列虚拟机(VM)。 如果以前未在云服务中使用 DS 系列计算机,则必须删除现有 VM,保留附加磁盘,然后在将 VM 重新创建为 DS* 角色大小之前创建新的云服务。 有关 azure 虚拟机大小的更多信息,请参阅 虚拟机和云服务大小。
云服务
只有在新的云服务中创建 DS* VM 时,才能将 DS* VM 与高级存储配合使用。 如果在 Azure 中使用 SQL Server Always On,Always On 侦听器将引用与云服务关联的 Azure 内部或外部负载均衡器 IP 地址。 本文重点介绍如何在此方案中保持可用性的同时迁移。
注释
DS* 系列必须是部署到新云服务的第一个 VM。
区域 VNETs
对于 DS* VM,必须将托管 VM 的虚拟网络(VNET)配置为区域性。 在 VNET 的扩展中,这样做是为了允许在其他群集中部署更大的虚拟机,并实现它们之间的通信。 在以下屏幕截图中,突出显示的“位置”展示了“区域性VNET”,而第一个结果则展示了“窄VNET”。
               
              
            
可以提交微软支持请求以迁移到区域虚拟网络。 然后Microsoft进行更改。 若要完成到区域 VNET 的迁移,请在网络配置中更改属性 AffinityGroup。 首先在 PowerShell 中导出网络配置,然后将 VirtualNetworkSite 元素中的 AffinityGroup 属性替换为 Location 属性。 指定 Location = XXXX 其中 XXXX 是 Azure 区域。 然后导入新配置。
例如,考虑以下 VNET 配置:
<VirtualNetworkSite name="danAzureSQLnet" AffinityGroup="AzureSQLNetwork">
<AddressSpace>
  <AddressPrefix>10.0.0.0/8</AddressPrefix>
  <AddressPrefix>172.16.0.0/12</AddressPrefix>
</AddressSpace>
<Subnets>
...
</VirtualNetworkSite>
若要将此配置移到西欧的区域 VNET,请将配置更改为以下内容:
<VirtualNetworkSite name="danAzureSQLnet" Location="West Europe">
<AddressSpace>
  <AddressPrefix>10.0.0.0/8</AddressPrefix>
  <AddressPrefix>172.16.0.0/12</AddressPrefix>
</AddressSpace>
<Subnets>
...
</VirtualNetworkSite>
存储帐户
需要创建为高级存储配置的新存储帐户。 请注意,使用高级存储是在存储帐户中设置的,而不是在单个 VHD 上设置的,但是使用 DS* 系列 VM 时,可以从高级存储帐户和标准存储帐户附加 VHD。 如果不想将 OS VHD 放在高级存储帐户上,可以考虑这一点。
以下 New-AzureStorageAccountPowerShell 命令使用“Premium_LRS”类型来创建一个高级存储帐户:
$newstorageaccountname = "danpremstor"
New-AzureStorageAccount -StorageAccountName $newstorageaccountname -Location "West Europe" -Type "Premium_LRS"   
VHD 缓存设置
创建属于高级存储帐户的磁盘的主要区别在于磁盘缓存设置。 对于 SQL Server 数据卷磁盘,推荐使用“读取缓存”。 对于事务日志卷,磁盘缓存设置应设置为“None”。 这不同于标准存储帐户的建议。
附加 VHD 后,无法更改缓存设置。 您需要先分离 VHD,然后使用更新的缓存设置重新附加它。
Windows 存储空间
可以使用 Windows 存储空间 与以前的标准存储一样,这样就可以迁移已使用存储空间的 VM。 附录(步骤 9 和向前)中的示例演示了用于提取和导入具有多个附加 VHD 的 VM 的 Powershell 代码。
存储池与标准 Azure 存储帐户一起使用,以增强吞吐量并减少延迟。 在测试具有高级存储的存储池进行新部署时,可能会发现其价值,但它们确实增加了存储设置的额外复杂性。
如何确定哪些 Azure 虚拟磁盘映射到存储池
由于附加 VHD 有不同的缓存设置建议,因此可能会决定将 VHD 复制到高级存储帐户。 但是,将它们重新附加到新的 DS 系列 VM 时,可能需要更改缓存设置。 为 SQL 数据文件和日志文件使用单独的 VHD(而不是包含两者的单个 VHD)时,应用高级存储建议的缓存设置更简单。
注释
如果同一卷上有 SQL Server 数据和日志文件,则选择的缓存选项取决于数据库工作负荷的 IO 访问模式。 只有测试可以演示哪种缓存选项最适合此方案。
但是,如果使用由多个 VHD 组成的 Windows 存储空间,则需要查看原始脚本,以确定哪些附加的 VHD 位于特定的池中,以便可以相应地为每个磁盘设置缓存设置。
如果没有可用于显示哪些 VHD 映射到存储池的原始脚本,您可以通过以下步骤来确定磁盘与存储池的映射。
对于每个磁盘,请使用以下步骤:
- 使用 Get-AzureVM 命令获取附加到 VM 的磁盘列表:
Get-AzureVM -ServiceName <servicename> -Name <vmname> | Get-AzureDataDisk
- 记下 DiskName 和 LUN。   
- 通过远程桌面连接到虚拟机。 然后转到 计算机管理 | 设备管理器 | 磁盘驱动器。 查看每个“Microsoft虚拟磁盘”的属性   
- 此处的 LUN 编号是对将 VHD 附加到 VM 时指定的 LUN 编号的引用。 
- 对于“Microsoft虚拟磁盘”,请转到 详细信息 选项卡,然后在 属性 列表中,转到 驱动程序密钥。 在 值中,请注意 偏移量,在以下屏幕截图中该值为 0002。 0002 表示存储池引用的 PhysicalDisk2。   
- 对于每个存储池,列出关联的磁盘: 
Get-StoragePool -FriendlyName AMS1pooldata | Get-PhysicalDisk
               
              
            
现在,可以使用此信息将附加的 VHD 关联到存储池中的物理磁盘。
将 VHD 映射到存储池中的物理磁盘后,即可将其分离并复制到高级存储帐户,然后使用正确的缓存设置连接它们。 请参阅 附录中的示例,步骤 8 到 12。 这些步骤演示如何将 VM 附加的 VHD 磁盘配置提取到 CSV 文件、复制 VHD、更改磁盘配置缓存设置,最后将所有附加磁盘重新部署为 DS 系列 VM。
VM 存储带宽和 VHD 存储吞吐量
存储性能取决于指定的 DS* VM 大小和 VHD 大小。 不同的 VM 对可附加的 VHD 数量和它们支持的最大带宽(MB/秒)有不同的限额。 有关特定带宽编号,请参阅 Azure 虚拟机和云服务的规格。
通过更大的磁盘大小实现 IOPS 增加。 考虑迁移路径时,应考虑这一点。 有关详细信息,请参阅 IOPS 和磁盘类型的表。
最后,请考虑到虚拟机(VM)对所有连接的磁盘有着不同的最大磁盘带宽。 在高负载下,您可能会达到分配给该 VM 角色大小的最大磁盘带宽的饱和状态。 例如,Standard_DS14最多支持 512MB/秒;因此,使用三个 P30 磁盘,可以饱和 VM 的磁盘带宽。 但在此示例中,可以根据读取和写入 IO 的组合,超出吞吐量限制。
新部署
接下来的两个部分演示如何将 SQL Server VM 部署到高级存储。 如前所述,不一定需要将 OS 磁盘放入高级存储。 如果要在 OS VHD 上放置任何密集型 IO 工作负荷,可以选择执行此作。
第一个示例演示了如何使用现有的 Azure Gallery Images。 第二个示例演示如何使用现有标准存储帐户中的自定义 VM 映像。
注释
这些示例假定已创建区域 VNET。
使用画廊映像创建具有高级存储的新 VM
下面的示例演示如何将 OS VHD 放置到高级存储中,并附加高级存储 VHDs。 但是,您还可以将 OS 磁盘放置在 标准 存储帐户中,然后附加那些驻留在 高级 存储帐户中的 VHD。 演示了这两种方案。
$mysubscription = "DansSubscription"
$location = "West Europe"
#Set up subscription
Set-AzureSubscription -SubscriptionName $mysubscription
Select-AzureSubscription -SubscriptionName $mysubscription -Current  
步骤 1:创建高级存储帐户
#Create Premium Storage account, note Type
$newxiostorageaccountname = "danspremsams"
New-AzureStorageAccount -StorageAccountName $newxiostorageaccountname -Location $location -Type "Premium_LRS"  
步骤 2:创建新的云服务
$destcloudsvc = "danNewSvcAms"
New-AzureService $destcloudsvc -Location $location
步骤 3:保留云服务 VIP(可选)
#check exisitng reserved VIP
Get-AzureReservedIP
$reservedVIPName = "sqlcloudVIP"
New-AzureReservedIP –ReservedIPName $reservedVIPName –Label $reservedVIPName –Location $location
步骤 4:创建 VM 容器
#Generate storage keys for later
$xiostorage = Get-AzureStorageKey -StorageAccountName $newxiostorageaccountname
##Generate storage acc contexts
$xioContext = New-AzureStorageContext –StorageAccountName $newxiostorageaccountname -StorageAccountKey $xiostorage.Primary   
#Create container
$containerName = 'vhds'
New-AzureStorageContainer -Name $containerName -Context $xioContext
步骤 5:将 OS VHD 放置在标准存储或高级存储上
#NOTE: Set up subscription and default storage account which is used to place the OS VHD in
#If you want to place the OS VHD Premium Storage Account
Set-AzureSubscription -SubscriptionName $mysubscription -CurrentStorageAccount  $newxiostorageaccountname  
#If you wanted to place the OS VHD Standard Storage Account but attach Premium Storage VHDs then you would run this instead:
$standardstorageaccountname = "danstdams"
Set-AzureSubscription -SubscriptionName $mysubscription -CurrentStorageAccount  $standardstorageaccountname
步骤 6:创建 VM
#Get list of available SQL Server Images from the Azure Image Gallery.
$galleryImage = Get-AzureVMImage | where-object {$_.ImageName -like "*SQL*2014*Enterprise*"}
$image = $galleryImage.ImageName
#Set up Machine Specific Information
$vmName = "dsDan1"
$vnet = "dansvnetwesteur"
$subnet = "SQL"
$ipaddr = "192.168.0.8"
#Remember to change to DS series VM
$newInstanceSize = "Standard_DS1"
#create new Availability Set
$availabilitySet = "cloudmigAVAMS"
#Machine User Credentials
$userName = "myadmin"
$pass = "mycomplexpwd4*"
#Create VM Config
$vmConfigsl = New-AzureVMConfig -Name $vmName -InstanceSize $newInstanceSize -ImageName $image  -AvailabilitySetName $availabilitySet  ` | Add-AzureProvisioningConfig -Windows ` -AdminUserName $userName -Password $pass | Set-AzureSubnet -SubnetNames $subnet | Set-AzureStaticVNetIP -IPAddress $ipaddr
#Add Data and Log Disks to VM Config
#Note the size specified '-DiskSizeInGB 1023', this attaches 2 x P30 Premium Storage Disk Type
#Utilising the Premium Storage enabled Storage account
$vmConfigsl | Add-AzureDataDisk -CreateNew -DiskSizeInGB 1023 -LUN 0 -HostCaching "ReadOnly"  -DiskLabel "DataDisk1" -MediaLocation "https://$newxiostorageaccountname.blob.core.windows.net/vhds/$vmName-data1.vhd"
$vmConfigsl | Add-AzureDataDisk -CreateNew -DiskSizeInGB 1023 -LUN 1 -HostCaching "None"  -DiskLabel "logDisk1" -MediaLocation "https://$newxiostorageaccountname.blob.core.windows.net/vhds/$vmName-log1.vhd"
#Create VM
$vmConfigsl  | New-AzureVM –ServiceName $destcloudsvc -VNetName $vnet ## Optional (-ReservedIPName $reservedVIPName)  
#Add RDP Endpoint
$EndpointNameRDPInt = "3389"
Get-AzureVM -ServiceName $destcloudsvc -Name $vmName | Add-AzureEndpoint -Name "EndpointNameRDP" -Protocol "TCP" -PublicPort "53385" -LocalPort $EndpointNameRDPInt  | Update-AzureVM
#Check VHD storage account, these should be in $newxiostorageaccountname
Get-AzureVM -ServiceName $destcloudsvc -Name $vmName | Get-AzureDataDisk
Get-AzureVM -ServiceName $destcloudsvc -Name $vmName |Get-AzureOSDisk
创建新的 VM 以将高级存储与自定义映像配合使用
此场景展示了您现有的自定义映像存储在标准存储帐户中的位置。 如前所述,如果要将 OS VHD 放置在高级存储上,则需要复制标准存储帐户中存在的映像并将其传输到高级存储,然后才能使用它。 如果您在本地有一个映像,也可以使用此方法将该映像直接复制到高级存储帐户。
步骤 1:创建存储帐户
$mysubscription = "DansSubscription"
$location = "West Europe"
#Create Premium Storage account
$newxiostorageaccountname = "danspremsams"
New-AzureStorageAccount -StorageAccountName $newxiostorageaccountname -Location $location -Type "Premium_LRS"  
#Standard Storage account
$origstorageaccountname = "danstdams"
步骤 2 创建云服务
$destcloudsvc = "danNewSvcAms"
New-AzureService $destcloudsvc -Location $location
步骤 3:使用现有映像
可以使用现有映像。 或者,可以 拍摄现有机器的图像。 请注意,您镜像的计算机不必是 DS* 计算机。 获取映像后,以下步骤演示如何使用 Start-AzureStorageBlobCopy PowerShell commandlet 将其复制到高级存储帐户。
#Get storage account keys:
#Standard Storage account
$originalstorage =  Get-AzureStorageKey -StorageAccountName $origstorageaccountname
#Premium Storage account
$xiostorage = Get-AzureStorageKey -StorageAccountName $newxiostorageaccountname
#Set up contexts for the storage accounts:
$origContext = New-AzureStorageContext  –StorageAccountName $origstorageaccountname -StorageAccountKey $originalstorage.Primary
$destContext = New-AzureStorageContext  –StorageAccountName $newxiostorageaccountname -StorageAccountKey $xiostorage.Primary  
步骤 4:在存储帐户之间复制 Blob
#Get Image VHD
$myImageVHD = "dansoldonorsql2k14-os-2015-04-15.vhd"
$containerName = 'vhds'
#Copy Blob between accounts
$blob = Start-AzureStorageBlobCopy -SrcBlob $myImageVHD -SrcContainer $containerName `
-DestContainer vhds -Destblob "prem-$myImageVHD" `
-Context $origContext -DestContext $destContext  
步骤 5:定期检查复制状态:
$blob | Get-AzureStorageBlobCopyState
步骤 6:将映像磁盘添加到订阅中的 Azure 磁盘存储库
$imageMediaLocation = $destContext.BlobEndPoint+"/"+$myImageVHD
$newimageName = "prem"+"dansoldonorsql2k14"
Add-AzureVMImage -ImageName $newimageName -MediaLocation $imageMediaLocation
注释
你可能会发现,即使状态报告为成功,你可能仍会遇到磁盘租约错误。 在这种情况下,请等待大约 10 分钟。
步骤 7:生成 VM
您将从映像创建 VM,并连接两个高级存储 VHD:
$newimageName = "prem"+"dansoldonorsql2k14"
#Set up Machine Specific Information
$vmName = "dansolchild"
$vnet = "westeur"
$subnet = "Clients"
$ipaddr = "192.168.0.41"
#This needs to be a new cloud service
$destcloudsvc = "danregsvcamsxio2"
#Use to DS Series VM
$newInstanceSize = "Standard_DS1"
#create new Availability Set
$availabilitySet = "cloudmigAVAMS3"
#Machine User Credentials
$userName = "myadmin"
$pass = "theM)stC0mplexP@ssw0rd!"
#Create VM Config
$vmConfigsl2 = New-AzureVMConfig -Name $vmName -InstanceSize $newInstanceSize -ImageName $newimageName  -AvailabilitySetName $availabilitySet  ` | Add-AzureProvisioningConfig -Windows ` -AdminUserName $userName -Password $pass | Set-AzureSubnet -SubnetNames $subnet | Set-AzureStaticVNetIP -IPAddress $ipaddr
$vmConfigsl2 | Add-AzureDataDisk -CreateNew -DiskSizeInGB 1023 -LUN 0 -HostCaching "ReadOnly"  -DiskLabel "DataDisk1" -MediaLocation "https://$newxiostorageaccountname.blob.core.windows.net/vhds/$vmName-Datadisk-1.vhd"
$vmConfigsl2 | Add-AzureDataDisk -CreateNew -DiskSizeInGB 1023 -LUN 1 -HostCaching "None"  -DiskLabel "LogDisk1" -MediaLocation "https://$newxiostorageaccountname.blob.core.windows.net/vhds/$vmName-logdisk-1.vhd"
$vmConfigsl2 | New-AzureVM –ServiceName $destcloudsvc -VNetName $vnet
不使用 AlwaysOn 可用性组的现有部署
注释
有关现有部署,请先参阅本文 先决条件 部分。
对于不使用 Always On 可用性组的 SQL Server 部署和使用 Always On 可用性组的部署,有不同的注意事项。 如果不使用 Always On 并且具有现有的独立 SQL Server,则可以使用新的云服务和存储帐户升级到高级存储。 请考虑以下选项:
- 创建新的 SQL Server VM。 可以创建使用高级存储帐户的新 SQL Server VM,如新部署中所述。 然后备份和还原 SQL Server 配置和用户数据库。 在内部或外部访问新 SQL Server 时,需要更新应用程序以引用新的 SQL Server。 需要复制所有“数据库外”对象,就像在进行并排 SQL Server 迁移一样。 这包括登录名、证书和链接服务器等对象。
- 迁移现有 SQL Server VM。 这需要使 SQL Server VM 脱机,然后将其传输到新的云服务,包括将其所有附加 VHD 复制到高级存储帐户。 当 VM 联机时,应用程序将引用服务器主机名,如前所述。 请注意,现有磁盘的大小会影响性能特征。 举例来说,400 GB 磁盘被舍入为 P20。 如果您确定不需要该磁盘性能,则可以将 VM 重新创建为 DS 系列的虚拟机,并附加符合您需求的大小/性能规格的高级存储 VHD。 然后,可以分离并重新附加 SQL DB 文件。
注释
复制 VHD 磁盘时,应注意大小,具体取决于大小意味着它们属于哪些高级存储磁盘类型,这决定了磁盘性能规范。 Azure 向上舍入到最接近的磁盘大小,因此,如果有 400GB 磁盘,则会向上舍入为 P20。 根据 OS VHD 的现有 IO 要求,可能不需要将其迁移到高级存储帐户。
如果 SQL Server 被外部访问,则云服务的 VIP 会发生变化。 还必须更新终结点、ACL 和 DNS 设置。
使用 AlwaysOn 可用性组的现有部署
注释
有关现有部署,请先参阅本文 先决条件 部分。
最初在本部分中,我们将了解 AlwaysOn 如何与 Azure 网络交互。 然后,我们将迁移分解为两种情况:可以容忍一些停机时间的迁移,以及必须在其中实现最短停机时间的迁移。
本地 SQL Server Always On 可用性组使用本地侦听器,该侦听器注册虚拟 DNS 名称以及一个或多个 SQL Server 之间共享的 IP 地址。 客户端连接时,通过侦听器 IP 被路由到主 SQL Server。 这是当时拥有 AlwaysOn IP 资源的服务器。
               
              
            
在 Microsoft Azure 中,只能将一个 IP 地址分配给 VM 上的 NIC,因此为了实现与本地相同的抽象层,Azure 利用分配给内部/外部负载均衡器(ILB/ELB)的 IP 地址。 服务器之间共享的 IP 资源设置为与 ILB/ELB 相同的 IP。 这在 DNS 中发布,客户端流量通过 ILB/ELB 传递到主 SQL Server 副本。 ILB/ELB 知道哪个 SQL Server 是主节点,因为它使用探测来探测 Always On IP 资源。 在前面的示例中,它会检查 ELB/ILB 所引用的终结点的每个节点,哪个节点响应就作为主 SQL Server。
注释
ILB 和 ELB 都分配给特定的 Azure 云服务,因此 Azure 中的任何云迁移都可能意味着负载均衡器 IP 发生更改。
迁移 AlwaysOn 部署,这些部署可能会造成一些停机时间
有两种策略可以迁移 Always On 部署,并允许一些停机时间:
- 向现有 AlwaysOn 群集添加更多次要副本
- 迁移到新的 AlwaysOn 群集
1.向现有 AlwaysOn 群集添加更多次要副本
一种策略是向 AlwaysOn 可用性组添加更多辅助数据库。 需要将这些内容添加到新的云服务中,并使用新的负载均衡器 IP 更新侦听器。
停机时间点:
- 群集验证。
- 测试新辅助节点的 Always On 故障转移。
如果在 VM 中使用 Windows 存储池以提高 IO 吞吐量,则在完整群集验证期间,这些池处于脱机状态。 将节点添加到群集时,需要验证测试。 运行测试所需的时间可能会有所不同,因此应在具有代表性的测试环境中测试此测试,以便大致了解这需要多长时间。
应预配可在新添加的节点上执行手动故障转移和混乱测试的时间,以确保 AlwaysOn 高可用性功能按预期运行。
               
              
            
注释
应在验证运行之前停止使用存储池的所有 SQL Server 实例。
高级步骤
- 在附加的高级存储的新云服务中创建两个新的 SQL Server。 
- 使用 NORECOVERY复制完整备份和还原。 
- 复制“用户数据库外”依赖对象,例如登录名等。 
- 创建新的内部负载均衡器(ILB)或使用外部负载均衡器(ELB),然后在这两个新节点上设置负载均衡终结点。 - 注释 - 在继续作之前,请检查所有节点是否具有正确的终结点配置 
- 停止对 SQL Server 的用户/应用程序访问(如果使用存储池)。 
- 停止所有节点上的 SQL Server 引擎服务(如果使用存储池)。 
- 将新节点添加到群集并运行完全验证。 
- 验证成功后,启动所有 SQL Server 服务。 
- 备份事务日志并还原用户数据库。 
- 将新节点添加到 AlwaysOn 可用性组中,并将复制置于 同步中。 
- 基于 附录中的多站点示例,通过 PowerShell for Always On 添加新云服务 ILB/ELB 的 IP 地址资源。 在 Windows 群集中,将 可能的所有者 的 IP 地址 资源设置为新节点的旧状态。 请参阅 附录的“在同一子网上添加 IP 地址资源”部分。 
- 故障转移到其中一个新节点。 
- 将新节点设为新的自动故障转移合作伙伴,并进行故障转移测试。 
- 从可用性组中删除原始节点。 
优点
- 在将新 SQL Server 添加到 AlwaysOn 之前,可以对其进行测试(SQL Server 和应用程序)。
- 可以更改 VM 大小,并根据确切要求自定义存储。 但是,保持所有 SQL 文件路径相同会很有帮助。
- 可以控制何时开始将数据库备份传输到次要副本。 这不同于使用 Azure Start-AzureStorageBlobCopy 命令来复制 VHD,因为它是异步复制。
缺点
- 使用 Windows 存储池时,在新的附加节点的完整群集验证过程中,群集将面临停机。
- 根据 SQL Server 版本和现有辅助副本数,在删除现有辅助副本的情况下,可能无法添加更多辅助副本。
- 设置辅助数据库时,可能会有很长的 SQL 数据传输时间。
- 在迁移期间,在并行运行新计算机时会产生额外的成本。
2.迁移到新的 AlwaysOn 群集
另一种策略是创建新的 AlwaysOn 群集,并在新的云服务中使用全新的节点,然后重定向客户端以使用它。
停机时间点
将应用程序和用户传输到新的 AlwaysOn 侦听器时,会停机。 停机时间取决于:
- 将最终事务日志备份还原到新服务器上的数据库所花费的时间。
- 更新客户端应用程序以使用新的 Always On 侦听器所需的时间。
优点
- 可以测试实际的生产环境、SQL Server 和 OS 生成更改。
- 可以选择自定义存储,并可能减小 VM 的大小。 这可能会导致成本降低。
- 在此过程中,可以更新 SQL Server 构建版本或版本。 你还可以升级操作系统。
- 先前的 Always On 群集可以充当可靠的回滚目标。
缺点
- 如果希望同时运行两个 Always On 群集,则需要更改侦听器的 DNS 名称。 这会增加迁移期间的管理开销,因为客户端应用程序字符串必须反映新的侦听器名称。
- 必须在两个环境之间实现同步机制,使其尽可能接近,以尽量减少迁移之前的最终同步要求。
- 在运行新环境时,迁移期间会增加成本。
迁移 AlwaysOn 部署以尽量减少停机时间
迁移 AlwaysOn 部署的两种策略可以最大程度地减少停机时间:
- 利用现有从属数据库:单一站点
- 利用现有备用副本:多站点
1.利用现有次要数据库:Single-Site
最小化停机时间的一种策略是将现有的云备份从当前云服务中移除。 然后将 VHD 复制到新的高级存储帐户,并在新的云服务中创建 VM。 然后在群集和故障转移中更新侦听器。
停机时间点
- 使用负载均衡终结点更新最终节点时,会停机。
- 客户端重新连接可能会延迟,具体取决于客户端/DNS 配置。
- 如果选择使 AlwaysOn 群集组脱机以交换 IP 地址,则会出现额外的停机时间。 可以通过对添加的 IP 地址资源使用 OR 依赖项和可能的所有者来避免这种情况。 请参阅 附录的“在同一子网上添加 IP 地址资源”部分。
注释
当希望添加的节点作为 AlwaysOn 故障转移合作伙伴加入时,需要添加一个 Azure 终结点,其中包含对负载均衡集的引用。 运行 Add-AzureEndpoint 命令执行此作时,当前连接保持打开状态,但在负载均衡器更新之前无法建立与侦听器的新连接。 在测试中,这被视为持续了 90-120 秒,应该对其进行测试。
优点
- 迁移期间不会产生额外费用。
- 一对一迁移。
- 降低了复杂性。
- 允许从高级存储产品类型中提升 IOPS。 当磁盘从 VM 分离并复制到新的云服务时,第三方工具可用于增加 VHD 大小,从而提供更高的吞吐量。 有关增加 VHD 大小的信息,请参阅此 论坛讨论。
缺点
- 迁移期间,HA 和 DR 暂时丢失。
- 由于这是 1:1 迁移,您必须使用支持您 VHD 数量的最小 VM 大小,因此可能无法缩小 VM。
- 此方案将使用 Azure Start-AzureStorageBlobCopy 命令,这是异步的。 对复制完成没有服务级别协议。 副本的时间各不相同,而这取决于队列中的等待时间,但也取决于要传输的数据量。 如果传输要转到另一个支持异地高级存储的 Azure 数据中心,则复制时间会增加。 如果只有 2 个节点,请考虑在复制所需时间长于测试过程时可能采取的应对措施。 这可能包括以下想法。
- 在迁移之前,先为 HA 添加一个临时的第 3 个 SQL Server 节点,并已就停机时间达成一致。
- 在 Azure 计划维护之外运行迁移。
- 确保已正确配置群集仲裁。
 
高级步骤
本文档未演示完整的端到端示例,但 附录 提供了可用于执行此作的详细信息。
               
              
            
- 收集磁盘配置信息,然后移除节点(请勿删除附加的虚拟硬盘)。
- 创建一个高级存储帐户,并从标准存储帐户复制虚拟硬盘 (VHD)。
- 创建新的云服务,并在该云服务中重新部署 SQL2 VM。 使用复制的原始操作系统 (OS) VHD 创建 VM,并附加复制的 VHD。
- 配置 ILB/ELB 并添加终结点。
- 通过以下任一方法更新侦听器:- 使 AlwaysOn 组脱机,并使用新的 ILB/ELB IP 地址更新 AlwaysOn 侦听器。
- 或者通过 PowerShell 将新的云服务 ILB/ELB 的 IP 地址资源添加到 Windows 群集中。 然后将 IP 地址资源的可能所有者设置为已迁移节点 SQL2,并在网络名称中将其设置为 OR 依赖项。 请参阅 附录的“在同一子网上添加 IP 地址资源”部分。
 
- 检查 DNS 配置,确保其传播到客户端。
- 迁移 SQL1 VM,并完成步骤 2 - 4。
- 如果使用步骤 5ii,则添加 SQL1 作为添加的 IP 地址资源的可能所有者
- 测试故障转移。
2.利用现有次要副本:多站点
如果有多个 Azure 数据中心(DC)中的节点,或者拥有混合环境,则可以在此环境中使用 AlwaysOn 配置来最大程度地减少停机时间。
此方法是将本地或辅助 Azure DC 的 AlwaysOn 同步更改为同步,然后故障转移到该 SQL Server。 然后将 VHD 复制到高级存储帐户,并将计算机重新部署到新的云服务中。 更新侦听器,然后恢复到故障前状态。
停机时间点
停机时间包括故障转移到备用数据中心以及从备用数据中心返回的时间。 它还取决于客户端/DNS 配置,客户端重新连接可能会延迟。 请考虑混合 AlwaysOn 配置的以下示例:
               
              
            
优点
- 可以利用现有的基础结构。
- 可以选择先在 DR Azure DC 上预升级 Azure 存储。
- 可以重新配置 DR Azure DC 存储。
- 迁移期间至少有两个故障转移,不包括测试故障转移。
- 无需通过备份和还原的方法来移动 SQL Server 数据。
缺点
- 根据客户端对 SQL Server 的访问,当 SQL Server 在应用程序的备用 DC 中运行时,延迟可能会增加。
- VHD 到高级存储的复制时间可能很长。 这可能会影响你是否将节点保留在可用性组中的决定。 在迁移期间运行日志密集型工作负载时,请考虑这一点,因为主节点必须在其事务日志中保留未复制的事务。 因此,这可能会显著增长。
- 此方案将使用 Azure Start-AzureStorageBlobCopy 命令,这是异步的。 完成时没有服务水平协议。 副本所需的时间各不相同,这既取决于队列中的等待时间,也取决于需要传输的数据量。 由于你在第二个数据中心只有一个节点,因此,如果数据复制花费的时间长于测试,则应采取缓解措施。 这些缓解步骤包括以下想法:- 在迁移之前,为高可用性(HA)添加一个临时第二个 SQL 节点,并商定停机时间。
- 在 Azure 计划维护之外运行迁移。
- 确保已正确配置群集仲裁。
 
此方案假定你已经记录了安装,并了解存储的映射方式,以便针对最佳磁盘缓存设置进行更改。
高级步骤
               
              
            
- 将本地/备用 Azure DC 设为 SQL Server 主服务器,并将其设为另一个自动故障转移合作伙伴。
- 从 SQL2 收集磁盘配置信息,并删除节点(请勿删除附加的 VHD)。
- 创建高级存储帐户,并从标准存储帐户中复制虚拟硬盘文件(VHD)。
- 创建一个新的云服务,并创建附加了高级存储磁盘的 SQL2 虚拟机。
- 配置 ILB/ELB 并添加终结点。
- 使用新的 ILB 或 ELB IP 地址更新 AlwaysOn 侦听器并测试故障转移。
- 检查 DNS 配置。
- 将 AFP 更改为 SQL2,然后迁移 SQL1 并完成步骤 2 – 5。
- 测试故障转移。
- 将 AFP 切换回 SQL1 和 SQL2
附录:将多站点 AlwaysOn 群集迁移到高级存储
本文的其余部分提供了将多站点 AlwaysOn 群集转换为高级存储的详细示例。 它还将侦听器从使用外部负载均衡器 (ELB) 转换为内部负载均衡器 (ILB)。
环境
- Windows 2k12 / SQL 2k12
- SP 上的 1 个 DB 文件
- 每个节点 2 个存储池
               
              
            
VM:
在此示例中,我们将演示如何从 ELB 移动到 ILB。 ELB 在 ILB 之前可用,因此演示如何在迁移期间切换到 ILB。
               
              
            
前置步骤:连接订阅
Add-AzureAccount
#Set up subscription
Get-AzureSubscription
步骤 1:创建新的存储帐户和云服务
$mysubscription = "DansSubscription"
$location = "West Europe"
#Storage accounts
#current storage account where the vm to migrate resides
$origstorageaccountname = "danstdams"
#Create Premium Storage account
$newxiostorageaccountname = "danspremsams"
New-AzureStorageAccount -StorageAccountName $newxiostorageaccountname -Location $location -Type "Premium_LRS"  
#Generate storage keys for later
$originalstorage =  Get-AzureStorageKey -StorageAccountName $origstorageaccountname
$xiostorage = Get-AzureStorageKey -StorageAccountName $newxiostorageaccountname
#Generate storage acc contexts
$origContext = New-AzureStorageContext  –StorageAccountName $origstorageaccountname -StorageAccountKey $originalstorage.Primary
$xioContext = New-AzureStorageContext  –StorageAccountName $newxiostorageaccountname -StorageAccountKey $xiostorage.Primary  
#Set up subscription and default storage account
Set-AzureSubscription -SubscriptionName $mysubscription -CurrentStorageAccount $origstorageaccountname
Select-AzureSubscription -SubscriptionName $mysubscription -Current
#CREATE NEW CLOUD SVC
$vnet = "dansvnetwesteur"
##Existing cloud service
$sourceSvc="dansolSrcAms"
##Create new cloud service
$destcloudsvc = "danNewSvcAms"
New-AzureService $destcloudsvc -Location $location
步骤 2:增加资源允许的故障 <可选>
在某些属于 Always On 可用性组的资源上,针对在一定时间内可能发生的故障次数有限制,当故障发生时群集服务会尝试重启资源组。 建议在进行此过程时增加此值,因为如果不手动执行故障转移并通过关闭计算机来触发故障转移,您可能会接近此限制。
为了谨慎起见,建议将故障限额加倍。要在故障转移群集管理器中执行此操作,请转到 Always On 资源组的属性:
               
              
            
将最大失败数更改为 6。
步骤 3:为群集组添加 IP 地址资源 <可选>
如果群集组只有一个 IP 地址,并且这与云子网保持一致,请注意,如果意外使该网络上云中的所有群集节点脱机,则群集 IP 资源和群集网络名称无法联机。 在这种情况下,它会阻止更新其他群集资源。
步骤 4:DNS 配置
实现平滑转换取决于 DNS 的利用和更新方式。 安装 Always On 后,它会创建 Windows 群集资源组(如果打开故障转移群集管理器)时,会看到它至少具有三个资源,文档引用的两个资源是:
- 虚拟网络名称 (VNN) - 客户端在想要通过 AlwaysOn 连接到 SQL Server 时连接到的 DNS 名称。
- IP 地址资源 – 与 VNN 关联的 IP 地址,可以有多个 IP 地址,在多站点配置中,每个站点/子网都有 IP 地址。
连接到 SQL Server 时,SQL Server 客户端驱动程序将检索与侦听器关联的 DNS 记录,并尝试连接到每个 Always On 关联的 IP 地址。 接下来,我们将讨论可能影响这一点的一些因素。
与侦听器名称关联的并发 DNS 记录数不仅取决于关联的 IP 地址数,还受 Always On VNN 资源中故障转移群集设置“RegisterAllIpProviders”的影响。
在 Azure 中部署 Always On 时,创建侦听器和 IP 地址的步骤不同,必须将“RegisterAllIpProviders”手动配置为 1,这不同于本地 AlwaysOn 部署,其中已设置为 1。
如果“RegisterAllIpProviders”为 0,则只会在与侦听器关联的 DNS 中看到一条 DNS 记录:
               
              
            
如果“RegisterAllIpProviders”为 1:
               
              
            
下面的代码会导出 VNN 设置并为你配置它们。 若要使更改生效,需要使 VNN 脱机并重新联机。 这会使侦听器脱机,导致客户端连接中断。
##Always On Listener Name
$ListenerName = "Mylistener"
##Get AlwaysOn Network Name Settings
Get-ClusterResource $ListenerName| Get-ClusterParameter
##Set RegisterAllProvidersIP
Get-ClusterResource $ListenerName| Set-ClusterParameter RegisterAllProvidersIP  1
在后续的迁移步骤中,您需要用一个引用负载均衡器的更新 IP 地址来更新 Always On 侦听器,这涉及到删除和添加 IP 地址资源。 IP 更新后,需要确保 DNS 区域中更新了新的 IP 地址,并且客户端正在更新其本地 DNS 缓存。
如果您的客户端位于不同的网络段并使用不同的 DNS 服务器,您需要考虑迁移过程中 DNS 区域传输会发生什么情况,因为应用程序重新连接时间至少会受侦听器新 IP 地址的任何区域传输时间的限制。 如果您面临时间限制,应该与 Windows 团队讨论并测试强制采取增量区域传输的方法,同时将 DNS 主机记录的生存时间 (TTL) 设置得更低,以便让客户端进行更新。 有关详细信息,请参阅 增量区域传输 和 Start-DnsServerZoneTransfer。
默认情况下,在 Azure 的“始终开启”功能中,与侦听器关联的 DNS 记录的 TTL 为 1200 秒。 在迁移过程中,如果时间紧迫,您可能希望缩短此过程,以确保客户端将其 DNS 更新为侦听器的最新 IP 地址。 可以通过导出 VNN 的配置来查看和修改其配置。
$AGName = "myProductionAG"
$ListenerName = "Mylistener"
#Look at HostRecordTTL
Get-ClusterResource $ListenerName| Get-ClusterParameter
#Set HostRecordTTL Examples
Get-ClusterResource $ListenerName| Set-ClusterParameter -Name "HostRecordTTL" 120
注释
“HostRecordTTL”越低,会有更多的 DNS 流量。
客户端应用程序设置
如果 SQL 客户端应用程序支持 .NET 4.5 SQLClient,则可以使用“MULTISUBNETFAILOVER=TRUE”关键字。 应应用此关键字,因为它允许在故障转移期间更快地连接到 SQL AlwaysOn 可用性组。 它会并行枚举与 Always On 侦听器关联的所有 IP 地址,并在故障转移期间执行更快的 TCP 连接重试速度。
有关前述设置的详细信息,请参阅 MultiSubnetFailover 关键字和关联的功能。 另请参阅 SqlClient 对高可用性、灾难恢复的支持。
步骤 5:群集仲裁设置
由于一次至少要关闭一个 SQL Server,因此,如果在两个节点上使用文件共享见证(FSW),应修改集群仲裁设置为允许节点多数并利用动态投票机制,使得即使只剩一个节点也能够继续运行。
Set-ClusterQuorum -NodeMajority  
有关管理和配置群集仲裁的详细信息,请参阅 在 Windows Server 2012 故障转移群集中配置和管理仲裁。
步骤 6:提取现有终结点和 ACL
#GET Endpoint info
Get-AzureVM -ServiceName $destcloudsvc -Name $vmNameToMigrate | Get-AzureEndpoint
#GET ACL Rules for Each EP, this example is for the Always On Endpoint
Get-AzureVM -ServiceName $destcloudsvc -Name $vmNameToMigrate | Get-AzureAclConfig -EndpointName "myAOEndPoint-LB"  
将此文本保存到文件中。
步骤 7:更改故障转移伙伴关系和复制模式
如果您有两个以上的 SQL Server,应该将另一个数据中心或本地的某个辅助服务器的故障转移方式更改为“同步”,并将其设为自动故障转移伙伴(AFP),这样在进行更改时可以维护高可用性。 可以通过 TSQL 或 SSMS 进行修改来实现此操作:
附录 6 
步骤 8:从云服务中删除辅助 VM
应首先计划迁移云辅助节点。 如果此节点当前为主节点,则应启动手动故障转移。
$vmNameToMigrate="dansqlams2"
#Check machine status
Get-AzureVM -ServiceName $sourceSvc -Name $vmNameToMigrate
#Shutdown secondary VM
Get-AzureVM -ServiceName $sourceSvc -Name $vmNameToMigrate | stop-AzureVM
#Extract disk configuration
##Building Existing Data Disk Configuration
$file = "C:\Azure Storage Testing\mydiskconfig_$vmNameToMigrate.csv"
$datadisks = @(Get-AzureVM -ServiceName $sourceSvc -Name $vmNameToMigrate | Get-AzureDataDisk )
Add-Content $file "lun, vhdname, hostcaching, disklabel, diskName"
foreach ($disk in $datadisks)
{
    $vhdname = $disk.MediaLink.AbsolutePath -creplace  "/vhds/"
    $disk.Lun, , $disk.HostCaching, $vhdname, $disk.DiskLabel,$disks.DiskName
    # Write-Host "copying disk $disk"
    $adddisk = "{0},{1},{2},{3},{4}" -f $disk.Lun,$vhdname, $disk.HostCaching, $disk.DiskLabel, $disk.DiskName
    $adddisk | add-content -path $file
}
#Get OS Disk
$osdisks = Get-AzureVM -ServiceName $sourceSvc -Name $vmNameToMigrate | Get-AzureOSDisk ## | select -ExpandProperty MediaLink
$osvhdname = $osdisks.MediaLink.AbsolutePath -creplace  "/vhds/"
$osdisks.OS, $osdisks.HostCaching, $osvhdname, $osdisks.DiskLabel, $osdisks.DiskName
$addosdisk = "{0},{1},{2},{3},{4}" -f $osdisks.OS,$osvhdname, $osdisks.HostCaching, $osdisks.Disklabel , $osdisks.DiskName
$addosdisk | add-content -path $file
#Import disk config
$diskobjects  = Import-CSV $file
#Check disk config, make sure below returns the disks associated with the VM
$diskobjects
#Identify OS Disk
$osdiskimport = $diskobjects | where {$_.lun -eq "Windows"}
$osdiskforbuild = $osdiskimport.diskName
#Check machibe is off
Get-AzureVM -ServiceName $sourceSvc -Name  $vmNameToMigrate
#Drop machine and rebuild to new cls
Remove-AzureVM -ServiceName $sourceSvc -Name $vmNameToMigrate
步骤 9:更改 CSV 文件中的磁盘缓存设置并保存
对于数据卷,应将其设置为只读 (READONLY)。
对于 TLOG 卷,应将其设置为 NONE。
               
              
            
步骤 10:复制 VHDS
#Ensure you have created the container for these:
$containerName = 'vhds'
#Create container
New-AzureStorageContainer -Name $containerName -Context $xioContext
####DISK COPYING####
#Get disks from csv, get settings for each VHDs and copy to Premium Storage accoun
ForEach ($disk in $diskobjects)
{
   $lun = $disk.Lun
   $vhdname = $disk.vhdname
   $cacheoption = $disk.HostCaching
   $disklabel = $disk.DiskLabel
   $diskName = $disk.DiskName
   Write-Host "Copying Disk Lun $lun, Label : $disklabel, VHD : $vhdname has cache setting : $cacheoption"
   #Start async copy
   Start-AzureStorageBlobCopy -srcUri "https://$origstorageaccountname.blob.core.windows.net/vhds/$vhdname" `
    -SrcContext $origContext `
    -DestContainer $containerName `
    -DestBlob $vhdname `
    -DestContext $xioContext
}
可以检查将 VHD 文件复制到高级存储帐户的状态:
ForEach ($disk in $diskobjects)
{
   $lun = $disk.Lun
   $vhdname = $disk.vhdname
   $cacheoption = $disk.HostCaching
   $disklabel = $disk.DiskLabel
   $diskName = $disk.DiskName
   $copystate = Get-AzureStorageBlobCopyState -Blob $vhdname -Container $containerName -Context $xioContext
   Write-Host "Copying Disk Lun $lun, Label : $disklabel, VHD : $vhdname, STATUS = " $copystate.Status
}
               
              
            
等到所有这些变为成功。
有关单个 blob 的信息:
Get-AzureStorageBlobCopyState -Blob "blobname.vhd" -Container $containerName -Context $xioContext
步骤 11:注册 OS 磁盘
#Change storage account
Set-AzureSubscription -SubscriptionName $mysubscription -CurrentStorageAccount $newxiostorageaccountname
Select-AzureSubscription -SubscriptionName $mysubscription -Current
#Register OS disk
$osdiskimport = $diskobjects | where {$_.lun -eq "Windows"}
$osvhd = $osdiskimport.vhdname
$osdiskforbuild = $osdiskimport.diskName
#Registering OS disk, but as XIO disk
$xioDiskName = $osdiskforbuild + "xio"
Add-AzureDisk -DiskName $xioDiskName -MediaLocation  "https://$newxiostorageaccountname.blob.core.windows.net/vhds/$osvhd"  -Label "BootDisk" -OS "Windows"
步骤 12:将辅助数据库导入到新的云服务中
下面的代码在此还使用了添加的选项,您可以导入机器并使用可保留的 VIP。
#Build VM Config
$ipaddr = "192.168.0.5"
#Remember to change to XIO
$newInstanceSize = "Standard_DS13"
$subnet = "SQL"
#Create new Availability Set
$availabilitySet = "cloudmigAVAMS"
#build machine config into object
$vmConfig = New-AzureVMConfig -Name $vmNameToMigrate -InstanceSize $newInstanceSize -DiskName $xioDiskName -AvailabilitySetName $availabilitySet  ` | Add-AzureProvisioningConfig -Windows ` | Set-AzureSubnet -SubnetNames $subnet | Set-AzureStaticVNetIP -IPAddress $ipaddr
#Reload disk config
$diskobjects  = Import-CSV $file
$datadiskimport = $diskobjects | where {$_.lun -ne "Windows"}
ForEach ( $attachdatadisk in $datadiskimport)
{
    $label = $attachdatadisk.disklabel
    $lunNo = $attachdatadisk.lun
    $hostcach = $attachdatadisk.hostcaching
    $datadiskforbuild = $attachdatadisk.diskName
    $vhdname = $attachdatadisk.vhdname
    ###Attaching disks to a VM during a deploy to a new cloud service and new storage account is different from just attaching VHDs to just a redeploy in a new cloud service
    $vmConfig | Add-AzureDataDisk -ImportFrom -MediaLocation "https://$newxiostorageaccountname.blob.core.windows.net/vhds/$vhdname" -LUN $lunNo -HostCaching $hostcach -DiskLabel $label
}
#Create VM
$vmConfig  | New-AzureVM –ServiceName $destcloudsvc –Location $location -VNetName $vnet ## Optional (-ReservedIPName $reservedVIPName)
步骤 13:在新云 Svc 上创建 ILB、添加负载均衡终结点和 ACL
#Check for existing ILB
GET-AzureInternalLoadBalancer -ServiceName $destcloudsvc
$ilb="sqlIntIlbDest"
$subnet = "SQL"
$IP="192.168.0.25"
Add-AzureInternalLoadBalancer -ServiceName $destcloudsvc -InternalLoadBalancerName $ilb –SubnetName $subnet –StaticVNetIPAddress $IP
#Endpoints
$epname="sqlIntEP"
$prot="tcp"
$locport=1433
$pubport=1433
Get-AzureVM –ServiceName $destcloudsvc –Name $vmNameToMigrate  | Add-AzureEndpoint -Name $epname -Protocol $prot -LocalPort $locport -PublicPort $pubport -ProbePort 59999 -ProbeIntervalInSeconds 5 -ProbeTimeoutInSeconds 11  -ProbeProtocol "TCP" -InternalLoadBalancerName $ilb -LBSetName $ilb -DirectServerReturn $true | Update-AzureVM
#SET Azure ACLs or Network Security Groups & Windows FWs
#https://msdn.microsoft.com/library/azure/dn495192.aspx
####WAIT FOR FULL AlwaysOn RESYNCRONISATION!!!!!!!!!#####
步骤 14:更新 AlwaysOn
#Code to be executed on a Cluster Node
$ClusterNetworkNameAmsterdam = "Cluster Network 2" # the azure cluster subnet network name
$newCloudServiceIPAmsterdam = "192.168.0.25" # IP address of your cloud service
$AGName = "myProductionAG"
$ListenerName = "Mylistener"
Add-ClusterResource "IP Address $newCloudServiceIPAmsterdam" -ResourceType "IP Address" -Group $AGName -ErrorAction Stop |  Set-ClusterParameter -Multiple @{"Address"="$newCloudServiceIPAmsterdam";"ProbePort"="59999";SubnetMask="255.255.255.255";"Network"=$ClusterNetworkNameAmsterdam;"OverrideAddressMatch"=1;"EnableDhcp"=0} -ErrorAction Stop
#set dependency and NETBIOS, then remove old IP address
#set NETBIOS, then remove old IP address
Get-ClusterGroup $AGName | Get-ClusterResource -Name "IP Address $newCloudServiceIPAmsterdam" | Set-ClusterParameter -Name EnableNetBIOS -Value 0
#set dependency to Listener (OR Dependency) and delete previous IP Address resource that references:
#Make sure no static records in DNS
               
              
            
现在删除旧的云服务 IP 地址。
               
              
            
步骤 15:DNS 更新检查
现在,应检查 SQL Server 客户端网络上的 DNS 服务器,并确保群集已为添加的 IP 地址添加了额外的主机记录。 如果这些 DNS 服务器尚未更新,请考虑强制进行 DNS 区域传输,并确保该子网中的客户端能够解析为 Always On IP 地址,这样就无需等待自动 DNS 复制。
步骤 16:重新配置 AlwaysOn
此时,请等待迁移过来的辅助节点与本地节点完全重新同步,然后将其切换到同步复制模式并将其设为 AFP。
步骤 17:迁移第二个节点
$vmNameToMigrate="dansqlams1"
Get-AzureVM -ServiceName $sourceSvc -Name $vmNameToMigrate
#Get endpoint information
$endpoint = Get-AzureVM -ServiceName $sourceSvc  -Name $vmNameToMigrate | Get-AzureEndpoint
#Shutdown VM
Get-AzureVM -ServiceName $sourceSvc -Name $vmNameToMigrate | stop-AzureVM
#Get disk config
#Building Existing Data Disk Configuration
$file = "C:\Azure Storage Testing\mydiskconfig_$vmNameToMigrate.csv"
$datadisks = @(Get-AzureVM -ServiceName $sourceSvc -Name $vmNameToMigrate | Get-AzureDataDisk )
Add-Content $file "lun, vhdname, hostcaching, disklabel, diskName"
foreach ($disk in $datadisks)
{
    $vhdname = $disk.MediaLink.AbsolutePath -creplace  "/vhds/"
    $disk.Lun, , $disk.HostCaching, $vhdname, $disk.DiskLabel,$disks.DiskName
    # Write-Host "copying disk $disk"
    $adddisk = "{0},{1},{2},{3},{4}" -f $disk.Lun,$vhdname, $disk.HostCaching, $disk.DiskLabel, $disk.DiskName
    $adddisk | add-content -path $file
}
#Get OS Disk
$osdisks = Get-AzureVM -ServiceName $sourceSvc -Name $vmNameToMigrate | Get-AzureOSDisk ## | select -ExpandProperty MediaLink
$osvhdname = $osdisks.MediaLink.AbsolutePath -creplace  "/vhds/"
$osdisks.OS, $osdisks.HostCaching, $osvhdname, $osdisks.DiskLabel, $osdisks.DiskName
$addosdisk = "{0},{1},{2},{3},{4}" -f $osdisks.OS,$osvhdname, $osdisks.HostCaching, $osdisks.Disklabel , $osdisks.DiskName
$addosdisk | add-content -path $file
#Import disk config
$diskobjects  = Import-CSV $file
#Check disk configuration
$diskobjects
#Identify OS Disk
$osdiskimport = $diskobjects | where {$_.lun -eq "Windows"}
$osdiskforbuild = $osdiskimport.diskName
#Check machine is off
Get-AzureVM -ServiceName $sourceSvc -Name  $vmNameToMigrate
#Drop machine and rebuild to new cls
Remove-AzureVM -ServiceName $sourceSvc -Name $vmNameToMigrate
步骤 18:更改 CSV 文件中的磁盘缓存设置并保存
对于数据卷,缓存设置应设置为 READONLY。
对于 TLOG 卷,缓存设置应设置为 NONE。
               
              
            
步骤 19:为辅助节点创建新的独立存储帐户
$newxiostorageaccountnamenode2 = "danspremsams2"
New-AzureStorageAccount -StorageAccountName $newxiostorageaccountnamenode2 -Location $location -Type "Premium_LRS"  
#Reset the storage account src if node 1 in a different storage account
$origstorageaccountname2nd = "danstdams2"
#Generate storage keys for later
$xiostoragenode2 = Get-AzureStorageKey -StorageAccountName $newxiostorageaccountnamenode2
#Generate storage acc contexts
$xioContextnode2 = New-AzureStorageContext  –StorageAccountName $newxiostorageaccountnamenode2 -StorageAccountKey $xiostoragenode2.Primary  
#Set up subscription and default storage account
Set-AzureSubscription -SubscriptionName $mysubscription -CurrentStorageAccount $newxiostorageaccountnamenode2
Select-AzureSubscription -SubscriptionName $mysubscription -Current
步骤 20:复制 VHDs
#Ensure you have created the container for these:
$containerName = 'vhds'
#Create container
New-AzureStorageContainer -Name $containerName -Context $xioContextnode2  
####DISK COPYING####
##get disks from csv, get settings for each VHDs and copy to Premium Storage accoun
ForEach ($disk in $diskobjects)
{
   $lun = $disk.Lun
   $vhdname = $disk.vhdname
   $cacheoption = $disk.HostCaching
   $disklabel = $disk.DiskLabel
   $diskName = $disk.DiskName
   Write-Host "Copying Disk Lun $lun, Label : $disklabel, VHD : $vhdname has cache setting : $cacheoption"
   #Start async copy
   Start-AzureStorageBlobCopy -srcUri "https://$origstorageaccountname2nd.blob.core.windows.net/vhds/$vhdname" `
    -SrcContext $origContext `
    -DestContainer $containerName `
    -DestBlob $vhdname `
    -DestContext $xioContextnode2
}
#Check for copy progress
#check individual blob status
Get-AzureStorageBlobCopyState -Blob "danRegSvcAms-dansqlams1-2014-07-03.vhd" -Container $containerName -Context $xioContext
可以检查所有 VHD 的拷贝状态:
ForEach ($disk in $diskobjects)
{
    $lun = $disk.Lun
    $vhdname = $disk.vhdname
    $cacheoption = $disk.HostCaching
    $disklabel = $disk.DiskLabel
    $diskName = $disk.DiskName
    $copystate = Get-AzureStorageBlobCopyState -Blob $vhdname -Container $containerName -Context $xioContextnode2
    Write-Host "Copying Disk Lun $lun, Label : $disklabel, VHD : $vhdname, STATUS = " $copystate.Status
}
               
              
            
等到所有这些变为成功。
有关单个 blob 的信息:
#Check individual blob status
Get-AzureStorageBlobCopyState -Blob "danRegSvcAms-dansqlams1-2014-07-03.vhd" -Container $containerName -Context $xioContextnode2
步骤 21:注册 OS 磁盘
#change storage account to the new XIO storage account
Set-AzureSubscription -SubscriptionName $mysubscription -CurrentStorageAccount $newxiostorageaccountnamenode2
Select-AzureSubscription -SubscriptionName $mysubscription -Current
#Register OS disk
$osdiskimport = $diskobjects | where {$_.lun -eq "Windows"}
$osvhd = $osdiskimport.vhdname
$osdiskforbuild = $osdiskimport.diskName
#Registering OS disk, but as XIO disk
$xioDiskName = $osdiskforbuild + "xio"
Add-AzureDisk -DiskName $xioDiskName -MediaLocation  "https://$newxiostorageaccountnamenode2.blob.core.windows.net/vhds/$osvhd"  -Label "BootDisk" -OS "Windows"
#Build VM Config
$ipaddr = "192.168.0.4"
$newInstanceSize = "Standard_DS13"
#Join to existing Availability Set
#Build machine config into object
$vmConfig = New-AzureVMConfig -Name $vmNameToMigrate -InstanceSize $newInstanceSize -DiskName $xioDiskName -AvailabilitySetName $availabilitySet  ` | Add-AzureProvisioningConfig -Windows ` | Set-AzureSubnet -SubnetNames $subnet | Set-AzureStaticVNetIP -IPAddress $ipaddr
#Reload disk config
$diskobjects  = Import-CSV $file
$datadiskimport = $diskobjects | where {$_.lun -ne "Windows"}
ForEach ( $attachdatadisk in $datadiskimport)
{
    $label = $attachdatadisk.disklabel
    $lunNo = $attachdatadisk.lun
    $hostcach = $attachdatadisk.hostcaching
    $datadiskforbuild = $attachdatadisk.diskName
    $vhdname = $attachdatadisk.vhdname
    ###This is different to just a straight cloud service change
    #note if you do not have a disk label the command below will fail, populate as required.
    $vmConfig | Add-AzureDataDisk -ImportFrom -MediaLocation "https://$newxiostorageaccountnamenode2.blob.core.windows.net/vhds/$vhdname" -LUN $lunNo -HostCaching $hostcach -DiskLabel $label
}
#Create VM
$vmConfig  | New-AzureVM –ServiceName $destcloudsvc –Location $location -VNetName $vnet -Verbose
步骤 22:添加负载均衡终结点和 ACL
#Endpoints
$epname="sqlIntEP"
$prot="tcp"
$locport=1433
$pubport=1433
Get-AzureVM –ServiceName $destcloudsvc –Name $vmNameToMigrate  | Add-AzureEndpoint -Name $epname -Protocol $prot -LocalPort $locport -PublicPort $pubport -ProbePort 59999 -ProbeIntervalInSeconds 5 -ProbeTimeoutInSeconds 11  -ProbeProtocol "TCP" -InternalLoadBalancerName $ilb -LBSetName $ilb -DirectServerReturn $true | Update-AzureVM
#STOP!!! CHECK in the Azure portal or Machine Endpoints through PowerShell that these Endpoints are created!
#SET ACLs or Azure Network Security Groups & Windows FWs
#https://msdn.microsoft.com/library/azure/dn495192.aspx
步骤 23:测试故障转移
等待迁移的节点与本地 Always On 节点同步。 将其置于同步复制模式,并等待同步。 然后将故障从本地系统转移到已迁移的第一个节点,即 AFP。 一旦操作成功,将最后迁移的节点更改为 AFP。
应测试所有节点之间的故障转移,并运行并通过混沌测试,以确保故障转移按预期工作,并以及时的方式进行。
步骤 24:恢复群集仲裁设置 / DNS TTL / 故障转移指针 / 同步设置
在同一子网上添加 IP 地址资源
如果只有两个 SQL Server 并想要将它们迁移到新的云服务,但想要将它们保留在同一子网上,则可以避免让侦听器脱机删除原始 AlwaysOn IP 地址并添加新 IP 地址。 如果要将 VM 迁移到另一个子网,则无需执行此作,因为有一个引用该子网的其他群集网络。
在故障转移现有主服务器之前,您应先启动已迁移的辅助数据库并在新云服务中添加新的 IP 地址资源,然后在群集故障转移管理器中执行以下步骤:
若要添加 IP 地址,请参阅附录中的步骤 14。
- 对于当前 IP 地址资源,请将可能的所有者更改为“现有主 SQL Server”,例如“dansqlams4”:   
- 对于新的 IP 地址资源,请将可能的所有者设为“已迁移的辅助 SQL Server”,例如“dansqlams5”:   
- 设置后,可以进行故障切换,当迁移到最后一个节点时,应编辑可能的所有者,以便将该节点添加为可能的所有者。 