ZFS unter Ubuntu/Kubuntu 6.10 (»Edgy Eft«)
Sun Microsystems hat der OpenSource Community ein neues Power-Tool geschenkt: Das Zettabyte Filesystem, kurz ZFS genannt. Dieses Filesystem räumt mit der gängigen Zuordnung »eine Partition – ein Dateisystem« gründlich auf und abstrahiert die Filesystem-Ebene komplett von der darunterliegenden Speicherinfrastruktur. Wer mehr zu den Grundlagen von ZFS lesen möchte, kann dies hier tun.
Zunächst war ZFS lediglich für Suns Betriebssystem Solaris verfügbar. Inzwischen laufen Portierungsprojekte auf verschiedene BSD-Derivate, MacOS und Linux. Gerade die Linux-Variante ist wohl für viele Anwender interessant. Diese wird von Ricardo Correira implementiert und baut auf FUSE auf, da die Integration der unter Suns CDDL freigegebenen Sourcen in den unter der GPL stehenden Linux-Kernel aus lizenzrechtlichen Gründen problematisch ist.
In diesem Blogpost möchte ich kurz beschreiben, wie man ZFS unter einem aktuellen Kubuntu 6.10 (»Edgy Eft«) kompiliert und zum Laufen bringt.
The shoulders of Giants
Auch andere haben sich natürlich schon dieses Themas angenommen, darunter Machine Check Exception und Chris Samuel.
Source Code besorgen
Es gibt grundsätzlich zwei Möglichkeiten, sich den Source-Code zu besorgen: per Download oder über das Mercurial-Repository von
Ricardo Correia. Letztere Möglichkeit ist insbesondere für Anwender/Entwickler, die immer auf dem letzten Stand sein wollen – birgt aber auch die Gefahr, dass der Code nicht gar so rock stable ist wie eine releaste Version.
Die letzte releaste Version 0.4.0_alpha1 (Stand: 31.12.2006) kann unter
https://developer.berlios.de/project/showfiles.php?group_id=6836
bezogen werden.
Das von dort heruntergeladene Source-Code-Archiv wird dann per
$ tar xfj zfs-fuse-0.4.0_alpha1.tar.bz2
entpackt.
Die Abenteurer unter uns können sich Mercurial installieren (falls nicht ohnehin schon vorhanden) und sich dann den Source Code direkt aus Ricardos Repository ziehen. Die erste der beiden Codezeilen checkt die letzte releaste Version aus der Serie 0.4 aus, die zweite besorgt die cutting edge Version (Hinweis: use at your own risk):
$ hg clone http://www.wizy.org/mercurial/zfs-fuse/0.4.x
$ hg clone http://www.wizy.org/mercurial/zfs-fuse/trunk
Dependencies installieren
Damit sich ZFS unter Ubuntu/Kubuntu kompilieren und installieren lässt, müssen wir uns zunächst eine Build-Umgebung schaffen und die Dependencies (die Sourcen von FUSE) installieren:
$ sudo apt-get install build-essential scons $ sudo apt-get install libfuse-dev
MAKE
Wir wechseln nun in das Verzeichnis mit den Sourcen. Der genaue Pfad hängt davon ab, welche der oben vorgestellten Möglichkeiten zur Beschaffung des Source Codes gewählt wurde:
$ cd zfs-fuse-0.4.0_alpha1/src # nach Download $ cd 0.4.x/src # Mercurial-Checkout aktuelle Serie $ cd trunk/src # für Wagemutige
Der Build der Sourcen wird über ein im Source-Paket enthaltenes Skript für scons gesteuert. Für uns bedeutet das, dass wir es nun sehr einfach haben:
$ scons
Installation
Die Installation ist ebenfalls extrem einfach gehalten und wird auch über scons gesteuert:
$ sudo scons install
Fertig!
Arbeiten mit ZFS
Hier möchte ich nun keine komplette Übersicht über die Möglichkeiten von ZFS bieten – dazu gibt es (vielleicht) mal einen weiteren Artikel. Interessant wäre aber schon, ob das gerade übersetzte und installierte ZFS überhaupt funktioniert …
Damit wir mit ZFS unter Linux arbeiten können, müssen wir zunächst den ZFS-Daemon starten. Ein Skript dafür ist in den Sourcen im Verzeichnis src/zfs-fuse enthalten:
$ cd src/zfs-fuse; ./run.sh
Wir benötigen nun noch mindestens ein, möglichst aber mehrere Block-Devices, um die Möglichkeiten von ZFS zu demonstrieren. In meinem Fall habe ich unter EVMS einfach zwei neue Devices /dev/evms/zfs0 und /dev/evms/zfs1 auf verschiedenen Festplatten angelegt. Man kann aber auch Dateien als Pseudo-Blockdevices verwenden.
$ dd if=/dev/zero of=~/zfs0 bs=1M count=1024 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB) copied, 22.3667 seconds, 48.0 MB/s $ dd if=/dev/zero of=~/zfs1 bs=1M count=512 512+0 records in 512+0 records out 536870912 bytes (537 MB) copied, 1.42299 seconds, 377 MB/s $ dd if=/dev/zero of=~/zfs2 bs=1M count=1536 1536+0 records in 1536+0 records out 1610612736 bytes (1.6 GB) copied, 21.063 seconds, 76.5 MB/s
Dies legt null-gefüllte Dateien zfs{0|1|2} mit einer Größe von 1G, 0.5G und 1.5G im Heimatverzeichnis des aktuellen Benutzers an.
Der ZFS Pool kann dann mit
$ sudo zpool create test ~/zfs0
angelegt werden. Wir können nun mit ZFS-Tools ein paar Informationen über den soeben angelegten ZPool sammeln:
$ sudo zpool list NAME SIZE USED AVAIL CAP HEALTH ALTROOT test 1016M 88K 1016M 0% ONLINE - $ sudo zpool status test pool: test state: ONLINE scrub: none requested config: NAME STATE READ WRITE CKSUM test ONLINE 0 0 0 /home/mneisen/zfs0 ONLINE 0 0 0 errors: No known data errors
Super: Noch keine Fehler …
Zeit für das erste Dateisystem; Dateisysteme in ZFS sind hierarchisch, d.h., Dateisysteme können ihrerseits wiederum Dateisysteme enthalten. Properties (wie etwa Quotas, Kompression, Reservierung, ...) werden dabei von oben nach unten vererbt.
$ sudo zfs create test/users $ sudo zfs list NAME USED AVAIL REFER MOUNTPOINT test 114K 984M 25.5K /test test/users 24.5K 984M 24.5K /test/users
Dann wollen mit mal ein paar Dateisysteme für unsere beiden Benutzer Alice und Bob anlegen:
$ sudo zfs create test/users/alice $ sudo zfs create test/users/bob $ sudo zfs list NAME USED AVAIL REFER MOUNTPOINT test 178K 984M 25.5K /test test/users 76.5K 984M 27.5K /test/users test/users/alice 24.5K 984M 24.5K /test/users/alice test/users/bob 24.5K 984M 24.5K /test/users/bob
Alice und Bob sollen jeweils maximal 1G Speicher verbrauchen können.
$ sudo zfs set quota=1G test/users/alice $ sudo zfs set quota=1G test/users/bob
Zusammen sollen Alice und Bob maximal 1.5G Platz in unserem ZPool belegen.
$ sudo zfs set quota=1536M test/users
Für Bob sollen allerdings mindestens 640M reserviert werden.
$ sudo zfs set reservation=640M test/users/bob $ sudo zfs list NAME USED AVAIL REFER MOUNTPOINT test 640M 344M 25.5K /test test/users 640M 344M 27.5K /test/users test/users/alice 24.5K 344M 24.5K /test/users/alice test/users/bob 24.5K 984M 24.5K /test/users/bob
Oops, was ist denn jetzt passiert? Alice kann nur noch 344M belegen? Ja. Das sind die Auswirkungen der Reservierung von 640M Platz für Bob. Damit dieser garantiert 640M belegen kann, müssen andere Nutzer in ihrem Platzbedarf eingeschränkt werden. Das ist ein wirklich schönes Feature von ZFS, dass es so zwar auch in anderen Dateisystemen oder Add-On-Produkten gibt. Hier ist aber Kernbestandteil des Dateisystems und kann auch auf ganze Teilbäume im hierarchischen Baum der Dateisysteme in ZFS angewendet werden. Mit
$ sudo zfs set reservation=1.5G test/users cannot set property for 'test/users': size is greater than available space
kann z.B. festgelegt werden, dass für die Benutzer mindestes 1.5G Platz zur Verfügung steht – wäre da nicht die ominöse Fehlermeldung, die uns darauf aufmerksam macht, dass für eine solche Reservierung nicht mehr genügend Speicherplatz in unserem Pool zur Verfügung steht. Da wir aber noch zwei weitere Devices (zfs1 und zfs2, unsere Pseudo-Blockdevices in normalen Files) zur Verfügung haben, können wir diese zu unserem ZPool hinzufügen und damit Platz schaffen:
$ sudo zpool add test ~/zfs1 $ sudo zpool add test ~/zfs2 $ sudo zpool list NAME SIZE USED AVAIL CAP HEALTH ALTROOT test 2.98G 194K 2.98G 0% ONLINE -
Nun können wir auch die Reservierung von 1.5G Platz für die Gesamtheit aller Dateisysteme unter test/users durchsetzen:
$ sudo zfs set reservation=1.5G test/users $ sudo zfs list NAME USED AVAIL REFER MOUNTPOINT test 1.50G 1.43G 25.5K /test test/users 640M 896M 27.5K /test/users test/users/alice 24.5K 896M 24.5K /test/users/alice test/users/bob 24.5K 1024M 24.5K /test/users/bob
Voìla! Wie man sieht, hat Bob nun maximal 1G zur Verfügung. Da er 640M fest zugesichert bekommt und für die Dateisysteme unter test/users maximal 1.5G eingeplant sind, bleiben für Alice 896M übrig. Sie wird Ihre maximal zugewiesenen 1G also nicht nutzen können – außer wir verändern die Obergrenze auf test/users. In unserem ZPool test haben wir insgesamt rund 3G Platz – 1.5G davon sind inzwischen aber verbraucht, da wir den Nutzern soviel Speicherplatz fest zugesagt haben.
Damit Alice, die keine 1G Platz beanspruchen kann, aber dennoch viel in ihrem Verzeichnis unterbringt, schalten wir (nur für ihren Verzeichnisbaum) Kompression an:
$ zfs set compression=on test/users/alice
Dies komprimiert alle neu hinzukommenden Daten in Alice’ Verzeichnis, vollkommen transparent für den Anwender. Wir testen die Auswirkungen:
$ cd ~; wget http://www2.kernel.org/pub/linux/kernel/v2.6/linux-2.6.19.1.tar.bz2 $ tar xj ~/linux-2.6.19.1.tar.bz2 $ du -sh linux-2.6.19.1 269M linux-2.6.19.1 $ sudo rsync -aS ~/linux-2.6.19.1 /test/users/alice [...] sent 230975825 bytes received 468146 bytes 1624168.22 bytes/sec total size is 229629549 speedup is 0.99 $ sudo zfs list NAME USED AVAIL REFER MOUNTPOINT test 1.50G 1.43G 25.5K /test test/users 775M 761M 27.5K /test/users test/users/alice 135M 761M 135M /test/users/alice test/users/bob 24.5K 1024M 24.5K /test/users/bob
Obwohl die Sourcen des Linux Kernel 2.6.19.1 etwa 269M umfassen, belegen sie in Alice’ komprimiertem Verzeichnis lediglich 135M. Wenn Alice also hauptsächlich mit gut komprimierbaren Daten arbeitet (Source Code, LaTeX-Dokumente, XML-Dateien, ...), dann wird sie aller Voraussicht nach sogar mehr als 1G Daten in ihrem Verzeichnis unterbringen können.
Fazit
Die ZFS-Portierung von Solaris nach Linux&FUSE ist zwar noch nicht ganz abgeschlossen, es wird auch auf die noch fehlende Optimierung und potentielle Bugs hingewiesen. In meinen Tests bin ich allerdings noch auf keinen solchen Fehler gestoßen, die Performance ist (wenn tatsächlich Disks und keine Dateien auf einem anderen Dateisystem) schon recht ordentlich. Für Systemadministratoren ist ZFS das Ende vieler Konfigurations-Alpträume und sollte Alternativen wie LVM und EVMS starke Konkurrenz machen.
Selbst professionelle, kommerzielle Lösungen können typischerweise auch nicht mehr als ZFS (z.B. Snapshots, Clones, ...). Wenn ich wetten müsste, welcher Volume Manager in 5 Jahren den Markt aufgerollt hat, würde ich auf ZFS tippen.
Für die kommende Zeit plane ich ein paar Performance-Messungen, über die ich dann hier berichten werde. Eventuell schreibe ich auch noch ein kleines Tutorial – mal sehen, wieviel Zeit ich haben werde …
Ähnliche Artikel in diesem Blog:








