[Azure][SQL]測試 Azure SQL Database 的彈性資料庫集區( Elastic database pool )

[Azure][SQL]測試 Azure SQL Database 的彈性資料庫集區( Elastic database pool )

前一陣子有看到 Azure SQL Database 有推出一個 Preview 的功能 ─ 「彈性資料庫集區」( Elastic database pool ),但因為每個月的 Azure 額度幾乎都用光了,因此只有大概知道這個功能,就沒有實際去測試了。最近剛好要準備一場關於 Azure SQL Database 的演講,加上善心人士願意借我 Azure 的額度進行測試,因此就利用這幾天晚上的時間做個測試。

 

在介紹這個之前,我先用自己所整理的一張圖來介紹,在 Azure SQL Database 有不同的「服務層級」 ( Database Service Tiers ),不同的服務層級具有不同的「資料庫輸送量單位」( DTU ),DTU 是一個量化的指標,當 DTU 增加時,服務層級所提供的處理能力也會隨之提升,當然伴隨的每個月的成本也會提高不少。目前來看,服務層級是「標準」( Standard ) 的時候,每一個 DTU 一個月的平均成本是 NT$46.55,但如果升級到「高階」(Premium) 的時候,則每一個 DTU 一個月的平均成本會提高到 NT$115.4

image

 

而當 DTU 提高的時候,效能真的會如果指標般的成長嗎 ? 像服務層級 S0 的 DTU 是 10,S1 的 DTU 是 20,真的 S1 會有 S0 兩倍的效能嗎 ? 這裡我用 SQL Server 上常見的範例資料庫 AdvantureWork,將他上傳到 Azure SQL Database 上,產生四個相同的資料庫,名稱是 S0 , S1 , S2 和 S3,也配置相同名稱的服務層級。

image

 

因為一般指令通常執行都很快速,實在比較不出時間,因此這次就寫了一個很笨的 Store Procedure,故意不符合 SARG,用來測試在不同服務層級下的執行時間

CREATE PROCEDURE [dbo].[TEST]
AS
BEGIN
	SET NOCOUNT ON
	DECLARE @PTR INT
	DECLARE @A INT
	DECLARE @DATA TABLE ( Id INT IDENTITY(1,1), [Year] INT,  Price Money )

	SET @A = ( CAST( RAND()*1000 AS  INT ) % 16 )
	SET @PTR = 0
	WHILE @PTR < 200
	BEGIN
		WITH detail as
		(
			select a.*,c.ListPrice from Sales.SalesOrderHeader a
				join Sales.SalesOrderDetail b ON a.SalesOrderID = b.SalesOrderID
				join Production.Product c ON  b.ProductID = c.ProductID
				join Production.ProductSubCategory d ON c.ProductSubCategoryID = d.ProductSubCategoryID
				where c.Name > 'A' AND b.CarrierTrackingNumber > '1' AND SalesOrderNumber > '1' AND ( a.SalesPersonID-274 = ( @A + @PTR%2 ) )
		)
		INSERT INTO @DATA([Year],[Price])
			SELECT YEAR(ShipDate), max( ListPrice ) from detail group by YEAR(ShipDate);
		SET @PTR += 1 ;
	END

	SELECT AVG([Price]) AVG_Price FROM @DATA 
END

 

因為懶得慢慢去統計,因此又寫了一個可以執行多次的統計用的 Store Procedure

 

CREATE PROCEDURE [dbo].[TEST_SUMMARY]( @Total INT = 10 )
AS
BEGIN
	DECLARE @Calc TABLE ( Id INT Identity(1,1), Seconds INT );
	DECLARE @PTR INT = 0 ;
	DECLARE @Start DATETIME ;

	WHILE @PTR < @Total
	BEGIN
		SET @Start = GETDATE()
		EXEC TEST
		INSERT INTO @Calc(Seconds) VALUES ( DATEDIFF( ss, @Start, GETDATE()) );
		SET @PTR +=1 ;
	END

	SELECT COUNT(*) Total,MIN(Seconds)[MIN],MAX(Seconds)[MAX],AVG(Seconds)[AVG],STDEV(Seconds)[STDEV] FROM @Calc
