Improve disk I/O performance in KVM

When getting started with KVM sometimes the choices available can be overwhelming. This is especially true when it comes to creating the virtual disks used by your virtual machines. Recently I was experiencing extremely poor performance on my personal/home KVM server, that I had not seen on my production systems. In this case the slow down was during fresh installs of CentOS and then taking snapshots of a running guest. After some quick searching I came across this article, KVM I/O slowness on RHEL 6 that has some useful information about improving the performance of a virtual guest. I ran the battery of tests documented in that article with my own server. The results are extremely compelling and I am changing how I provision VMs for KVM. Outlined are three basic ways to improve the disk I/O performance of your virtual guests managed by libvirt.

Methods to improve Disk I/O

For the non-readers, I’ll sum up what I found. Explanations and further details follow.

#1 – Paravirtual with virtio

The first way to improve performance is to use the virtio disk controller. The virtio devices are the paravirtual interfaces for disk and net I/O in KVM. This is built into the Linux kernel since 2.6.25 and was also backported into CentOS 5. For additional details see Virtio.

To use the virtio disk device, you can use something like the following,

1
2
3
4
5
6
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='none'/>
      <source file='/vmstore/images/centos_test0_preallc.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <address type='drive' controller='0' bus='0' unit='0'/>
    </disk>

In virt-manager the setting Disk Bus is under the Advanced options for the virtual disks. Similiar to the image below,

virt-manager_nocache1.png

#2 – Preallocation

The second performance improvement can be done when creating a virtual disk, by setting preallocation. For qcow2 images this setting is set to metadata. Use something like the following to create a 20GB disk.

1
# qemu-img create -f qcow2 -o preallocation=metadata centos_test0_preallc.qcow2 20G

There is no way to create a qcow2 virtual disk with preallocation in virt-manager-0.8.7. The allocation setting in virt-mananger-0.8.7 only applies to the raw format.

Converting existing disks

If you’ve already created images without preallocation, you can still convert them without losing data, but I still recommend you make a backup copy just to be safe. I did not attempt the conversion on live VMs, and am unsure if it’s possible. It only took a matter of seconds to convert my disk images which were 50GB in size.

1
# qemu-img convert -f qcow2 -O qcow2 -o preallocation=metadata centos_test0_nopreallc.qcow2 centos_test0_preallc.qcow2

#3 – Disable Cache Mode

The third recommendation is setting the Cache mode to None. Use something like the following in your VM’s XML definition

1
2
3
4
5
6
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='none'/>
      <source file='/vmstore/images/centos_test0_preallc.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <address type='drive' controller='0' bus='0' unit='0'/>
    </disk>

In virt-manager the setting Cache mode is under the Advanced options for the virtual disks. See the image for #1.

The Results

The tests I performed was doing a minimal install of CentOS 6.0 x86_64 to four different virtual guests.

  1. Preallocation=metadata with write-through cache
  2. Preallocation=metadata with no cache
  3. No preallocation with write-through cache
  4. No preallocation with no cache

I timed each install from the the beginning of installing the first package till the “Reboot” screen appeared. Below is the actual figures from these tests and a graph to illustrate the results.

Test Type Time (MM:SS)
Preallocation, write-through 3:48
Preallocation, no cache 3:12
No preallocation,write-through 4:51
No preallocation, no cache 4:34

graph_install

Based on the results, it’s clear that to achieve the best disk I/O performance using QCOW2 images you need to enable preallocation and disable caching.

Comments (0)

› No comments yet.

Leave a Reply


*

Allowed Tags - You may use these HTML tags and attributes in your comment.

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>