Am 2. Januar 2007 um 17:07 Uhr
Interessanter Artikel! Vielleicht werde ich ZFS auf meinem System auch einmal testen. Ich würde mich über weitere Details zur Performance freuen – schließlich ist das ein Aspekt, der für ein FS ziemlich wichtig ist.
Am 2. Januar 2007 um 19:37 Uhr
Ich bin gerade dabei, ZFS/FUSE auf einer etwas größeren Maschine unter Gentoo zu installieren und werde da dann einige Performance-Messungen mit unterschiedlichen ZFS-ZPool-Konfigurationen und im Vergleich zu LVM2 mit XFS machen. Stay tuned … oder so …
Am 7. Januar 2007 um 17:33 Uhr
For those who want to try this howto:
dd if=/dev/zero of=~/zfs0 of=1M count=1024
should be:
dd if=/dev/zero of=~/zfs0 bs=1M count=1024
Am 7. Januar 2007 um 18:36 Uhr
Thanks for your correction, Dogmatica. You are completely right, the original version of that line in my post is complete non-sense. I have corrected the posting by now, though.
Am 12. Januar 2007 um 08:45 Uhr
Sehr interessanter Artikel! Werde mir ZFS bei Zeiten mal genauer ansehen.
Am 1. Februar 2007 um 22:42 Uhr
$ sudo apt-get install build-essentials scons
es muss doch so heißen:
$ sudo apt-get install build-essential scons
Am 1. Februar 2007 um 23:57 Uhr
Hi Xaseron,
Du hast natürlich völlig recht. Die Stelle im Post korrigiere ich dann mal …
Vielen Dank für den Hinweis!
Am 8. März 2007 um 07:18 Uhr
s/Zettabyte/Zetabyte/ – please
Am 8. März 2007 um 15:05 Uhr
Hi C.,
I do not think that your hint for substitution is correct. When searching for »zettabyte« on Google, I get 171,000 hits, compared to only 17,000 for »zetabyte«. When searching for »zetabyte«, Google asks: »Did you mean: zettabyte?«
Even Wikipedia seems to think that »zettabyte« is the correct spelling.
Moreover, ZFS is attributed as »Zettabyte File System« nearly everywhere – even on Sun Microsystem’s own web site, f.e. in the data sheet for ZFS.
No offense meant: I guess I just leave it as it is …
(P.S.: Since you seem to come from a network assigned to Sun Microsystems: Is there any inside information about this thing – did you rename ZFS?)
Am 18. November 2007 um 00:44 Uhr
Hi! Danke für die Zusammenfassung! War sehr hilfreich für ein paar Experimente mit ZFS (0.4.0 beta1) unter Kubuntu 7.10. Ein Problem hab ich jedoch mit ZFS-Fuse.
Der ZFS-Daemon friert die Konsole ein.
Soweit kein Problem, da ich das Konsolen-Fenster schließen kann und der Daemon läuft weiter. Wollte dann ZFS-Fuse per init-script beim booten starten lassen mit dem Ergebnis, daß der Bootvorgang beim script ebenfalls einfriert. Irgendeine Vermutung woran das liegen könnte? Grüße, paulistano!
Am 14. Dezember 2007 um 10:32 Uhr
Hallo paulistano: Nein, dafür weiß ich leider keine Lösung, inzwischen ist das bei mir schon mal passiert. Ärgerlich, ...
Am 19. März 2008 um 00:16 Uhr
Hi,
First of all, thanks for the blog post – I’m finding it really useful in my efforts to get zfs-fuse working on Ubuntu 7.10 (alternate install). Second, sorry for not writing in German, but I thought I’d post anyway in case my comment is of use to anyone. I got an error saying I was missing zlib.h when trying to compile zfs-fuse (i.e. I ran scons). I fixed it by installing two packages
sudo apt-get install zlib1g-dev libssl-dev
hope this helps someone!
Am 19. März 2008 um 00:19 Uhr
Actually, on second thoughts, maybe only zlib1g-dev is needed…
Am 24. April 2008 um 16:16 Uhr
Um die aktuenne beta1 mit gcc 4.2 zu kompilieren braucht man noch einen patch, den man sich von gentoo holen kann:
http://bugs.gentoo.org/show_bug.cgi?id=213440