閱讀989 返回首頁    go 技術社區[雲棲]


在阿裏雲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可用性組的軟件解決方案,讀者可以先大致閱讀,稍後詳細介紹:

粘貼圖片.png

核心組件概述

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)中。
11.png

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指令配置:
22.png

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創建,通過向導創建比較容易,然後根據提示操作,不再把所有圖片貼出來了:
333.png

也可以使用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:
5555.png

至此,AlwaysOn可用性組就全部創建成功,請讀者看看,這三個圖,在不同的副本上截取的,有些地方是不同的,這體現了主副本和輔助副本,同步和異步的複製關係:
777.png

888.png

999.png

20.**創建HAVIP**

請谘詢VPC/HAVIP產品經理開通HAVIP白名單,然後在用戶控製台上關聯到兩個同步的ECS上,注意,一定是同步複製的數據庫副本上的ECS,HAVIP(高可用虛擬IP)必須與偵聽器的IP一致,監聽的端口也是和偵聽器的端口一致:
123.png

12345.png

20.**創建隻讀的SLB**

這個就很簡單了,將隻讀的ECS綁定到SLB,指定權重就好了,不再累述。

注意事項

1. 這個解決方案中是沒有域控的,所以在配置上有很多安全上的要求

2. 如果需要加入域控,那麼配置AlwaysOn的安全就不再需要

3. 該方案將是產品化方案的一個雛形,產品化將會在不久的將來推出,產品化的方案會在權限方麵有所控製,同時自動化能力會非常高,將是一種PaaS服務

最後更新:2017-05-11 14:31:12

  上一篇:go  Oracle DBCA高級玩法:從模板選擇、腳本調用到多租戶
  下一篇:go  多級緩存:支撐海量讀服務的瑞士軍刀