Experimenting with Compressed Swap

The Intel X25 has once again encouraged me to find something very interesting. I've been reading a bit about the X25’s “endurance management” feature. It sounds as though the drive switches to some sort of slower write strategy if the average writes per day continually exceed an average of 20 GB per day.

My laptop doesn't tend to swap at all most of the time. Even under my heaviest memory usage, when I have multiple test virtual machines running, I only seem to dip about 200 MB or so into my swap.

Testing Out compcache

Ubuntu 9.04 seems to ship with an older version of compcache. I decided to build my own modules from the latest tarball. The instructions of the website were very straightforward, and I had things up and running in no time.

So far I have not compiled a kernel with the 'swap free notify' patch applied. It does look like it would be very useful, since it would allow compcache to free up unused swap space much faster.

For testing purposes I disabled my original swap partition. I initialized a ramzswap device with the default size (25% of total memory) and activated it. Here is what free showed before I tried to fill up more memory than I ever would in practice:

             total       used       free     shared    buffers     cached
Mem:       3310124    3105004     205120          0     194312    1777532
-/+ buffers/cache:    1133160    2176964
Swap:       827524          0     827524

swapon -s shows:

Filename                            Type            Size    Used    Priority
/dev/ramzswap0                          partition   827524  0       100

I fired up six QEMU machines with memory sizes between 384 and 512 MB for a total of 2432 MB.

Here is what free looked like after letting the machines boot up and settle down for a bit:

             total       used       free     shared    buffers     cached
Mem:       3310124    3293424      16700          0       1768      86740
-/+ buffers/cache:    3204916     105208
Swap:       827524     600916     226608

At this point, cached data dropped from 1.7 GB down to under 100 MB and the poor little laptop was pushing 600 MB into swap. The rzscontrol program can show us some interesting statistics about the swap space that is in use:

OrigDataSize:     575584 kB
ComprDataSize:    157969 kB
MemUsedTotal:     159260 kB

rzscontrol is showing that 575 MB of data is currently swapped out and it is only taking up 159 MB of RAM. If that ratio holds steady, I could fill that 800 MB swap space and only eat up a little over 200 MB of RAM.

I even got a little meaner and started running memtest86+ in the virtual machines to make sure I wasn't getting extra special results because of zeroed out pages. I couldn't get the compression ratio to drop past 3:1.

I also tried a similar experiment using physical swap… It brought my laptop to a crawl. When swapping to compcache it didn't feel any different than when I'm not swapping at all.

Compcache, Suspend to Disk, and Swap Files

I am currently running compcache on my laptop. I don't plan to use it as my only swap space, though. I activated my old swap partition with a lower priority than my compcache swap space:

Filename                            Type            Size    Used    Priority
/dev/ramzswap0                          partition   827524  0       100
/dev/sda1                               partition   4000176 0       1

I haven't done much testing with how this will behave. I'm hoping it won't reach for the physical swap space until the ramzswap device fills up. I don't believe I will be that lucky, though. Compcache has an option to let you back a ramzswap device with a physical swap device. When I tested this, dstat was showing disk activity on my swap partition the whole time swap was in use. This was pretty much what I expected based on the documentation.

Suspend to disk seemed to “Just Work” as long as I have my old swap partition activated. Ubuntu uses swsusp to suspend to disk, which means that it can't suspend to a swap file. I was hoping I could just create a swap file for those rare occasions when I actually need to suspend to disk instead of to RAM.

How I Reduced My Virtual Machine Disk Images By Over 75% With QEMU

Lately I've been wanting to replace the hard drive in my laptop with a nice fast second-generation Intel X25-m. Unfortunately, my disk footprint is just a little too high to comfortably fit on the disk I want to buy, so I have been looking to free up a little space wherever I can.

What I Started With

I had three test VirtualBox images totaling around 8.5 GB. I figured that since two of the images were running the same version of Ubuntu, that QEMU's qcow2 copy-on-write disk images would be able to save me a bit of room. My original three machines looked like this:

total 8.5G
3.8G OpenVZ 1 Test.vdi
2.8G OpenVZ 2 Test.vdi
1.9G patshead.com Test.vdi

The first two were Ubuntu 8.04 servers, the last was running Ubuntu 9.04. I decided that it would be easiest to rebuild these machines from scratch and migrate over whatever data was needed.

Creating The Base Disk Images

In order to keep organized, I created a pair of directories to keep disk images in. One for the read only base images, and another for the writable images:

~/qemu/qcow-ro
~/qemu/qcow-rw

I created two temporary disk images to hold fairly stripped-down installations of Ubuntu Hardy and Jaunty server. I created the initial machines without swap space. I also made sure to install all the latest updates and remove any extra outdated kernel packages (they are surprisingly large!). I also made sure to install any software that I knew I would want to have available in all my future machines.

Once everything was installed, I needed to clean things up, and I think I made a small error here. I ran apt-get clean to remove any downloaded packages. I probably should have zeroed out the files with a command like shred -n 1 -z /var/cache/apt/archives/*.deb instead.

I also made sure to delete the ssh host keys (rm /etc/ssh/ssh_host_*). When I boot a new image, I make sure to run dpkg-reconfigure openssh-server to generate a new set of keys for the new server.

At this point I was left with two images that needed to be shrunk down. The compression of qcow2 images is only applied when the image is created; any later writes to the same disk image will be uncompressed. I used qemu-img convert to recompress the images.

This left me with two smaller base images:

total 834M
438M hardy-root.qcow2
397M jaunty-root.qcow2

From here I just had to create more qcow2 images using one of these two as the base. Specifying the full path for the base_image seemed to be important. For example:

qemu-img create -b ~/qemu/qcow-ro/hardy-root.qcow2 -f qcow2 ~/qemu/qcow-rw/new-hardy-root.qcow2

To save a bit more space, I created an empty swap disk image and ran mkswap on it. The scripts I wrote for starting my QEMU machines will make a copy of my empty swap image as needed. They are deleted when the machine shuts down.

Squeezing Out a Bit More Space

After I finished loading all the data into my test images I decided to try to recompress the images using qemu-img convert. In one case, I saved about 200 MB, which was about 40%. In most cases, the images got bigger! Zeroing out files instead of deleting them probably would have helped quite a bit in this case as well.

What I Ended Up With

After setting up equivalents of my original three machines, my disk footprint was just under 2 GB. I was very happy with that result. I have added another server and I am now right around 2.5 GB. Here are the images I am currently using:

qcow-ro:
total 834M
438M hardy-cow-root.qcow2
397M jaunty-cow-root.qcow2

qcow-rw:
total 1.6G
 28K EMPTYSWAP.qcow2
757M OpenVZ-Test-1-root.qcow2
348M OpenVZ-Test-2-root.qcow2
3.0M Patshead-dev-root.qcow2
517M movabletype-root.qcow2
 28K movabletype-swap.raw

Overall, I am very happy with the savings in disk space. It is also less costly in both time and disk space to throw up a temporary test machine if I need one.

The biggest drawback is that QEMU, even with the KQEMU accelerator, is quite a bit slower than Virtualbox or VMware Server. Fortunately, the performance is more than acceptable for what I'm using it for. Your mileage may vary, of course.

Now I just have to wait for the G2 X25-m drives to ship again…