最近连续做了几个微软虚拟化解决方案的售前演示,其实对于大部分客户来讲不会对一整套“相对完善”的方案在第一时间就看的很深入,反而通常会更在意一些最基础的功能和配置选项,特别是技术岗位的人往往都会有“先入为主”的情绪,这很正常,假设客户使用了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虚机提供服务)
正确的监视方式应该是使用perfmon.exe来看,为什么呢?因为Windows Server一旦启用了hypervision(虚拟化层),那么物理机OS将与GusetOS处于同一级,也就是说你可以理解成物理机OS与虚拟机OS在共享物理资源,他们是平级的;举个例子你给hyper-v中的一台虚机vCPU加压,然后在物理机中直接通过任务管理器-性能-是看不出有变化的,而通过perfmon-hyperv logical processor-total run time就可以看到真实的物理CPU使用情况
######################################################################################
有关hyper-v上面的虚拟NUMA节点先说这么多,在一些有针对性的需求时,还是很有意义的;这篇文章我也是参考了许多中英博文总结出来的,个人感觉很有意义并且认为很有必要分享出来,感兴趣的朋友们可以抽空测一测,欢迎随时与我交流,谢谢!