有人对构建服务器的虚拟机性能进行过基准测试吗?
我们一直在尝试使用虚拟机作为构建服务器。我们的构建服务器都在运行WinXP32,并且我们把它们放在运行Ubuntu 9.10的VMWare Server 2.0上。我们构建的内容包括C、C++、Python包,还有其他各种部署任务(比如安装程序、7z文件、归档等等)。使用VMWare托管的构建服务器管理起来非常方便。我们可以随意移动它们,利用一台大型8核机器上的共享系统资源,通过网页界面远程访问这些系统,总之管理起来更轻松了。
但是,问题是,与使用物理机器相比,性能似乎时好时坏,甚至有时候很糟糕,这让人很沮丧。有时候主机的系统负载会超过20,而有时候又会低于1。这似乎和实际在系统上完成的工作量没有太大关系。我怀疑系统中有瓶颈,但我找不到具体是什么。(最近怀疑是I/O问题,但我们有一块专用的1TB 7200RPM SATA 2硬盘,32MB缓存,专门用来运行虚拟机。看起来对于1-2台机器来说,这个配置是足够的。其他的硬件配置也都不错,8GB内存,每个虚拟机分配2GB,8个核心,每个虚拟机一个核心。)
所以在想尽了所有办法之后,我想向Stack Overflow社区求助。
- 有没有人运行过或者见过其他人在虚拟机中进行软件构建性能的基准测试?
- 我们应该对比物理系统期待什么样的表现?
- 我们牺牲了多少性能?
- 大家使用的硬件/虚拟机服务器配置是什么样的?
任何帮助都将不胜感激。
1 个回答
磁盘输入输出(IO)在这里确实是个问题,当你只有一个硬盘的时候,无法进行大量的磁盘IO操作。单个SATA硬盘的32MB缓存很快就会被主机和几个虚拟机的基本操作占满。如果你查看Ubuntu主机操作系统中的磁盘队列长度计数器,你会发现这个数字很高(在这个系统中,如果有两个硬盘,任何时间超过1就意味着有东西在等待这个磁盘)。
在为虚拟机配置基础设施时,我通常会估算每个虚拟机需要30到50个IOPS(每秒输入输出操作次数),这适用于那些对磁盘使用不多的系统。如果系统对IO活动的需求不高,可以稍微降低这个数字,但构建系统的IO模式通常会有很多随机的小读取。更糟糕的是,你希望有很多虚拟机同时在构建,这会让磁盘的竞争变得非常激烈。总体来说,磁盘带宽可能不是大问题(当IO模式完全顺序时,SATA硬盘的速度大约可以达到70-100MB/秒),但当文件小且分散时,你的IO会受到硬盘转速的限制,7.2k SATA硬盘大约只能处理每秒70-100个IO。在轻负载下,运行像VMware Server这样的二级虚拟机监控器的主机,可能会达到这个限制。
我的建议是构建一个RAID 10阵列,使用更小且更快的硬盘。10k的SAS硬盘每个可以提供100-150个IOPS,所以4个硬盘可以处理600个读取IOPS和300个写入IOPS,直到达到极限。同时确保你对存放VMDK文件的硬盘进行数据分区对齐,如果你把虚拟机文件放在RAID阵列中,这样可以提高20-30%的磁盘性能。对于这种情况,尽量避免使用RAID 5,因为空间便宜,而RAID 5的写入惩罚意味着你需要4个硬盘才能达到单个硬盘的写入性能。
还有一点要提的是,VMware Server在性能方面并不是一个很好的虚拟机监控器,如果可能的话,建议你转向一级虚拟机监控器(比如免费的ESXi v4)。虽然设置起来不简单,并且会完全失去主机操作系统,但你会发现整体的IO性能,尤其是磁盘和网络流量,会好得多。
编辑以回应你的评论。
1) 查看你现有的Ubuntu主机是否真的有问题。
我看到你尝试过dstat,但我觉得它提供的信息不够详细,可能无法让你了解发生了什么,不过我对它不太熟悉,所以可能错了。iostat可以给你一个很好的情况概述——这篇关于使用iostat的文章可以帮助你更好地了解磁盘的实际IO模式 - http://bhavin.directi.com/iostat-and-disk-utilization-monitoring-nirvana/。avgrq-sz和avgwq-sz是排队请求数量的原始指标。数字高通常不好,但具体的坏情况会因磁盘类型和RAID结构而异。你最终想知道的是,磁盘IO是否在队列中花费的时间比实际被服务的时间更长。计算(await-svctim)/await*100
可以告诉你磁盘是否在努力跟上,如果超过50%,那么你的IO在队列中等待的时间和被磁盘服务的时间差不多,如果接近100%,说明磁盘已经完全被压垮。如果你发现主机并没有真正受到压力,而VMware Server实际上表现不佳(这可能是事实,我在Linux平台上从未使用过它),那么你可以在转向ESXi之前尝试一下VirtualBox等其他选项。
2) 确定你需要什么。
基准测试一个在性能良好或可接受的系统上进行的典型构建的IO需求——在Windows上查看IOPS计数器——磁盘读取/秒和磁盘写入/秒计数器,并确保平均队列长度小于1。你需要知道在系统负载时的峰值值,瞬时峰值可能很高,如果一切都来自磁盘缓存,所以要关注持续的峰值值,持续一两分钟。得到这些数字后,你就可以规划一个能满足你需求的磁盘子系统。查看IO数字的原因是,它们反映了磁头完成读取和写入所需的实际切换(每秒IO次数,IOPS),除非你在进行大文件流式传输或完整磁盘备份,否则它们最准确地反映了磁盘在负载下的极限。
- 7.2k SATA硬盘 - 70-100 IOPS
- 10k SAS硬盘 - 120-150 IOPS
- 15k SAS硬盘 - 150-200 IOPS
请注意,这些数字是典型硬盘在最大负载和不利IO模式下的饱和能力的近似值。这是为最坏情况设计的,除非你真的知道自己在做什么,否则应该这样做。
RAID阵列可以让你的IO工作负载并行化,使用一个不错的RAID控制器,N个硬盘的RAID阵列可以提供N*(单个硬盘的基本IOPS)的读取IO。对于写入IO,由于RAID策略会产生惩罚——RAID 0没有惩罚,写入速度和读取一样快。RAID 5每个IO需要2次读取和2次写入(读取奇偶校验,读取现有块,写入新奇偶校验,写入新块),所以它的惩罚是4。RAID 10的惩罚是2(每个IO需要2次写入)。RAID 6的惩罚是5。要计算RAID阵列需要多少IOPS,你需要将操作系统所需的基本读取IOPS数字与操作系统所需的写入IOPS数字乘以相关的惩罚因子相加。
3) 现在计算出满足你性能需求的RAID阵列结构
如果你对一个物理基准系统的分析告诉你只需要4到5个IOPS,那么你的单个硬盘可能可以接受。我会很惊讶,但不要只听我的——获取你的数据并做出明智的决定。
假设你在基准测试中测得30个读取IOPS和20个写入IOPS,并且你希望能够支持8个这样的构建系统作为虚拟机。为了实现这一点,你的磁盘子系统需要能够支持240个读取IOPS和160个写入IOPS。根据你实际需要的系统数量调整你的计算。
如果你选择RAID 10(我强烈推荐),RAID 10牺牲容量以换取性能,但当你设计出足够的性能时,可以调整硬盘的大小以获得所需的容量,结果通常会比RAID 5便宜,除非你的IO模式涉及非常少的写入。你的硬盘需要能够提供560个IOPS(读取240,写入320,以考虑RAID 10的写入惩罚因子2)。
这需要:
- 4个15k SAS硬盘
- 6个10k SAS硬盘(向上取整,RAID 10需要偶数个硬盘)
- 8个7.2k SATA硬盘
如果你选择RAID 5,你需要调整以应对增加的写入惩罚,因此需要880个IOPS来提供你想要的性能。
这需要:
- 6个15k SAS硬盘
- 8个10k SAS硬盘
- 14个7.2k SATA硬盘
这样你会有更多的存储空间,但成本几乎是两倍,因为你需要更多的硬盘,并且需要一个相当大的机箱来容纳它们。这就是为什么如果性能有任何顾虑,我强烈推荐RAID 10。
另一个选择是找到一个好的SSD(比如Intel X-25E,而不是X-25M或其他便宜的型号),它的存储容量足够满足你的需求。买两个并设置为RAID 1,SSD的性能相当不错,但它们的故障率(即使是像X-25E这样的硬盘)目前比旋转硬盘要差,所以除非你准备处理系统崩溃的问题,至少要使用RAID 1。结合一个好的高端控制器,像X-25E这样的SSD在实际使用中可以轻松维持6000个IOPS,这相当于30个15k SAS硬盘。SSD每GB的容量成本相对较高,但如果使用得当,它们可以为IO密集型任务提供更具成本效益的解决方案。