Bug 22231 - Anlegen/Wiederherstellen/Löschen eines Snapshot dauert sehr lang wenn das Image auf einem NFS Share liegt und die Instanz läuft
Anlegen/Wiederherstellen/Löschen eines Snapshot dauert sehr lang wenn das Ima...
Status: CLOSED FIXED
Product: UCS
Classification: Unclassified
Component: Virtualization - KVM
UCS 2.4
Other Linux
: P5 normal (vote)
: UCS 2.4-3
Assigned To: Philipp Hahn
Janek Walkenhorst
:
Depends on:
Blocks: 23068 23445 29252 30504
  Show dependency treegraph
 
Reported: 2011-04-15 15:25 CEST by Felix Botner
Modified: 2013-02-20 08:39 CET (History)
4 users (show)

See Also:
What kind of report is it?: ---
What type of bug is this?: ---
Who will be affected by this bug?: ---
How will those affected feel about the bug?: ---
User Pain:
Enterprise Customer affected?:
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional):
Max CVSS v3 score:


Attachments
Qcow2 overhead(cluste_size, filesyste_size) (17.54 KB, application/octet-stream)
2011-08-29 09:50 CEST, Philipp Hahn
Details
Python-Skript zum Dumpen einer Qcow2-Imagedatei (13.18 KB, text/plain)
2011-08-29 09:51 CEST, Philipp Hahn
Details
Article about qcow2 performance (9.62 KB, text/plain)
2011-08-29 09:51 CEST, Philipp Hahn
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Felix Botner univentionstaff 2011-04-15 15:25:20 CEST
Getestet mit Windows7. Auf dem KVM Node wurde das Image Verzeichnis per NFS eingebunden. 

Wenn ich von Window7 einen Snapshot im laufendem Betrieb erstelle, dauert das Anlegen und Zurückspielen dieses Snapshot sehr lang (>20min).