END

 

我們將不同的服務層級時間做個整理,可以從下面的表中看出來,隨著 DTU 的提高,執行時間也會按照一定的比例去縮減。( 並不一定所有測試都會有類似的比例,這只是透過上面的測試指令出來的結果 )

image

 

那這跟我們要談的「彈性資料庫集區」又有甚麼關係呢 ? 雖然 Azure SQL Database 可以按著你的需要去動態調整服務層級,但隨著我們的資料的增加之後,我們可能會利用 Scale out 的方式,將資料分散在不同的 Azure SQL Database 上,此時如果我們將每個資料庫的服務層級都設定很高,那麼可能相對的成本也高,設定太低,則可能執行效能不佳。利用彈性資料庫集區的話,就是你所選定的資料庫可以一起共用你所設定的 DTU 集合,而設定的時候還可以設定每個資料庫所能使用的上限和下限,這樣如果某些資料庫臨時需要比較高的 DTU 則可以自動提升上去使用,但也不會因為總 DTU 都被分配光了,造成某些資料庫完全不能執行的困擾。

 

在目前的版本中因為還是屬於 Preview 階段,目前只能使用 PowerShell 指令或者是到新的 Portal 網站( 後面指的 Portal 都是這個 )上去設定,在舊的 Azure Portal 上是無法設定的。當我們在 Portal 上選擇 「SQL 彈性級區」的時候,你會發現上面並沒有新增的按鈕。

image

 

你必須到 「SQL Server」下的節點,選擇 v12 版本的 SQL Server 實體,才能看到有「新增集區」的按鈕

image

 

如果第一次使用新增集區的話,因為這個是 Preview 的版本,因此要先接受「預覽條款」才可以使用。在建立資料集區的時候有幾點要注意一下:

1. 資料集區跟資料庫服務層級在效能和售價上類似,一共有三種不同的層級的資料集區 基本、標準和高階

2. 不同層級的資料集區,會影響單一個資料庫所能使用的 DTU 上限

3. 每個集區的價格除了 DTU 會有費用外,每多增加一個資料庫到集區內都會增加一些費用

image

 

在上例中我建立一個資料集區 ElasticPool-200,我設定這個 Pool 有 200 eDTUs,共有四個資料庫加入到這個集區內,每個資料庫所能使用的 DTU 介於 10~100 DTU 之間。

image

 

設定好之後我們就可以來測試一下,看原本測試的數據會有甚麼樣的變化,是否真的能動態配置,首先我先測試四個依序執行,也就是先跑 S0 , 等執行完畢再跑 S1,按照這樣的順序測試看四台跑出來的數據為何,看起來跟我們上面測試使用 S3 100DTU 的服務層級差不多。

image

 

接下來我們測試如果四個資料庫都一起執行的狀況,看起來有些搶到比較多的 DTU,有些配置會是比較低的,但都比我們設定的最低的 10 DTU 的狀況來的好

image

 

因此假設原本的四個資料庫如果我們都採用 S3 100DTU 的服務層級,則四個大約會花費 NT$18,620 ,但如果類似的狀況配置一個 200 eDTUs 的資料集區,則只需要 NT$14,121,如果你的資料庫不是都一值在使用高 DTU 的狀況下,使用動態分配的方式相對來說會比較划算一點。

 

因為資料庫集區一建立就要收費,所以如果你不沒有資料庫要使用的時候,一定要記得刪除,否則他還是會有發生費用。反之如果設定之後,覺得不需要再使用的話,那麼你必須先把原本在集區內的資料庫,都先重新設定服務層級,確定該資料庫集區內沒有資料庫之後,該資料庫集區才可以刪除。