談談個人微軟特約稿:《SQL Server 2014 新特性:IO資源調控》

一.本文所涉及的內容(Contents)

  1. 本文所涉及的內容(Contents)
  2. 背景(Contexts)
  3. 撰寫經歷(Experience)
  4. 特約稿正文(Content-body)
    1. 第一部分:生活中資源調控器;
    2. 第二部分:SQL Server中資源調控器;
    3. 第三部分:SQL Server資源調控器運用場景—CPU;
    4. 第四部分:SQL Server資源調控器運用場景—IO;
    5. 第五部分:總結;
    6. 第六部分:做者簡介;
  5. SQL Server 2014 新特性文章連接(IT168)

二.背景(Contexts)

  寫這篇文章的目的是想記錄此次的撰寫文章的經歷,其實一篇技術文章來得並不容易,以前本身寫博客的隨意性很強,排版能夠根據本身喜愛,可是一篇文章要被你們所接受,讓你們願意讀完實際上是一件很難的事情,因此排版仍是挺重要的,這裏我想提示下IT168的編輯,個人SQL代碼實際上是有高亮的,可是編輯發出來後發現高亮不見,閱讀起來的確很不爽,估計你們也有一樣的感受。再者就是講講此次的技術內容,其實在SQL Server 2014以前就有資源調控器這個功能了,因此網上也很多這方面的資料,因此要寫這個主題就須要找到一些新的亮點(新功能+通俗類比),這也是讀者感興趣的地方。我對寫這篇文章還有一個感覺就是,你須要不斷修改、完善你文章的內容,包括總體文章的架構是否合理?語言描述是否通順?邏輯是否清晰?內容是否豐富?測試案例是否全面等等。因此這篇文章給我最大的感覺是:一篇憑良心出品的文章的確來之不易html

  2014年5月7日,從宋沄劍宋大俠得知有一個爲IT168和微軟撰寫SQL Server 2014新功能文章的機會,撰寫的內容爲:SQL Server 2014的資源調控器(Resource Governor),這裏再次感謝宋大俠的推薦。sql

三.撰寫經歷(Experience)

  1. 接到任務的時候在忙公司的事情,簡單看了看這個功能在網上的介紹,大概瞭解下以後就繼續忙其它工做了;
  2. 過了幾天,感受是時候動手撰寫這篇文章了,繼續查資料,簡單作了下構思,就動手搭了文章的基本框架;
  3. 框架搭建完,寫了部分的描述,這須要一個環境進行測試,立刻想到了在Azure建立一個帶有SQL Server 2014的虛擬機,簡單的測試了Resource Governor的CPU控制功能;
  4. 繼續寫內容,忽然有個靈感,我想把生活中的BRT引用到文中來,由於他們之間有着許多的共同點,並且能夠做爲開篇,讓讀者一會兒就能在生活中找到共鳴;
  5. 努力找BRT的圖片當中;
  6. 看到MSDN上關於Resource Governor的架構圖,感受有些不妥,因而就本身畫了一個新的,並且我也能夠畫一個關於BRT的架構圖,把公路資源這種畫到圖裏面去,更加能經過BRT架構圖引出Resource Governor的架構圖;
  7. 對Resource Governor的IO進行了測試和場景的設計與分析;
  8. 繼續對文章的架構進行調整,組織語言,初稿出來了;
  9. 把文章發給宋沄劍,但願能獲得一些建議,首先獲得了他的確定,同時他建議在開頭和結尾加入雲服務的概念,立刻動手,肯定後,再發一次給他,他轉發給了IT168的編輯,在期待中煎熬度過;
  10. 過了幾天,想了想,爲了不編輯的修改建議,繼續對文章進行再一次的修改,不管從語言、結構、描述等等方面繼續完善,看得都感受要吐了,再次轉發給宋沄劍了;
  11. 2014年5月27日,從宋沄劍那裏得知,文章一次性經過了IT168和微軟的審覈了,爽了;
  12. 2014年5月28日,文章在IT168的首頁發佈了;

四.特約稿正文(Content-body)

特此說明:因爲版權的緣由,這裏的正文爲引用IT168的稿件地址:http://tech.it168.com/a2014/0526/1627/000001627131_all.shtml數據庫

 

  【IT168 專稿】在數據庫服務器上,有三種硬件資源一直是影響數據庫性能好壞的關鍵,甚至會影響到整個生產系統的使用,這三種資源分別是內存CPU和物理IO。當數據庫服務器上掛載了多個數據庫的時候,極有可能發生資源的爭奪,如何能保證重要數據庫在擁有足夠資源的前提下再把多餘的資源提供給其它數據庫呢?資源調控器應運而生。api

