VM性能的快速测试方法

By , December 24, 2012 10:16 pm

前段时间陆续发布了一些对公有云服务性能评测的数据。经常有同行问我怎么样去做这些性能评测。其实这些性能评测都很简单,任何一个具备Linux基础知识的工程师都可以完成。我们通常使用UnixBench来评估虚拟机CPU性能,mbw来评估内存性能,iozone来评估文件IO性能,iperf来评估网络性能,pgbench来评估数据库性能。在这里我将我自己做性能测试的过程整理一下,供各位同行参考。

(0)安装必要的软件

假定VM的操作系统是Ubuntu,可以按照如下步骤安装必要的软件:

sudo apt-get install python-software-properties
sudo add-apt-repository ppa:pitti/postgresql
sudo apt-get update
apt-get install libx11-dev libgl1-mesa-dev libxext-dev perl perl-modules make gcc nfs-common postgresql-9.1 postgresql-contrib-9.1 mbw iperf

cd ~
wget http://www.iozone.org/src/current/iozone3_414.tar
wget http://byte-unixbench.googlecode.com/files/UnixBench5.1.3.tgz
tar xvf iozone3_414.tar
tar zxvf UnixBench5.1.3.tgz

cd ~/iozone3_414/src/current
make

cd ~/UnixBench
make

(1)CPU性能测试

我们使用UnixBench来进行CPU性能测试。UnixBench是一套具有悠久历史的性能测试工具,其测试结果反映的是一台主机的综合性能。从理论上来说UnixBench测试结果与被测试主机的CPU、内存、存储、操作系统都有直接的关系。但是根据我们的观察,对于现代的计算机系统来说,UnixBench测试结果受CPU 处理能力的影响更大一些。因此,在这里我们用UnixBench测试结果来代表虚拟机的vCPU 处理能力。每个UnixBench测试结果包括两个数据,一个是单线程测试结果,另一个是多线程测试结果(虚拟机上有几颗虚拟CPU,就有几个并发的测试线程)。

cd ~/UnixBench

./Run

下面是一个可供参考的测试结果。在这个测试中使用了两台物理机,每台物理机各配置一颗Intel Core i3 540 @ 3.07 GHz (双核四线程),16 GB内存(DDR3 @ 1333 MHz),一块Seagate ST2000DL003-9VT1硬盘(SATA,2TB,5900RPM),运行Ubuntu 10.04 AMD64 Server操作系统,使用的文件系统为ext4,使用的Hypervisor为KVM(qemu-kvm-0.12.3)。我们分别测试了宿主机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在本地磁盘上的虚拟机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在NFS上的虚拟机的CPU性能。虚拟机的配置为2 颗vCPU(占用两个物理线程,也就是一个物理核心)和4 GB内存,运行Ubuntu 12.04 AMD64 Server操作系统。在这个测试中没有对操作系统、文件系统、NFS、KVM等等进行任何性能调优。

测试场景 宿主机 本地磁盘上的虚拟机 NFS服务上的虚拟机
单线程 1360 1365 1374
多线程 3250 2529 2536

从如上测试结果可以看出,在没有进行任何性能调优的情况下,在单线程CPU性能方面,宿主机 >> 本地磁盘上的虚拟机 >> NFS服务上的虚拟机;在多线程CPU性能方面,宿主机 >> 本地磁盘上的虚拟机 = NFS服务上的虚拟机。需要注意的是,在多线程测试结果方面,宿主机所占的优势完全是由于宿主机比虚拟机多占用了两个物理线程,也就是一个物理核心。可以认为,在如上所述测试中,物理机和虚拟机的CPU性能基本上是一致的,虚拟化基本上没有导致CPU性能损失。

(2)文件IO性能测试

我们使用iozone来进行文件IO性能测试。iozone性能测试结果表示的是文件IO的吞吐量(KBps),但是通过吞吐量可以估算出IOPS。在如下命令中,我们评估的是以256K为数据块大小对文件进行写、重写、读、重读、随机读、随机写性能测试,在测试过程当中使用/io.tmp作为临时测试文件,该测试文件的大小是4 GB。需要注意的是,命令中所指定的测试文件是带路径的,因此我们可以测试同一虚拟机上不同文件系统的性能。例如我们通过NFS将某一网络共享文件系统挂载到虚拟机的/mnt目录,那么我们可以将该测试文件的路径设定为/mnt/io.tmp。