Wenn die Instanz aus ist, braucht er für das Anlegen des Snapshot ein paar Sekunden. Wieder herstellen mit UVMM funktioniert im Moment leider nicht (wenn die Instanz beim Erstellen das Snapshot ausgeschaltet war, siehe Bug #22221) aber auf der Kommandozeile braucht er dafür auch nicht lang:

-> time qemu-img snapshot -a "sysprep pre" win7-felix-basis-0.qcow2

real    0m0.974s
user    0m0.056s
sys     0m0.148s
Comment 1 Philipp Hahn univentionstaff 2011-04-15 15:50:58 CEST
Ein "strace -f -p `pidof kvm.bin`" zeigt, das der Qemu-Prozeß mit dem Zurücksetzen des Block-Devices auf den Zustand zum Zeitpunkt des Schnappschusses beschäftigt ist:

 [pid  9437] pwrite(8, "\0\3\0\3\0\1\0\3\0\3\0\3\0\3\0\3\0\3\0\3\0\3\0\3\0\3\0\3\0\3\0\3\0"..., 65536, 8590065664) = 65536
 [pid  9437] fdatasync(8)                = 0
(diese Meldung wird ständig wiederholt)

File-Descriptor 8 entspricht dem Qcow2-Image der ersten Platte, wie ein "lsof -p `pidof kvm.bin`" zeigt.

Auffällig ist, das hier nach vermutlich jeder Änderung (einer Bitmap?) diese Änderung sofort auf die Platte zurückgeschrieben und per "fdatasync()" auch erzwungen wird, daß die Änderungen tatsächlich auf der Platte landen. Im Falle von NFS führt vermutlich genau dieses erzwungene syncen zu der schlechten Performance, weil jeder 64KiB-Schreibvorgang mehrere Round-Trips zwischen NFS-Client und -Server erfordert.

Ggf. sollte hier zunächst mal untersucht werden, ob das Ändern des /domain/devices/disk/driver/@cache-Attributs eine Auswirkung hat <http://libvirt.org/formatdomain.html#elementsDisks> und ob "qemu-img snapshot -a" auch so häufig synced.
Comment 2 Philipp Hahn univentionstaff 2011-07-18 17:55:35 CEST
(In reply to comment #1)
> Ggf. sollte hier zunächst mal untersucht werden, ob das Ändern des
> /domain/devices/disk/driver/@cache-Attributs eine Auswirkung hat
> <http://libvirt.org/formatdomain.html#elementsDisks> und ob "qemu-img snapshot
> -a" auch so häufig synced.

Laut <https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/741887/comments/4> ist das Cache-Verhalten von Qemu schuldig: qemu hängt den Hauptspeicherinhalt und den Zustand der virtuellen Geräte an den Speicherbereich an, der für den Festplatteninhalt benötigt wird. Dazu wird die normale Qemu-Implementierung für Qcow2-Dateien verwendet, die normalerweise das sichere "writethrough" verwendet: Jeder Schreibvorgang erfordert das Aktualisieren gewisser Bitmaps und Verweisstrukturen, die jedesmal gesynced werden. Mit "writeback" bzw. "none" soll es schneller gehen, allerdings zu Lasten der Datensicherheit bei Crashs!

3× time virsh snapshot-create "$VM"
 writethrough
  real    1m1.831s
  real    1m46.552s
  real    1m44.091s
 writeback
  real    0m4.369s
  real    0m43.519s
  real    0m43.263s
 none
  real    0m6.337s
  real    0m45.446s
  real    0m40.556s
Fazit:
- Der 1. Snapshot ist immer deutlich schneller erstellt als alle weiteren
- Auf einem lokalen ext3-Dateisystem sind die Unterschiede nicht so gravierend wie mit NFS
Comment 3 Philipp Hahn univentionstaff 2011-07-20 19:48:09 CEST
Ggf. hilft folgender Patch:
[Qemu-devel] [PATCH] qcow2: Use Qcow2Cache in writeback mode during loadvm/savevm
<http://lists.gnu.org/archive/html/qemu-devel/2011-07/msg01628.html>
Comment 4 Philipp Hahn univentionstaff 2011-07-21 12:39:39 CEST
Zum persistenten Ändern der Cache-Strategie auf "none" kann man folgendes machen:
 sed -e "/<driver name='qemu'/s|\( cache='[^']*'\)\?/>| cache='none'/>|" /var/lib/libvirt/qemu/snapshot/"$VMNAME"/*.xml /etc/libvirt/qemu/"$VMNAME".xml
 /etc/init.d/univention-virtual-machine-manager-node-common restart
Comment 5 Philipp Hahn univentionstaff 2011-07-21 14:01:19 CEST
(In reply to comment #3)
> Ggf. hilft folgender Patch:
> [Qemu-devel] [PATCH] qcow2: Use Qcow2Cache in writeback mode during
> loadvm/savevm
> <http://lists.gnu.org/archive/html/qemu-devel/2011-07/msg01628.html>

Der Patch lässt sich auf unser qemu-0.14 anwenden und lässt sich anschließend bauen. Ein Kurzer Auf xen14 ergab folgende positive Verbesserung:

for a in 1 2 3; do time virsh snapshot-create $VM; done | tac | sed -ne 's/Domain snapshot \([0-9]\+\) created.*/\1/p' | xargs -n 1 virsh snapshot-delete $VM

Ohne Patch:
 real    2m45.302s
 real    3m30.491s
 real    3m9.515s

Mit Patch:
 real    0m8.164s
 real    0m40.641s
 real    0m39.645s

Von daher wäre es vermutlich sinnvoll, diesen Patch bei uns anzuwenden, um Snapshots wieder sinnvoll verwenden zu können.
Comment 6 Philipp Hahn univentionstaff 2011-07-21 17:26:48 CEST
Aus <http://wiki.qemu.org/download/qemu-doc.html>:
By default, writethrough caching is used for all block device. This means that the host page cache will be used to read and write data but write notification will be sent to the guest only when the data has been reported as written by the storage subsystem.

Writeback caching will report data writes as completed as soon as the data is present in the host page cache. This is safe as long as you trust your host. If your host crashes or loses power, then the guest may experience data corruption. When using the ‘-snapshot’ option, writeback caching is used by default.

The host page cache can be avoided entirely with ‘cache=none’. This will attempt to do disk IO directly to the guests memory. QEMU may still perform an internal copy of the data.

Some block drivers perform badly with ‘cache=writethrough’, most notably, qcow2. If performance is more important than correctness, ‘cache=writeback’ should be used with qcow2.
Comment 7 Philipp Hahn univentionstaff 2011-07-21 17:57:45 CEST
In case you don't care about data integrity over host failures, use
cache=unsafe. This option tells qemu that it never needs to write any data
to the disk but can instead keeps things in cache. If anything goes wrong,
like your host losing power, the disk storage getting disconnected accidently,
etc. you're image will most probably be rendered unusable.   When using
the -snapshot option, unsafe caching is always used.



unsafe:
 Ignoriert flush()-Aufforderungen
 write() landen im Buffer-Cache des Kernels, kehrt sofort zurück
 Benutzt kein fdatasync() bzw. O_DSYNC

writeback:
 Honoriert flush()-Aufforderungen
 write() landen im Buffer-Cache des Kernels, kehrt sofort zurück
 Benutzt kein fdatasync() bzw. O_DSYNC

off/none:
 Honoriert flush()-Aufforderungen
 write() benutzt O_DIRECT und umgeht den Buffer-Cache des Kernels
 Braucht kein fdatasync() bzw. O_DSYNC ???
 
writethrough:
 Honoriert flush()-Aufforderungen
 write() landen im Buffer-Cache des Kernels, wartet bis erfolgreich geschrieben
 Erzwingt fdatasync() bzw. O_DSYNC

Das sind die Modi, mit denen die QCow2-Image-Datei geöffnet wird. Ein Schreibvorgang im Gast erfordert ggf. bis zu 4 Zugriffen: Daten-Cluster, L1- und L2-Tabelle, Refcount-Tabelle. Bei writethrough sind die alle synchron und werden streng nacheinander ausgeführt!
Bei NFS kommt erschwerend hinzu, das dort Asynchronous-IO nicht (gut) funktioniert und ein fdatasync() sehr teuer ist, weil große Teile der Datei geflushed werden müssen.
Comment 8 Philipp Hahn univentionstaff 2011-07-21 18:04:37 CEST
Ein Default per UCR wäre sinnvoll, damit man zwischen "sicher(er)" und "schnell(er)" wählen kann. Im Einzelfall wäre konfigurierbar über UVMM hilfreich.
Im Profil macht weniger Sinn, da die Einstellung insbesondere vom Host-System und dem dort verwendeten Image-Format abhängt, also Gast-Unabhängig ist.
Comment 9 Tobias Scherer univentionstaff 2011-07-28 15:07:11 CEST
Auch aufgefallen an Ticket#: 2011072010001472 im Forum http://forum.univention.de/viewtopic.php?f=43&t=1517
Comment 10 Stefan Gohmann univentionstaff 2011-08-02 10:01:39 CEST
Wie besprochen, dann sollten wir den Upstream Patch übernehmen.
Comment 11 Philipp Hahn univentionstaff 2011-08-05 11:58:15 CEST
Qemu-kvm_0.14.1 <http://wiki.qemu.org/ChangeLog/0.14> wurde aus Debian-Sid als neues Bugfix-Release importiert und der Patch eingespielt. Angaben sind unpatched-0.14.0 → patched-0.14.1:

virsh dumpxml "$VM" | grep type=\'qcow2\'\\\|memory
  <memory>512000</memory>
  <driver name='qemu' type='qcow2'/>
time virsh snapshot-create "$VM" /dev/stdin <<<'<domainsnapshot><name>Test1</name></domainsnapshot>'
  real    00m42.012s → m5.384s
time virsh snapshot-create "$VM" /dev/stdin <<<'<domainsnapshot><name>Test2</name></domainsnapshot>'
  real    1m34.990s → 1m13.111s
virsh snapshot-list "$VM"
 Test1                2011-08-05 10:26:33 +0200 running
 Test2                2011-08-05 10:26:44 +0200 running
time virsh snapshot-delete "$VM" Test1
  real    0m26.158s → 0m0.131s
time virsh snapshot-delete "$VM" Test2
  real    1m1.359s → 0m0.036s

svn9540, qemu_0.14.1+dfsg-3.22.201108042028, qemu-kvm_0.14.1+dfsg-4.11.201108042116

ChangeLog:
\item Die Versionen von Qemu und Qemu-KVM wurden jeweils auf die Version 0.14.1 aktualisiert.
...
\item Das Erstellen und Wiederherstellen von Sicherungspunkten ist nun schneller (\ucsBug{22231}).
Comment 12 Janek Walkenhorst univentionstaff 2011-08-26 17:21:21 CEST
Für die QA:
8 Tests
 mit neuer und alter qemu-Version, (Pakete qemu-utils und qemu-kvm)
 Revert und Snapshot
 WriteThrough und WriteBack
Comment 13 Philipp Hahn univentionstaff 2011-08-29 09:50:34 CEST
Created attachment 3484 [details]
Qcow2 overhead(cluste_size, filesyste_size)
Comment 14 Philipp Hahn univentionstaff 2011-08-29 09:51:02 CEST
Created attachment 3485 [details]
Python-Skript zum Dumpen einer Qcow2-Imagedatei
Comment 15 Philipp Hahn univentionstaff 2011-08-29 09:51:31 CEST
Created attachment 3486 [details]
Article about qcow2 performance
Comment 16 Janek Walkenhorst univentionstaff 2011-08-30 11:50:10 CEST
Die Geschwindigkeit von Sicherungspunkten (Erstellen, Wiederherstellen, Löschen) hat sich mit der neuen Version nicht verschlechtert, für Erstellen bei WriteThrough signifikant verbessert, und für Löschen und Wiederherstellen bei WriteThrough drastisch (auf WriteBack-Niveau) verbessert.

Changelog OK
Comment 17 Sönke Schwardt-Krummrich univentionstaff 2011-09-14 10:56:36 CEST
UCS 2.4-3 wurde veröffentlicht. Sollte der hier beschriebene Bug mit einer
neueren Version von UCS erneut auftreten, so sollte der Bug dupliziert werden:
"Clone This Bug".