在SQL Server 2014中已經增長了對物理IO資源的控制,這個功能在私有云的數據庫服務器上的做用體現得尤其重要,它可以爲私有云用戶提供有效的控制、分配,並隔離物理IO資源。服務器

 

1、生活中資源調控器架構

  在講述SQL Server 2014的資源調控器(Resource Governor)以前,讓咱們來找一找生活中資源調控器的影子。你們都知道一線城市的交通能夠用擁堵一詞來形容,你時常能夠見到如圖1所示的路面情況。框架

wps_clip_image-5695
▲圖1:生活中的資源調控器——城市交通函數

  爲了緩解擁堵的交通,北京、上海、廣州等城市都修建了一個稱之爲BRT的交通設施,BRT的全稱爲Bus Rapid Transit,意爲快速公交,就是在擁堵的公路上分配一條專門提供給公交車使用的車道,儘可能保證大部分人出行的通暢。BRT專用車道的大體狀況如圖2所示。性能

wps_clip_image-18657
▲圖2:生活中的資源調控器——BRT專用車道測試

  交通部門規定:在出行高峯期,BRT專用道只供公交車使用,其它機動車只能使用BRT專用道以外的車道資源。人有專門的人行道,自行車有自行車道。根據這個邏輯,能夠得出如圖3所示的人與車在使用道路資源的邏輯結構圖:

wps_clip_image-27152
▲圖3:道路資源邏輯結構圖

 

2、SQL Server中資源調控器

  瞭解了生活中的資源調控器以後,咱們立刻進入今天的主題:SQL Server資源調控器,它與生活中的資源調控器有着驚人的類似之處。

  SQL Server 2014的資源調控器默認包含了兩個工做負荷組(internal、default)和兩個資源池(internal、default),在沒有手動設置資源調控器的狀況下,建立的數據庫會默認放到default資源池當中。

  SQL Server資源調控器接收到會話請求後,經過用戶定義的分類器函數把會話進行劃分並路由到相應的工做負荷組,再經過工做負荷組找到對應的資源池,由資源池中設置的內存CPU和物理IO資源的閥值來決定會話請求的資源分配。根據描述,能夠得出如圖4所示的SQL Server資源調控器邏輯結構圖:

wps_clip_image-9078
▲圖4:SQL Server資源調控器邏輯結構圖

 

3、SQL Server資源調控器運用場景—CPU

  理解了SQL Server資源調控器的原理以後,接着講述資源調控器在CPU方面的運用場景:假設數據庫服務器上有一個重要的數據庫ImportantDB和一個普通的數據庫GeneralDB,從業務出發,但願服務器上的資源在知足了ImportantDB以後才考慮分配多餘的資源給GeneralDB,保證重要業務系統的正常運行。

  須要說明的是:筆者的機器是Azure上的虛擬機,機器的配置如圖5所示,下面的測試都是基於這個環境的,因此讀者在自行測試的時候應該根據本身的機器環境進行調整。

wps_clip_image-2010
▲圖5:硬件環境

假設GeneralDB 數據庫佔用的CPU最大值爲10%,ImportantDB數據庫佔用的CPU最大值爲90%,實現這個需求的步驟以下:

1. 建立測試數據庫

--建立重要業務數據庫
CREATE DATABASE ImportantDB
GO
--建立普通業務數據庫
CREATE DATABASE GeneralDB
GO

2. 建立並配置新的資源池和工做負荷組

--建立重要業務數據庫的資源池
CREATE RESOURCE POOL rpImportantDB
WITH
(
     MAX_CPU_PERCENT = 90,
     MIN_CPU_PERCENT = 10
)
GO
--建立重要業務數據庫的工做負荷組
CREATE WORKLOAD GROUP wgImportantDB
WITH
(
     IMPORTANCE = MEDIUM
)
USING rpImportantDB
GO
 
--建立普通業務數據庫的資源池
CREATE RESOURCE POOL rpGeneralDB
WITH
(
     MAX_CPU_PERCENT = 10,
     MIN_CPU_PERCENT = 0
)
GO
--建立重要業務數據庫的工做負荷組
CREATE WORKLOAD GROUP wgGeneralDB
WITH
(
     IMPORTANCE = LOW
)
USING rpGeneralDB
GO

3. 更新內存中資源調控器的配置

--更新內存中的配置
ALTER RESOURCE GOVERNOR RECONFIGURE
GO

4. 查詢資源調控器中資源池和工做負荷組的配置信息,返回結果如圖6所示:

--查詢獲取資源池和工做負荷組配置
USE master
SELECT * FROM sys.resource_governor_resource_pools
SELECT * FROM sys.resource_governor_workload_groups
GO