cd ~/iozone3_414/src/current

./iozone -Mcew -i0 -i1 -i2 -s4g -r256k -f /io.tmp

下面是一个可供参考的测试结果。在这个测试中使用了两台物理机,每台物理机各配置一颗Intel Core i3 540 @ 3.07 GHz (双核四线程),16 GB内存(DDR3 @ 1333 MHz),一块Seagate ST2000DL003-9VT1硬盘(SATA,2TB,5900RPM),运行Ubuntu 10.04 AMD64 Server操作系统,使用的文件系统为ext4,使用的Hypervisor为KVM(qemu-kvm-0.12.3)。我们分别测试了宿主机、NFS、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在本地磁盘上的虚拟机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在NFS上的虚拟机、以及从虚拟机内部挂载宿主机NFS服务(虚拟网卡启用了virtio)的磁盘IO性能。虚拟机的配置为2 颗vCPU(占用两个物理线程,也就是一个物理核心)和4 GB内存,运行Ubuntu 12.04 AMD64 Server操作系统。在这个测试中没有对操作系统、文件系统、NFS、KVM等等进行任何性能调优。

测试场景 write re-write random write read re-read random read
宿主机 114398 115766 67757 4621231 4897959 4899447
NFS 51482 51253 35867 114914 4332976 476465
本地磁盘上的虚拟机 12447 22257 19664 542379 887648 468469
NFS服务上的虚拟机 7414 4433 4975 97238 581717 209665
虚拟机中的NFS 32650 31772 22076 84982 111296 88263

从如上测试结果可以看出,在如上所述特定测试场景中,在文件IO性能方面,宿主机 > NFS > 虚拟机中的NFS > 本地磁盘上的虚拟机 >NFS服务上的虚拟机。值得注意的是,即使是从虚拟机中挂载NFS服务,其文件IO性能也远远超过本地磁盘上的虚拟机。

[特别说明]需要注意的是,当我们说文件(或者磁盘)IO性能的时候,我们指的通常是应用程序(例如iozone)进行文件读写操作时所看到的IO性能。这个性能通常是与系统相关的,包括了多级缓存(磁盘自身的缓存机制、操作系统的缓存机制)的影响,而不仅仅是磁盘本身。利用iozone进行文件IO性能测试时,测试结果与主机的内存大小、测试数据块的大小、测试文件的大小都有很大的关系。如果要全面地描述一个特定系统(CPU、内存、硬盘)的文件IO性能,往往需要对测试数据块的大小和测试文件的大小进行调整,进行一系列类似的测试并对测试结果进行全面分析。本文所提供的仅仅是一个快速测试方法,所提供的测试参数并没有针对任何特定系统进行优化,仅仅是为了说明iozone这个工具的使用方法。如上所述之测试数据,仅仅在如上所述之测试场景下是有效的,并不足以定性地说明任何虚拟化场景下宿主机和虚拟机的文件IO性能差异。建议读者在掌握了iozone这个工具的使用方法的基础上,对被测试对象进行更加全面的测试。(感谢saphires网友的修改建议。)

(3)内存性能测试

我们使用mbw来测试虚拟机的内存性能。mbw通常用来评估用户层应用程序进行内存拷贝操作所能够达到的带宽(MBps)。

mbw 128

下面是一个可供参考的测试结果。在这个测试中使用了两台物理机,每台物理机各配置一颗Intel Core i3 540 @ 3.07 GHz (双核四线程),16 GB内存(DDR3 @ 1333 MHz),一块Seagate ST2000DL003-9VT1硬盘(SATA,2TB,5900RPM),运行Ubuntu 10.04 AMD64 Server操作系统,使用的文件系统为ext4,使用的Hypervisor为KVM(qemu-kvm-0.12.3),虚拟机运行Ubuntu 12.04 AMD64 Server操作系统。我们分别测试了宿主机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在本地磁盘上的虚拟机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在NFS上的虚拟机的内存性能。虚拟机的配置为2 颗vCPU(占用两个物理线程,也就是一个物理核心)和4 GB内存。在这个测试中没有对操作系统、文件系统、NFS、KVM等等进行任何性能调优。

测试场景 宿主机 本地磁盘上的虚拟机 NFS服务上的虚拟机
MEMCPY 3245 3332 3261
DUMP 3165 3317 3255
MEMBLOCK 9605 9091 8739

