Hyper-V和NUMA架構那點事兒
最近連續做了幾個微軟虛擬化解決方案的售前演示,其實對于大部分客戶來講不會對一整套“相對完善”的方案在***時間就看的很深入,反而通常會更在意一些最基礎的功能和配置選項,特別是技術崗位的人往往都會有“先入為主”的情緒,這很正常,假設客戶使用了N多年的VMware或者他是思杰鐵粉兒,那么你懷揣著一套microsoft環境去給人家講的時候,可能對方會先問一些hyper-v管理器的功能,甚至會問的很細,不要小看這些看似“不起眼”的功能選項,恰恰會成為不同廠商之間競爭的有力砝碼或成為整套方案基礎架構的核心支柱
#################################################################################
這篇文章主要以Hyper-V當中的NUMA功能來做一些說明,我本人也是這兩天花時間查閱了一些資料,希望能給有需要的朋友提供一些幫助
【非統一內存訪問(NUMA)是一種用于多處理器的電腦記憶體設計,內存訪問時間取決于處理器的內存位置。 在NUMA下,處理器訪問它自己的本地存儲器的速度比非本地存儲器(存儲器的地方到另一個處理器之間共享的處理器或存儲器)快一些。】
以上就是就是NUMA架構的大致意思,有關這項技術的更多概念,大家可以很輕松的在百度或者維基上查閱到。那么它的優點和價值在何處呢?
我們以SQL服務來舉例說明,在此我會轉載一些SQL支持組官方博客的文章http://blogs.msdn.com/b/apgcdsd/archive/2011/11/16/sql-server-numa.aspx
下圖就描述了一個比較形象的NUMA架構:
我們有兩個NUMA結點。每個NUMA結點有一些CPU, 一個內部總線,和自己的內存,甚至可以有自己的IO。每個CPU有離自己最近的內存可以直接訪問。所以,使用NUMA架構,系統的性能會更快。在NUMA結構下,我們可以比較方便的增加CPU的數目。而在非NUMA架構下,增加CPU會導致系統總線負載很重,性能提升不明顯。
每個CPU也可以訪問另外NUMA結點上的內存,但是這樣的訪問,速度會比較慢。我們要盡量避免。應用軟件如果沒有意識到這種結構,在NUMA機器上,有時候性能會更差,這是因為,他們經常會不自覺的去訪問遠端內存導致性能下降。
####################################################################################
對NUMA架構有了大致了解后,我們來說一說Hyper-V中的虛擬NUMA節點配置,下圖是我個人電腦上的CPU屬性,很難過的是——它不支持硬件NUMA架構;但是對于某些服務,我們可以實現軟件模擬多NUMA節點,比如SQL可以通過修改注冊表來實現,大家可以在本文上部的鏈接中查閱
同樣在性能監視器中(perfmon.exe),我們可以添加本機的“hyper-v VM vid NUMA node”來查看當前hyper-v使用的節點數量,下圖還是我的個人電腦,只顯示了一個node0,并且頁面數量1025851000;用頁面數量*頁面大小(4k)=4GB,這個就是我這臺電腦的實際物理內存
####################################################################################
接下來咱們換一臺服務器看看,CPU是兩顆,雙核,支持超線程;那么2*2*2=8,你會看到8個邏輯CPU
同樣我們可以看到這臺設備支持硬件NUMA;并且是兩個節點;這樣我們就能自己算一下,32G內存+8個邏輯CPU,分成兩份兒,那么一個節點就是16G內存+4邏輯CPU
同樣我們在性能監視器中可以看到兩個節點;即node0與node1,并且下面對應的頁面數量和處理器數量分別是16GB和4顆LCPU
接下來我們找一臺虛擬機,在設置中找到“處理器”下面的“NUMA”;我們可以看到有一個硬件拓撲,如果選擇了“硬件拓撲”,則系統會把這臺服務器的NUMA架構直接映射過來,以這臺服務器為例,也就是“每節點16G+4LCPU”;但是如果你的這臺虛擬機上確實要跑一些高性能的并行運算且需要NUMA架構支持,那么簡單的映射物理服務器配置可能不是***選擇;
以下圖為例:這臺虛機中有一個SQL實例,虛機配置是4G+4vCPU;我將它配置成了2個虛擬NUMA節點,那么每節點就是2vCPU+2G內存;且每個CPU插槽默認最多支持1個節點,于是我這臺VM就有兩個socket(插槽);如果你把這臺虛機看成物理機的話,那么它就是一臺擁有“兩顆物理CPU,每顆CPU雙核或單核雙線程,4G內存”的機器
這樣一來,我們這臺虛機就是一臺支持NUMA架構的機器了,如果結合本文開篇提到的SQL NUMA環境;那么我們就能更加靈活的來對數據庫服務進行調優
我們啟動這臺虛機,進入系統之后查看windows應用程序日志,找到對應的SQL 17152日志,可以看到有兩條,分別顯示了兩個節點的配置狀態,node0與node1;這就說明這臺虛機已經按照之前的規劃成功的實現了NUMA架構的模擬
同樣在SQL服務器屬性中,可以在“處理器”選項中看到當前識別到的NUMA節點;你可以讓SQL自動的關聯,或者手動關聯
對比一下我本機的SQL配置,只有一個節點
######################################################################################
講到這里,我再轉載一下SQL開發小組的文章:
SQL Server 不僅僅在引擎上支持NUMA, 而且在連接層面上也支持NUMA。如果沒有在連接層面上對NUMA進行設置的話,那么每一個連接進來,SQL Server會根據round-robin方式,選擇NODE 進行處理。在NODE內部,SQL Server會選擇CPU負載***的一個CPU進行處理。這種方法的缺點是,有可能某一個NODE內的所有CPU都很忙,但是另外一個NODE內的所有CPU都很空。導致資源不均衡。這種情況下,使用NUMA架構性能反而會下降,還不如使用非NUMA架構。系統能均衡分配CPU資源。
如下圖所示,我們用round-robin方式,可能NUMA NODE0會非常繁忙,而NUMA NODE1會非常空閑,系統資源不能充分利用。重要的連接可能會被分配到NODE0, 導致不能得到及時處理,性能受到影響
為此,在連接上,我們可以做設置。對于重要的操作,我們使用端口1450, 該端口會綁定NUMA結點0, 1, 2, 而對于不重要的操作(可能需要耗費大量資源,但不重要的),我們使用端口1433, 該端口會綁定NUMA結點3, 這樣,不重要的操作不會對重要的操作在性能上有所影響
如何設置端口對NUMA結點的綁定呢?我們可以在偵聽的端口后面加NUMA結點信息;還是拿剛才演示的那臺虛機來說;有2個NUMA結點,如果要使用NUMA結點0 那么根據轉換二進制的方式,相應的數值是1;這個就跟我們計算子網掩碼時候一樣,在對應的節點數下面寫1,然后轉換成二進制就好
NUMA NODE NUMBER |
1,0 |
Mask for 1 |
0,1 |
然后把算好的值加在你要監聽的端口后面就行了,比如我要某一項服務在0,1節點上都跑,那么在1433端口后面加個[3]就行了
#######################################################################################
接下來我們在回到Hyper-V的話題上,宿主機支持NUMA架構的話,那么系統會自動把虛機分配到某一個節點上跑,我們還是拿剛才這臺SQL服務器來說明;先安裝一個winrar,然后運行自帶的性能測試來給CPU加壓
可以看到虛機的CPU使用率負載馬上出現了變化
這個時候再來看一下宿主機,在性能監視器中添加“hyper-v VM vid partition”,可以看到當前這臺“10.12_TFS_DB”的虛機跑在了節點1下(參考preferred NUMA node index=1),并且邏輯CPU使用率只占用了4個
######################################################################################
那么這里就會出現一個問題,一個NUMA節點的資源畢竟是有限的,這種架構說白了就是給物理資源進行了一個分組;把若干個邏輯CPU和若干大小的內存進行了綁定,以此來提高CPU對內存訪問的命中率,有效減少了前端總線的瓶頸;但若此時多臺虛機被分配到了同一節點時,可偏偏這個節點的資源又被吃滿了怎么辦?
其實這種場景下CPU通常不會是瓶頸,出問題的往往又是內存;于是乎總有一臺突破臨界點的虛機要去跨節點訪問內存了;這時候問題就來了,NUMA架構就是為了劃分節點邊界,使數據交互盡量保持在各自節點內進行,結果這么一跨訪問;又會出現性能下降的問題了,而且不光本節點的這臺虛機受影響,還會侵占被訪問節點的資源;那么有沒有什么辦法來人為控制一下呢?肯定是有的,先來看一下跨節點訪問時的效果吧
我們同時開啟多臺虛機,盡可能分配一些大內存;如下圖所示
這時有意思的事情出現了,我們三臺虛機DC、DB還有WEB都跑在了節點1上面,但是呢DC這臺機器的“remote physical pages”出現了數值,這就是遠程訪問其他節點的內存;我們這臺宿主機就倆節點,所以它一定是用到了節點0的資源;并且你可以通過頁面大小來計算出它吃了多少非本地內存
####################################################################################
為了盡可能避免上述情況的發生,特別是面對一些對性能指標很敏感的需求時,我們就要手動的來限制一下;下面這個腳本是從msdn博客上挖來的,可以指定某臺虛機與某個numa節點來做綁定,鏈接如下:
直接執行腳本會出現提示,支持三個參數:/list列出當且宿主機上的虛機名稱;/set來做綁定;/clear來解除綁定
下面針對DC這臺虛機來做一個綁定,讓它去節點0上面跑,而不要跨節點的占用資源(關閉虛機后運行/set參數)
再回到性能監視器,可以看到此時“10.11_DC”這臺虛機已經轉移到了節點0上面了
再回到宿主機上觀察CPU使用率,可以看到目前所有邏輯處理器基本都以被占用了(說明節點0正在專注的為DC虛機提供服務)
######################################################################################
有關hyper-v上面的虛擬NUMA節點先說這么多,在一些有針對性的需求時,還是很有意義的;這篇文章我也是參考了許多中英博文總結出來的,個人感覺很有意義并且認為很有必要分享出來,感興趣的朋友們可以抽空測一測,歡迎隨時與我交流,謝謝!