wps_clip_image-12952
▲圖6

5. 建立分類器函數,這是一個用戶自定義函數 (UDF),它供資源調控器用來對會話進行分類,以便將它們路由到對應的工做負荷組中,函數返回工做負荷組的名稱;

--建立分類器函數
CREATE FUNCTION fn_Classifier()
RETURNS SYSNAME
WITH SCHEMABINDING
AS
BEGIN
    DECLARE @strGroupName SYSNAME
    IF ORIGINAL_DB_NAME()='ImportantDB'
        SET @strGroupName='wgImportantDB'
    ELSE IF ORIGINAL_DB_NAME()='GeneralDB'
        SET @strGroupName='wgGeneralDB'
    ELSE 
        SET @strGroupName='default'
    RETURN @strGroupName
END
GO

6. 將分類器函數fn_Classifier註冊到資源調控器並更新內存中的配置

--註冊分類器函數到資源調控器並更新內存中的配置
ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = dbo.fn_Classifier)
ALTER RESOURCE GOVERNOR RECONFIGURE
GO

7. 接下來就是對CPU進行測試,建立能佔用CPU的測試腳本,把下面的腳本分別保存爲GeneralDB.sql和ImportantDB.sql:

--測試CPU
DECLARE @Counts INT
WHILE 1=1
BEGIN
    SELECT @Counts=COUNT(*) FROM SYS.COLUMNS A,SYS.COLUMNS B
END

8. Windows操做系統爲SQL Server資源調控器提供了大量的性能計數器幫助瞭解資源的使用狀況,查看SQLServer:Resource Pool Stats對象下的CPU usage%計數器,裏面包括四個對象實例:default、internal和剛剛建立的rpGeneralDB、rpImportantDB,如圖7所示:

wps_clip_image-19850
▲圖7:添加計數器

9. 由於分類器函數fn_Classifier 經過函數ORIGINAL_DB_NAME()返回用戶在數據庫鏈接字符串中指定的數據庫名稱,因此能夠經過使用SQLCMD來模擬用戶輸入,SQLCMD調用GeneralDB.sql和ImportantDB.sql腳本的命令以下:

SQLCMD -S . -d GeneralDB -i GeneralDB.sql

SQLCMD -S . -d ImportantDB -i ImportantDB.sql

10. 性能計數器CPU usage%記錄了在測試過程當中CPU的使用狀況,結果如圖8所示: 

wps_clip_image-607
▲圖8:性能計數器

  執行GeneralDB.sql後,藍色實例rpGeneralDB佔用了25%左右的CPU;接着在另外的窗口執行ImportantDB.sql後,紫色實例rpImportantDB一樣佔用了25%左右的CPU,以一樣的方式繼續增長紫色實例rpImportantDB的CPU佔用量,當佔用量超過了設置的90%,能夠發現藍色實例rpGeneralDB佔用CPU百分比立刻降低了。從這個測試的結果來看,SQL Server資源調控器已經達到咱們預期對CPU資源的規劃效果。

  值得一提的是,你們可能已經發現rpImportantDB資源池的CPU usage%計數器的最新值高達97.470%,資源池不是設置了MAX_CPU_PERCENT = 90嗎?怎麼會超過這個限制呢?其實這是由於rpGeneralDB資源池的MIN_CPU_PERCENT = 0,因此在沒有其它最小CPU的限制的話,rpImportantDB資源池佔用的CPU是有可能達到100%的。

 

4、SQL Server資源調控器運用場景—IO

  前面講述關於CPU資源的控制更多的是爲下面講述SQL Server 2014在IO資源上的調控作鋪墊,上面的例子是以數據庫爲單位規劃各個庫佔用CPU的百分比,下面的例子咱們就將以登錄用戶來劃分磁盤的IOPS;

  假設generalUser用戶佔用的IOPS最大值爲10,importantUser用戶佔用IOPS的最大值爲20,實現這個需求的步驟以下:

1. 首先,解除分類器函數與資源調控器註冊關係;

USE [master]
GO
--解除分類器函數註冊
ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = NULL)
GO

2. 接着,修改rpImportantDB、rpGeneralDB資源池,添加MAX_IOPS_PER_VOLUME和MIN_IOPS_PER_VOLUME兩個屬性值;

--修改重要業務數據庫的資源池
ALTER RESOURCE POOL rpImportantDB
WITH
(
     MAX_CPU_PERCENT = 90,
     MIN_CPU_PERCENT = 10,
     MAX_IOPS_PER_VOLUME = 20,
     MIN_IOPS_PER_VOLUME = 0
)
 