从如上测试结果可以看出,在没有进行任何性能调优的情况下,宿主机、本地磁盘上的虚拟机、NFS服务上的虚拟机在内存性能方面基本上是一致的,虚拟化基本上没有导致内存性能损失。

(4)网络带宽测试

我们使用iperf来测试虚拟机之间的网络带宽(Mbps)。测试方法是在一台虚拟机上运行iperf服务端,另外一台虚拟机上运行iperf客户端。假设运行服务端的虚拟机的IP地址是192.168.1.1,运行客户端的虚拟机的IP地址是192.168.1.2。

在服务端执行如下命令:

iperf -s

在客户端执行如下命令:

iperf -c 192.168.1.1

测试完成后,在客户端会显示两台虚拟机之间的网络带宽。

下面是一个可供参考的测试结果。在这个测试中使用了两台物理机,每台物理机各配置一颗Intel Core i3 540 @ 3.07 GHz (双核四线程),16 GB内存(DDR3 @ 1333 MHz),一块Seagate ST2000DL003-9VT1硬盘(SATA,2TB,5900RPM),运行Ubuntu 10.04 AMD64 Server操作系统,使用的文件系统为ext4,使用的Hypervisor为KVM(qemu-kvm-0.12.3)。我们分别测试了宿主机之间、宿主机与虚拟机之间、虚拟机与虚拟机之间的内网带宽。虚拟机的配置为2 颗vCPU(占用两个物理线程,也就是一个物理核心)和4 GB内存。虚拟机的配置为2 颗vCPU(占用两个物理线程,也就是一个物理核心)和4 GB内存,运行Ubuntu 12.04 AMD64 Server操作系统。在这个测试中没有对操作系统、文件系统、NFS、KVM等等进行任何性能调优,但是虚拟机的网卡启用了virtio。

测试场景 宿主机之间 宿主机与虚拟机之间 虚拟机与虚拟机之间
内网带宽 930 920 850(虚拟机运行在不同的宿主机上)

从如上测试结果可以看出,宿主机之间的内网带宽接近内网交换机的极限。在启用了virtio的情况下,宿主机与虚拟机之间内网带宽有小幅度的性能损失,基本上不会影响数据传输能力;虚拟机与虚拟机之间的内网带宽有接近15%的损失,对数据传输能力影响也不是很大。

(5)数据库性能测试

postgresql是一个著名的开源数据库系统。在MySQL被Sun 公司收购并进一步被Oracle公司收购之后,越来越多的公司正在从MySQL迁移到postgresql。pgbench是一个针对postgresql的性能测试工具,其测试结果接近于TPC-B。pgbench的优点之一在于它能够轻易地进行多线程测试,从而充分利用多核处理器的处理能力。

在虚拟机上以postgres用户登录:

su -l postgres

将/usr/lib/postgresql/9.1/bin加入到路径PATH当中。

创建测试数据库:

createdb pgbench

初始化测试数据库:

pgbench -i -s 16 pgbench

执行单线程测试:

pgbench -t 2000 -c 16 -U postgres pgbench

执行多线程测试,在下面的命令中将N替换为虚拟机的vCPU数量:

pgbench -t 2000 -c 16 -j N -U postgres pgbench

下面是一个可供参考的测试结果。在这个测试中使用了两台物理机,每台物理机各配置一颗Intel Core i3 540 @ 3.07 GHz (双核四线程),16 GB内存(DDR3 @ 1333 MHz),一块Seagate ST2000DL003-9VT1硬盘(SATA,2TB,5900RPM),运行Ubuntu 10.04 AMD64 Server操作系统,使用的文件系统为ext4,使用的Hypervisor为KVM(qemu-kvm-0.12.3),虚拟机运行Ubuntu 12.04 AMD64 Server操作系统。我们分别测试了宿主机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在本地磁盘上的虚拟机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在NFS上的虚拟机的数据库性能。虚拟机的配置为2 颗vCPU(占用两个物理线程,也就是一个物理核心)和4 GB内存,运行Ubuntu 12.04 AMD64 Server操作系统。在这个测试中没有对操作系统、文件系统、NFS、KVM等等进行任何性能调优。

测试场景 宿主机 本地磁盘上的虚拟机 NFS服务上的虚拟机
单线程 126 24 14
多线程 146 31 17

