本文属于SQL Server虚拟化系列
搭建SQL Server虚拟机,在各个组织之间都有自己的标准和最佳实践。从第一眼看去,光物理配置就有过百种,所有的这些细微差别都有可能为后续日常管理过程中故障侦测带来麻烦。如果创建一个合适的虚拟机模版,并用于后续新虚拟机的创建和部署,那么可以把很多部署问题最小化。
在本文中,会讨论“为什么”要针对当前SQL Server负载创建理想化的SQL Server虚拟机。下一章会演示对于目前主流的VMWare和Hyper-V虚拟环境的创建。
VM配置:
虚拟机包含了绝大部分传统物理机的组件——CPU、内存、网卡和存储。虚拟机仅仅变更了这些的配置和分配形式,但是这种变更必须跟操作系统挂钩才能生效。
虚拟CPU配置:
了解CPU的基础架构可以帮助你在指令管理中选择合适的CPU配置用于SQL Server 虚拟机。今时今日的CPU架构非常复杂和多样,服务器往往可以包含一个到16个CPU芯片插座,而每个物理CPU又可以分为多个虚拟CPU核心(core),一个物理CPU可以包含1个或最多16个cores。
对于虚拟机和新版hypervisors,可以配置虚拟CPU插槽数和虚拟CPU核心数,但是多少才是“合适”的呢?
在物理机世界,太少的CPU会限制SQL Server处理负载的能力。在虚拟机世界,也如此。另外一个极端现象就是太多CPU。在物理机环境中,CPU太多只是闲置率很高,而且会产生额外的热量,时刻等待着负载的增加。但是对于虚拟机,太多的CPU就不会相同了。
对于虚拟机,分配太多的CPU会导致性能下降,因为太多的虚拟CPU分配到一个虚拟机上时,会降低虚拟机的运行速度以及因为占了同一个物理机上CPU的资源从而造成额外的CPU争用。
因此,对每台SQL Server虚拟机选择合适数量的虚拟CPU个数成了这部分的关键点和难点,不仅因为这个缺乏足够负载分析导致的困难,也是因为这是一个不断变化的过程。
虚拟NUMA:
现代服务器中,存在多个CPU插槽,每个插槽包含一个CPU芯片,每个芯片又包含了多个虚拟核心。比如下图,一个逻辑CPU被配置到4个插槽,48个core的服务器中。每个插槽有一定数量的内存分配在上面。那么插槽和这部分内存的组合就属于一个NUMA(Non Uniform Memory Access,非一致性内存访问/节点)。其他操作系统线程可以在一个NUMA节点的一个core上访问来自于其他NUMA节点中的内存,但是由于物理路径的变长,导致路径复杂,从而降低速度。
新版的hypervisors通过改良的编码从而可以更好地利用NUMA,虚拟机的活动可以隔离到单一的NUMA节点从而最小化跨NUMA节点的开销,从而提升VM的性能。同时也可以扩展一个虚拟机的NUMA配置到操作系统,使得物理机器能够合理地平衡工作负载,使得应用程序能利用好NUMA的配置。
上图展示了2个不同的虚拟机虚拟CPU配置,每个虚拟机都配置了8个虚拟CPU。第一个虚拟机(左边)使用了2个虚拟插槽(小于每个NUMA节点的CPU封装调度数),每个插槽有4个虚拟核心。第二个VM使用默认配置,每个虚拟插槽对应一个虚拟核心,也就是8个虚拟插槽。
第一个配置中配置了同等规模的,跨两个物理CPU插座的配置,可能对于每个CPU插座工作负载而言是最佳配置。其内存访问方式可以配置成仅两个插槽,然后VM就知道如何通过查找每个虚拟NUMA节点的内存从而达到最高效的内存管理。
第二个配置中,把可能的负载分散到所有可用的虚拟CPU socket中,内存管理不如第一个配置好,从而可能有性能损失。
如果一个SQL Server虚拟机需要16个虚拟CPU来应付工作负载。那么如何下面的配置选项中哪个才是最优化的?
- 1个虚拟插槽(16个虚拟核心)。
- 2个虚拟插槽,每个8个虚拟核心。
- 4个虚拟插槽,每个4个虚拟核心。
- 8个虚拟插槽,每个2个虚拟核心。
- 16个虚拟插槽,每个1个虚拟核心。
DBA领域有一个名言:it depends(具体情况具体分析)。同样适合在这里使用,这个完全依赖于你的底层硬件、物理机器上的资源争用情况、应用程序对NUMA的识别程度等。幸运的是,SQL Server是一个识别NUMA的应用程序。所以可以使用特定配置,运行负载压测或者合成的基准工具( synthetic benchmarking utility ),然后得出性能指标。对于核心的应用程序,尽可能使用这种方式来得出最佳性能。
概括地说,如果使用上图的方式测试1个月,并使用上面5项的中间三种不同的配置测试。并使用 HammerDB模拟SQL Server负载,得到如下结果:
在这个测试中,使用4个虚拟CPU插槽,每个带有4个虚拟CPU核心(core),在每个测试中都最高,在64个并发用户中,比2插槽每个8个虚拟core的快31%。这个戏剧性的改进,不必要改动任何一行代码,而且是完全免费的。
我们的目标是配置一个合适某个工作负载的CPU给一台VM,并且通过NUMA配置使其最优化。如果分配到VM的内存要横跨NUMA节点,那么会降低VM的性能。所以确保物理机上的VM都能运行在相同的硬件配置上。如果不同的配置存在,那么需要单独的测试以便找出最合适的方案。
热添加(Hot-Add):
Hypervisors支持热添加,也就是在VM正在运行的过程中可以直接添加CPU和内存资源。但是当涉及NUMA影响时就要有所考虑,比如有一个CPU插槽,4个vCPU和16GB内存的虚拟机,然后添加13个虚拟CPU到虚拟机使其达到总数17个虚拟CPU时,NUMA如何均衡处理呢?从技术上是可以解决的,但是除非VM所在的物理机的CPU插槽数大于物理CPU core数,否则会因为内存寻址时跨NUMA导致性能下降。因此,不管启用任何一种形式热添加CPU或热添加内存,vNUMA扩展是不启用的。并且你很可能影响现有的SQL Server性能,因为VM的NUMA寻址因为热添加CPU或内存导致寻址跨NUMA。
所以这里建议不要启用运行了SQL Server的VM的热添加功能,除非你的实际情况需要这样做。
虚拟网络(Virtual Networking):
虚拟机需要一种方式来与物理网络互联,hypervisors通过创建名为虚拟网络的方式来打通虚拟机和物理机之间的网络。这个网络映射到虚拟交换机,本质上就是hypervisor内部的流量路由引擎( traffic routing engine),虚拟交换机连到物理机的一个或多个物理网络适配器上。当一个VM上的虚拟网络适配器被授予到一个特定的命名虚拟网络之后,网络流量就可以通过流量路由传出到物理网络上。
虚拟网络是可以有多个的,流量通常可以通过VLAN的扩展,被隔离或者重定向到一定数量的目标上。一个VLAN允许流量以特定方式传输流量或者路由,多个VLAN可以共享到一个物理网络适配器端口。每个虚拟网络被一个VLAN tag标记,并授予到特定VLAN的流量管道上。
如果你打算在虚拟机中配置Availability Groups(SQL Server AlwaysON),然后希望隔离开AG传输流量和备份流量。在下图的三个虚拟网络就是针对的配置方案:
在AlwaysON中的两台SQL Server(SQLAG01和SQLAG02)包含了3个虚拟网络适配器。第三台独立机器(SQL09)仅有两个,这些适配器都连到一个独立的虚拟网络。每个虚拟网络使用独立的VLAN tag或者VLAN 分配来配置。如果底层网络设置了不在多个VLAN之间路由流量,那么一台服务器上的网络适配器就识别不了其他VM的网络适配器。
比如上图的SQL09的流量是不会到VLAN61上,也不能通过VLAN61访问高可用组。这种配置可以使得AG流量被隔离开来,从而最大化性能,因为不用担心被其他虚拟机的流量影响,同时备份的流量也被隔离并且可以单独对它进行安全设置。如果引入虚拟范获取,能够进一步增加安全性。
虚拟硬盘(Virtual Disks):
存储系统可以在虚拟机中以多种方式展现,而每种方式都有优缺点。大部分VM管理员会使用虚拟硬盘的方式,如下图。在Vmware中以VMDK格式,在Hyper-V中一个VHDX为文件格式显示。一个虚拟硬盘是一个由hypervisor管理的共享的文件系统,从hypervisor角度来说,可以提供非常大的灵活性。虚拟硬盘可以被动态重新分配或者动态扩充而不需要中断对应的访客系统。对于SQL Server VM,使用这种硬盘方式几乎占有绝对的比例。
第二种方式在VMware中叫 Raw Device Mapped disk (RDM,原始设备映射磁盘),在Hyper-V中叫Pass-Through disk(直连磁盘)。存储被花费为SAN LUN,展现给所有物理服务器虚拟化集群。如下图,这种磁盘以红色箭头和盒子形状标识。但是,这些并不是由hypervisor为虚拟磁盘格式化和管理志勇,它被配置成单独分配给虚拟机的盘,并通过hypervisor直接从物理硬盘连到虚拟机。最终结果就是类似一个单独的SAN LUN直连到一个物理机器。
然而,一般情况下,RDM和直连磁盘的使用场景优先,因为卷的大小被有限制,在旧版的hypervisor中和VMware特定共享存储,对于如Windows Server故障转移群集的共享存储应用程序是锁定大小的。旧版本的hypervisor限制到2TB,但是vSphere 5.5放开了限制到64TB,Hyper-V也一样。在过去,RDM和直连磁盘的性能由于虚拟磁盘,但是现代hypervisor的差异已经小到可以忽略。
第三种虚拟机磁盘表现形式就是in-guest ,通常与iSCSI或SMB 3.0相关。在访客机中,允许虚拟机的操作系统连接到存储目标上,而不是由hypervisor控制。 这种方式的优势在于介于物理机和虚拟机之间,把LUN从一个服务器重定位到另外一个服务器中。这种设计可以减少大规模负载从物理服务器迁移到虚拟服务器中的停机时间。但是这种配置把特定设备的抽象功能移除,因此相对于VM的虚拟硬盘而言,降低了灵活性。
除非有特殊要求,否则虚拟硬盘通常是首选。在选择虚拟硬盘之前,不仅要对原始的SQL Server实例进行资料收集,还要对原始的服务器本身进行收集。因为工作负载可能存在于这个服务器上的非SQL Server之中。继续这些收集的资料,再决定适合工作负载的虚拟硬盘的配置。
比如下面这个例子,基于一个特定负载收集,在一个虚拟机中添加8个虚拟硬盘,并且分配常规的空间大小:
驱动器 | 大小(GB) | 目的 |
C | 60 | 操作系统 |
D | 20 | SQL Server实例安装路径 |
E | 20 | SQL Server系统库存放路径 |
F | 100 | 用户数据库数据文件 |
L | 40 | 用户数据库日志文件 |
T | 50 | TempDB 数据和日志文件 |
Y | 50 | Windows 分页文件 |
Z | 100 | 数据库本地备份盘 |
注意不是所有的SQL Server都需要按上面这种进行配置。 在负载较轻的SQL Server中,配置可能类似于这样:
驱动器 | 大小(GB) | 目的 |
C | 80 | 操作系统+SQL Server实例安装路径 |
F | 100 | 用户数据库数据文件 |
L | 40 | 用户数据库日志文件 |
T | 50 | TempDB数据和日志文件 |
Z | 100 | 数据库本地备份盘 |
就像在物理机上的SQL Server,通常的目标都是把负载分摊到合理的硬盘上,使其队列更小。如果一个进程仅有一个工作线程可用,那么端到端的系统堆栈的任何一个路径都有可能拥堵,从而成为系统瓶颈。如下图,一个只有单文件组和数据文件在一个卷(E盘)的SQL Server,存储请求会通过Windows OS的一个路径传输到虚拟层,然后通过HBA卡传到内联交换机,最终与SAN控制器和物理硬盘相连。
相对来说,添加多个文件组、数据文件、物理磁盘并确保路径被正确隔离最小化可能的瓶颈,可以使得hypervisor和物理层更好地分摊负载。如下图。
隔离负载的目标和类型也体现了终端用户如何管控卷的灵活性上。比如,如果一个Windows或者SQL Server SP需要安装,那么管理员可以针对虚拟磁盘创建一个VM层面的快照,但是此时可能会排除掉数据库的卷,以免在系统回滚时丢失已提交的事务。
SQL Server的系统库:master、model和msdb,被单独放在一个卷中,因为如果系统要使用高级功能如镜像或者高可用组(Availability Groups),可以把这个硬盘放到更快的存储上面从而提供更好的性能。
Windows操作系统的页文件也是独立的,如果在繁重的SAN到SAN复制机制下,就应该这样做。这些文件放在非标准位置可以使得这个单个虚拟硬盘放在复制频率远低于其他卷的SAN的卷中,节省了复制带宽。
数据库备份目标是用于本地存储备份文件。和Windows的页文件类似,可以通过防止在低速盘来节省开销。
TempDB由于自身特性被独立放置在单独的盘中。如果TempDB在资源争用明显的硬盘,会导致TempDB争用等待。
同理,对数据文件和日志文件的配置也需要这样考虑。基于负载的不同,空间和分盘策略都会有所不同。
总结:
理解虚拟环境的核心概念和核心组件配置对DBA在数据库虚拟机创建和管理方面都是非常必要的。如果已经有服务器运行在虚拟环境上,那么可以检查并调整。接下来两节将分别介绍VMware和Hyper-V上的操作。
下一节:
S QL Server 虚拟化(3)——在Vmware上搭建SQL Server
本文属于SQL Server虚拟化系列