--修改普通業務數據庫的資源池
ALTER RESOURCE POOL rpGeneralDB
WITH
(
     MAX_CPU_PERCENT = 10,
     MIN_CPU_PERCENT = 0,
     MAX_IOPS_PER_VOLUME = 10,
     MIN_IOPS_PER_VOLUME = 0
)
GO

3. 接着修改分類器函數fn_Classifier(),把它修改爲按照登錄用戶:importantUser和generalUser(這兩個登錄用戶請自行建立,爲了方便測試,這兩個用戶都是管理員身份)返回對應的工做負荷組名稱;

--修改分類器函數
ALTER FUNCTION fn_Classifier()
RETURNS SYSNAME
WITH SCHEMABINDING
AS
BEGIN
    DECLARE @strGroupName SYSNAME
    IF SUSER_SNAME()='importantUser'
        SET @strGroupName='wgImportantDB'
    ELSE IF SUSER_SNAME()='generalUser'
        SET @strGroupName='wgGeneralDB'
    ELSE 
        SET @strGroupName='default'
    RETURN @strGroupName
END
GO

4. 從新把分類器函數fn_Classifier()註冊到資源調控器並更新內存中的配置;

--註冊分類器函數到資源調控器並更新內存中的配置
ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = dbo.fnClassifier)
ALTER RESOURCE GOVERNOR RECONFIGURE
GO

5. 在GeneralDB數據庫中建立一個名爲TestIOPS的表,並向表中插入10000行記錄;

USE [GeneralDB]
GO
--建立表
CREATE TABLE [dbo].[TestIOPS](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [MyStr] [nchar](450) NULL
) ON [PRIMARY]
GO
 
--插入測試數據
SET NOCOUNT ON;
GO
DECLARE @count INT = 0;
WHILE (@count < 10000)
BEGIN
    INSERT INTO [GeneralDB].[dbo].[TestIOPS](MyStr) 
        VALUES(REPLICATE('a',450));
    SET @count +=  1;
END
GO

6. 使用generalUser用戶登錄SSMS,經過在TestIOPS表的MyStr字段建立一個非彙集索引來測試IOPS,在執行建立索引的腳本以前,打開性能計數器幫助監控建立索引時的IOPS,找到SQLServer:Resource Pool Stats對象下的Disk Write IO/sec計數器,計數器監控的結果如圖9所示:

USE [GeneralDB]
GO
--建立索引
CREATE NONCLUSTERED INDEX idx_MyStr_1 ON [GeneralDB].[dbo].[TestIOPS] ([MyStr]);
GO

wps_clip_image-3405
▲圖9:計數器監控結果

  從圖9能夠看出資源池rpGeneralDB 中Disk Write IO/sec計數器的最大值爲10,發生Disk Write IO/sec的時間從22:54:52持續到22:55:02,持續時間大概爲20秒;

7. 接着,使用importantUser用戶登錄SSMS,建立上一步驟中同樣的索引結構,只須要修改索引名稱便可,一樣須要監控SQLServer:Resource Pool Stats對象下的Disk Write IO/sec計數器,計數器監控的結果如圖10所示:

USE [GeneralDB]
GO
--建立索引
CREATE NONCLUSTERED INDEX idx_MyStr_2 ON [GeneralDB].[dbo].[TestIOPS] ([MyStr]);
GO

wps_clip_image-237
▲圖10:Write IO/sec計數器監視結果

  從圖10能夠看出資源池rpImportantDB 中Disk Write IO/sec計數器的最大值爲20,發生Disk Write IO/sec的時間從22:59:52持續到23:00:11,持續時間大概爲9秒;

  經過上面資源調控器的IOPS的測試,能夠發現即便兩個用戶執行了相同操做,但IOPS卻能夠根據不一樣用戶而有所區別,這徹底歸功於資源調控器對IO資源的控制,這將爲數據庫主機或者私有云上運行IO密集型工做負載提供解決方案。

 

5、總結

  資源調控器(Resource Governor)在沒有資源爭奪的時候,那麼運用能夠分配到100%資源,若是達到了分類器函數的臨界值,會按照預先分配的比例進行調配,從而保證重要業務在資源緊缺的狀況下順利進行,加強對數據庫的管理性。SQL Server 2014的新功能中提供了一個很是重要的IO資源控制,這將爲私有云用戶提供更人性化的管理和服務。

 

做者簡介

  陳暢亮,微軟SQL Server最有價值專家,目前就任於廣州某互聯網公司任數據庫團隊Leader,專一於數據庫解決方案與性能調優。

 

五.SQL Server 2014 新特性文章連接(IT168)

相關文章
相關標籤/搜索