从如上测试结果可以看出,在没有进行任何性能调优的情况下,在数据库性能方面,宿主机 >> 本地磁盘上的虚拟机 >> NFS服务上的虚拟机。

 

13 Responses to “VM性能的快速测试方法”

  1. 陈自欣 says:

    在进行测试的过程中,有没有在宿主机及虚拟机上面,执行Nmon ,取得相应的性能相关指标,来获知两者之间的性能状况关系?

  2. qyjohn says:

    没有。这个测试基本上是从最终用户的角度来评估特定IaaS服务是否可用的。

  3. saphires says:

    virtual to virtual的网络throughput,如果在同一个主机上,基本上是远大于virtual to host, 或host to host的。您的virtual to virtual是在两个不同主机上的guest吧?

  4. saphires says:

    个人觉得iozone这个测试需要再斟酌一下。您的物理机内存是16GB,那么在物理机里面的读写性能基本上被cache影响了。拿4621231 KB/s,就是4.6GB/s来看,这个不可能是磁盘的性能。而您这里面没有说明虚拟机的内存是多少。看887648 KB/s这个数字,一定程度上还是收益于cache,但是估计应该是小于你的数据大小4GB的。如果您做一个8GB RAM的guest,估计会有不同的结果。

  5. qyjohn says:

    谢谢Saphires的提醒。我修改了一下原文,补充说明了VM的配置。iozone结果受各级缓存的影响比较大,尤其内存大小对读操作测试的结果有较大影响,因为/io.tmp是刚刚被写入的。写操作的测试有较高的参考价值,基本上可以定性地说明由于虚拟化导致的性能损失。(由于这个教程是一个入门级的教程,所以没有能够对磁盘IO的各个层面进行详细说明。)

  6. saphires says:

    我想说的是用这篇博文里面的iozone参数会有一定的误导。在结果里面cache对磁盘性能的影响太大了,不能客观的体现出磁盘的性能。比如我在稍微大一点的环境里面,用你的iozone参数得到如下结果。虚拟机里面的”IO性能”是高于物理机的。
    guest(4 vcpu, 8GB virtual RAM)
    4194304 256 724488 721595 4543823 4605643 4893937 358028

    host(2 x X5675(6cores), 12 x 8GB DDR3-1333)
    4194304 256 162413 151756 4214050 4045935 4207819 168335

  7. qyjohn says:

    我已经说过,这篇文章是从最终用户的角度来对VM的性能进行评价。如果用同样的测试方法和测试参数去测试不同的VM,那么基于所得到的结果是可以对VM性能进行对比的,并且这种对比是严格地与测试方法和测试参数相关的。

    你所得到的测试结果,可疑之处在于虚拟机的写性能远大于物理机的写性能,原因不明。合理之处在于虚拟机的读性能和物理机的读性能基本在一条水平线上,主要的原因在于内存足够大。

    根据我在多个不同的云平台上的测试结果,换一个配置高一点的虚拟机并不能够显著提高写性能。你可以看看我关于HP Cloud Services的性能测试结果。http://www.qyjohn.net/?p=2326

  8. saphires says:

    不好意思,写偏高是因为虚拟机和物理机的根分区使用了不同性能的LUN,我调换过来了,现在基本一致,不过还是略高。

    guest(4 vcpu, 8GB virtual RAM)
    4194304 256 724488 721595 4543823 4605643 4893937 358028

    host(2 x X5675(6cores), 12 x 8GB DDR3-1333)
    4194304 256 523525 584130 6740869 4762088 4832464 632843

    可能是我没表述清楚,其实我想说的是这个测试的文件大小设置得太小了,导致cache对结果影响太大,进而影响到几组结果的公平。http://www.iozone.org/docs/IOzone_msword_98.pdf里明确的写了run rule. If you wish to get accurate results for the entire range of performance for a platform you need to make sure
    that the maximum file size that will be tested is bigger than the buffer cache.

    您测试中物理机中文件大小远小于内存大小,而虚拟机中的文件大小等于内存大小。从你的结果来看,虚拟机的磁盘性能大约为物理机的1/10,这一点是非常误导人的,可能被解读为虚拟环境的IO能力是物理环境的1/10。就拿读来说,4621231展现的是file被cache的性能,而542379展现的是cache和磁盘混合的性能。这两个数字没有可比性。你看我那个测试,两个的读性能几乎是一致的,正如你说讲,是因为两个文件读都建立在cache上。

    也就是对于您这个特定环境,也许应该用32g的文件大小来做比较,结果会更具有可比较性和参考性。

    同理于http://www.qyjohn.net/?p=2326的结果。为什么读在medium到large会有显著提升?因为RAM从4G涨到8G,展现的是cache read了。如果你把size变成512M,或者32G,你会看到所有的线,包括读或者写都是几乎水平的。不是因为medium到large的磁盘性能有性能提高,而是因为特定的测试参数造成了那个“提高”。

  9. qyjohn says:

    这个评测是从最终用户的角度出发,对不同的虚拟机进行比较,而不是对虚拟机和物理机的性能做比较。在虚拟机上,测试文件的大小是有局限性的。在多个公有云平台上,根分区的大小只有10GB左右,因此选择4GB作为测试文件的大小是合适的。

    仅仅用RAM增加来解释medium到large的读性能增长是不通的。论据很简单,在HP Cloud Services这个案例中,同样是RAM从2G增加到4G,large实例的系统盘读性能提升了,数据盘性能并没有得到提升。

  10. saphires says:

    > 这个评测是从最终用户的角度出发,对不同的虚拟机进行比较,而不是对虚
    > 拟机和物理机的性能做比较。在虚拟机上,测试文件的大小是有局限性的。
    > 在多个公有云平台上,根分区的大小只有10GB左右,因此选择4GB作为测
    > 试文件的大小是合适的。
    因为您的http://www.qyjohn.net/?p=2715
    上有各种环境的比较。

    另外,如果size有局限,可以用direct io来消除cache对读的影响。
    还是那句话,4GB在hpcloud上的测试是不甚合理的。要么选择一个大于所有instance内存的size,让io都落到磁盘上去;要么选择一个小于所有instance内存的size,让io都落到cache去。
    一半disk, 另一半cache,这样的结果没有太好的可比性。
    >
    > 仅仅用RAM增加来解释medium到large的读性能增长是不通的。论据很简
    > 单,在HP Cloud Services这个案例中,同样是RAM从2G增加到4G,large实
    > 例的系统盘读性能提升了,数据盘性能并没有得到提升。
    >
    不是仅仅,而是主要。
    就拿4621231这个数来说,您觉得测出来4.6GB/s的磁盘读性能能说明什么问题?如果不是cache的因素,您觉得什么样的磁盘能达到1GB/s–5GB/s的读性能?

    您如果不想增大size,那么把size减小试试,看还能有medium->large->xlarge的显著提升么?或者拐点换到small->medium了?

  11. qyjohn says:

    真是不明白,为啥你会这么死心眼呢。文章的题目讲的很清楚,是对VM性能评测,并且是一个快速测试方法。文章的第一段也再次强调,这些方法是针对公有云VM的。如果要对不通的公有云以及不同的VM类型进行比较,那么就应该对不同的公有云和不同的VM类型都采用同样的测试参数,这样的测试才是公平的。

    只要有一点基础知识的人都知道,测试结果是严格地与测试参数相关的。当你换了测试参数之后,测试结果会是不一样的。这篇入门级文章的目的是告诉需要做性能测试的人有这些工具,当他了解了这些工具之后,他慢慢地会根据自己的需要去深入学习相关的工具,并进一步调整自己的测试参数。

    在HP Cloud Services这个例子中,RAM增加的确不是系统读性能提升的主要原因。具体的原因我跟HP Cloud Services团队讨论过,跟我在相关文章的猜测是一致的。由于有保密协议的原因,在这里不能够把细节公布出来而已。

    从iozone的角度来出发,当我们说磁盘IO性能的时候,我们指的是应用程序(iozone)进行读写操作时所看到的IO性能。这个性能通常是与系统相关的,包括了多级缓存(磁盘自身的缓存机制、操作系统的缓存机制)的影响,而不仅仅是磁盘本身。

  12. […] 本文转自蒋青野的技术博客http://www.qyjohn.net/?p=2715 […]

  13. qyjohn says:

    安装postgresql时候遇到LOCALE问题的解决办法:

    (1)编辑/etc/environment,在文件的最后加如下一行,然后重启:

    LC_ALL=”en_US.utf-8″

    (2)如果数据库还没有初始化,需要初始化数据库:

    pg_createcluster 9.2 main –start

    (3)用postgres用户登录进行操作。

Leave a Reply

Panorama Theme by Themocracy