ZFS-FUSE
Írta: Szabó Tamás Zoltán
2010. december 8.
Ez az oldal a ZFS fájlrendszert és a Linux FUSE alrendszeren való használatát mutatja be.
1 Története
A ZFS-t a Sun Microsystems fejlesztette ki saját Solaris rendszerére, amelynek tervezésénél az addigi fájlrendszerek problémáit próbálták kiküszöbölni egy funkciókban gazdag, új felépítésű fájlrendszerrel. Először 2005-ben jelent meg a Sun OpenSolaris nevű operációs rendszerében. Elnevezése eredetileg a Zettabyte File System rövidítése, ami a lehetséges méretére vonatkozik, ugyanis 264 byte méretű lehet egy fájlrendszer maximális mérete, és a legtöbb fájlrendszerhez köthető méretkorlát legalább zettabyte nagyságendű, ami jelenleg a gyakorlatban korlátlan méretet jelent.
2010-ben az Oracle megvásárolta a Sun Microsystems-et, ezzel – egyéb Sun termékek mellett – a Solaris is az Oracle tulajdonába került.
A ZFS fejlődése során folyamatosan bővül, ezért a fejlődés lépcsőihez inkrementális verziószámot rendelnek (zpool version). Ezek közül a fontosabbak verziószámok szerint:
- 1: adatstruktúrák definiálása
- 2: metaadat-replikáció
- 3: melegtartalék, dupla paritású RAID-Z (RAID-Z2)
- 4: zpool history
- 5: röptömörítés a gzip algoritmusával
- 6: bootfs pool
- 9: CIFS szerver támogatás, fejlettebb kvótarendszer
- 10: cache device támogatása: operatív memória és diszk-rendszer közé vezet be további cache-réteget
- 11: zpool scrub / resilver teljesítmény növelés
- 12: snapshot
- 17: tripla paritású RAID-Z (RAID-Z3)
- 19: ZFS log device eltávolítás
- 20: röptömörítés a zle algoritmusával
- 21: blokkszintű deduplikáció
- 22: zfs receive
- 23: slim ZIL
- 26: snapshot törlés gyorsítás
- 27: snapshot létrehozás gyorsítás
- 28: multiple virtual device replacement
- 29: RAID-Z/mirror hybrid allocator
- 30: titkosítás
A legutolsó verzió (2010. december): 31
2 Tulajdonságai
2.1 Adatintegritás
Minden blokk integritását egy ellenőrző kóddal védi, amelyet a blokkra mutató pointer mellé tárol el. Az ellenőrző kód beállítástól függően lehet 32 bites vagy 256 bites. Bár a diszkek hibajavító kódolást használnak, előfordulhatnak a diszken kívül átviteli hibák, amik hatására a beolvasott adat megsérül. Ennek valószínűsége nagy, kritikus adatmennyiséget kezelő rendszereknél már nem elhanyagolható.
2.2 128 bites fájlrendszer
Gyakorlatilag korlátlan: legtöbb méretkorlát legalább 248 nagyságú.
2.3 Storage pool
A ZFS architektúrája eltér a hagyományos fájlrendszerekétől, ugyanis egy logikai kötetkezelőt is tartalmaz.
Virtual device-okból poolok építhetőek, egy poolon több ZFS létrehozható. Egy fájlrendszer fájlok csooportja a pool-on (dataset). Emiatt egy fájlrendszer méretét sem kell előre megadni.
Virtual device lehet blokkeszköz, reguláris fájl, vagy ezek valamilyen összetettebb konfigurációja, például RAID-Z, vagy tükrözés vagy egyszerű összefűzés.
2.4 Hotspare
Poolokhoz melegtartalék rendelhető, amely egy diszk meghibásodása esetén átveszi a hibás diszk helyét.
2.5 Copy-on-write tranzakciókezelés
Egy blokkot a fájlrendszer nem helyben módosít, hanem a következő módszerrel:
- új blokkot foglal le, ebbe írja a módosított adatot
- minden, az eredeti blokkra közvetlenül vagy indirekten hivatkozó metaadat-blokkokból olyan új példányokat hoz létre, ami a módosított adatot tartalmazó blokkra mutat
- frissíti a superblock-ot (uberblock) is, ez atomi művelet
Mivel az utolsó művelet atomi, ezért a superblock mindig egy konzisztens struktúrára mutat. Az overhead csökkentése érdekében a ZFS tranzakció csoportokat, szinkron íráshoz intent(„szándék”) naplózást használ (ebben a művelet elvégzése előtt írja a naplóba, hogy mit fog kiírni).
2.6 Snapshot
A copy-on-write mechanizmust használja ki, vagyis hogy a fájlrendszer módosításnál mindíg új blokkba írja a módosított tartalmat. Snapshot esetén a régi adatokat tartalmazó blokkot nem szabadítja fel, hanem snapshotként jelöli meg, ez a felszabadításnál olcsóbb művelet is, mint snapshot nélkül.
2.7 Clone
Fájlrendszer klónozása. Klónozni csak egy fájlrendszer snapshotjából lehet. Lérehozásakor mindkét fájlrendszer ugyanazokat a blokkokat használja. Ha valamelyikben módosítás történik, akkor ahhoz copy-on-write mechanizmus segítségével új blokk jön létre a módosított fájlrendszerhez, a régi blokkot megtartja.
2.8 Automatikus csíkozás
A poolban lévő eszközöket RAID-0-szerűen csíkozza. Új diszk esetén a csíkozás automatikus kiterjed rá, a copy-on-write mechanizmus segítségével az írások során egyenletesen lesz szétosztva az adat a diszkek közt.
2.9 Változó blokkméret
128 kbyte-ig változtatható a blokkok mérete az adminisztrátor által. Tömörítés esetén a legkisebb blokkméretet használja, amibe az eredeti blokk tömörített formája belefér. Tervek szerint a fájlrendszer a blokkméret automatikus, terhelés-függő változtatására is képes lesz. Extenteket nem használ, mert nagy méretük nem ideális copy-on-write és ellenőrző összegek használatára.
2.10 Adaptív bájtsorrend
Az adatokat mindíg natív bytesorrendben írja ki, mellé jelzi, hogy little-endian vagy big-endian a bájtsorrend. Olvasáskor ha az adott architektúra más sorrendet használ, akkor a beolvasott adatot átalakítja a saját formátumára.
2.11 Deduplikáció
A blokk ellenőrző összeg felhasználásánál íráskor képes detektálni az azonos tartalmú blokkokat a blokkokhoz tartozó ellenőrző összegekből felépített adatbázis alapján.
2.12 Live data scrubbing
Időnként automatikusan vagy manuálisan elindul egy adatellenőrzés a poolon. Ha hibát talál, akkor kijavítja automatikusan, ha lehetséges.
2.13 RAID-Z
RAID-5 módszerhez hasonló , de véd az írás megszakításából adódó inkonzisztencia porblémáktól. A Sun ajánlása alapján legfeljebb kilenc diszket ajánlott egy RAID-Z konfigurációban használni, ha ennél többet szeretnénk, akkor érdemes kisebb RAID-Z csoportokra felosztani ezeket. Lehet dupla (RAID-Z2) és tripla (RAID-Z3) paritású konfigurációt is választani. Előbbi a RAID-6-hoz hasonló, két hiba javítására, utóbbi három hiba javítására képes.
2.14 Transzparens titkosítás
Aránylag új a ZFS-ben, a ZFS/FUSE megvalósítás nem támogatja.
Fájlrendszerenként állítható, swap és dump is titkosítható zvolume használatával. Boot fájlrendszeren nem használható.
2.15 Transzparens tömörítés
LZJB, GZIP és ZLE tömörítési eljárásokat támogat. A tömörítés használat közben be- és kikapcsolható, a változtatás csak az újonnan kiírt adatokat érinti.
2.16 Adaptive Replacement Cache
Újabb gyorsítótár-kezelés, ami az elterjedt LRU-nál (Least Recently Used) jobban teljesít.
2.17 Egyéb tulajdonságok
- Fejlettebb ACL kezelés
- Egyszerű pool mozgatás zpool export és zpool import segítségével
- Intelligens prefetch: például stream szolgáltatás esetén hasznos
- I/O pipeline[1]: Az adatok a diszk és a fájlrendszer drivere közt egy pipelineon (úgynevezett ZIO-n) haladnak át. Ez a műveleteket csővezetékbe szervezi, ezzel próbálja növelni a párhuzamosíthatóságot. Ilyen műveletek például az ellenőrző kód számítása és a tömörítés.
- Dinamikus metaadat-allokáció
- Prioritásos belső I/O ütemező
- Minden metaadatot legalább két példányban tárol. Ez írásnál overheadet okoz, de egyrészt javítja a megbízhatóságot, másrészt olvasásnál növelheti is a teljesítményt.
- Nincs töredezettség-mentesítő eszköz hozzá, pedig copy-on-write használata miatt sok írásnál töredezetté válhat a fájlrendszer.
3 Operációs rendszerek
A ZFS elsődleges platformja a Sun saját operációs rendszere, a Solaris/OpenSolaris.
Mivel nyílt forráskódú, ezért további rendszerekbe is bekerült:
FreeBSD 8.0 óta támogatja a zpool v13-at, a 8.1 a v14-et.
A NetBSD ZFS port fejlesztés alatt áll.
A Linux kernelbe hivatalosan az eredeti kód nem kerülhet bele, mivel a ZFS kódja CDDL licenc alatt érhető el, ami nem kompatibilis a Linux GPL licenszével. A kernelbe csak egy olyan ZFS driver reimplementáció kerülhet bele, amelynek kódja GPL kompatibilis.
Linuxon a ZFS alternatívája lehet a btrfs, amely tervek szerint a ZFS-hez hasonló funkcionalitással fog rendelkezni. Ez azonban még fejlesztés alatt áll, éles használatra nem alkalmas.
Linuxra készül egy natív kernel-space és egy userspace verzió, utóbbi a Linux kernel FUSE interfészét használja.
A FUSE előnye a kernel-space megvalósítással szemben, hogy a fájlrendszer kódjának nem kell GPL kompatibilisnek lennie, valamint a driver összeomlása nem okozza az egész rendszer leállását, cserébe viszont kisebb teljesítménnyel bír.
4 ZFS/Linux-FUSE
A forráskód letölthető a http://zfs-fuse.net oldalról. Ez tartalmazza a userspace driver-t, programkönyvtárakat és userspace eszközöket. Ez az írás a 0.6.9-es verziót mutatja be, amely a ZFS 23-as verzióját támogatja.
4.1 Telepítés
A használatához legalább 2.6-os verziójú FUSE-t támogató kernel szükséges. A függőségek és SCons telepítése után lefordítani a következő parancsokkal lehet:
root@home:/# cd src root@home:/# scons
Ha sikeresen lefordult, telepíteni a következő paranccsal lehet:
root@home:/# scons install
4.2 ZFS/FUSE daemon indítása
Mivel a fájlrendszer driver user-space, ezért használatához egy daemon processz indítása szükséges:
root@home:/# zfs-fuse
4.3 ZFS eszközök
A fuse-zfs telepítése után az alábbi fontosabb eszközöket kapjuk:
- zpool: poolok adminisztrációja
- zfs: ZFS fájlrendszerek adminisztrációja
- zdb: ZFS debugger, verziószám lekérdezése
4.4 Poolok adminisztrációja
4.4.1 Pool létrehozása
Összefűzés RAID-0-szerűen:
zpool create -m <csatolási pont> <pool név> <vdev lista>
Egy példa:
zpool create pool1 /dev/sda2 /dev/sda3
Itt lérehoztuk a pool1 nevű ZFS pool-t a /dev/sda2 és /dev/sda3 blokkeszközökre. Ekkor létrejön a pool és csatolódik a /pool1 alá:
root@home:~# mount pool1 on /pool1 type fuse (rw,allow_other) ...
Az -m kapcsolóval más mount pontot is meg lehet adni, alapértelmezetten a gyökérbe csatol.
Az új pool önálló fájlrendszerként is használható, de a ZFS lehetőségei nem használhatóak így ki. Ha létrehozunk erre a poolra egy ZFS fájlrendszert, akkor azt a pool könyvtárába csatolja.
RAID-Z konfiguráció létrehozása:
zpool create <pool név> raidz <vdev lista>
Itt a raidz az egyszeres paritást jelenti. Lehet ezen kívül raidz2 és raidz3 (a megfelelő fájlrendszer-verziók esetén), ez dupla, illetve tripla paritást jelent. Előbbihez legalább három, utobbihoz legalább négy eszköz szükséges.
Példa dupla paritású RAID-Z építése /dev/sd[abc]1 eszközökre
zpool create pool1 raidz2 /dev/sda1 /dev/sdb1 /dev/sdc1
Tükrözés használata (mint RAID-1):
zpool create <pool név> mirror <vdev lista>
Melegtartalék használata a poolban:
zpool create <pool név> <vdev lista> spare <tartalék vdev-ek>
Log eszköz használata:
zpool create <pool név> <vdev lista> log <vdev eszköz>
Összetettebb példa: Hozzunk létre pool1 néven a /dev/sda2 és /dev/sdb3 blokkeszközökre egy RAID-Z konfigurációt /zfs.log naplófájllal és /zfs.spare tartalékkal. Utóbbi kettő reguláris fájlok.
root@home:/# zpool create pool1 raidz /dev/sda2 /dev/sdb3 log /zfs.log spare /zfs.spare
4.4.2 Pool törlése
zpool destroy <pool név>
Ez törli a megadott poolt és felszabadítja a használt eszközöket. Előtte le kell csatolnia a rajta létrehozott fájlrendszereket, így a művelet csak akkor sikeres, ha nem használja semmi a fájlrendszert vagy ha -f kapcsolót használjuk.
4.4.3 Poolok listázása
root@home:/# zpool list NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT pool1 3,88G 81K 3,87G 0% 1.00x ONLINE -
Ez kilistázza az összes olyan észlelt poolt, amit az adott verziójú ZFS driver kezelni tud.
4.4.4 Poolok állapotai
root@home:/# zpool status pool: pool1 state: ONLINE scrub: scrub completed after 0h0m with 0 errors on Wed Dec 8 00:18:31 2010 config: NAME STATE READ WRITE CKSUM pool1 ONLINE 0 0 0 sda2 ONLINE 0 0 0 sda3 AVAIL
Ez információkat ad a pool állapotáról, például a legutóbbi scrub hibakeresés eredménye és a poolban lévő eszközök állapota.
4.4.5 Pool frissítés
zpool upgrade -a
Ha van olyan pool a rendszerben, ami a jelenleginél régebbi ZFS verziójú, akkor ezzel a paranccsal frissíteni lehet a verzióját.
4.4.6 Pool importálás és exportálás
Pool importálása:
zpool import -d <könyvtár>
Pool exportálása:
zpool export <poolnév>
4.4.7 Scrub indítása
zpool scrub <pool név>
Ez elindít egy hibakeresést a megadott nevű poolon. A hibakeresés eredménye a zpool status parancssal kérdezhető le.
Az első paranccsal kereshetőek a megadott könyvtárban poolok, a másodikban egy pool exportálható. Exportálás után a pool mozgathatóvá válik, nem használható és nem látható a zpool-al importálásig. Csak olyan poolt lehet exportálni, amin nincs mountolt fájlrendszer. A -D kapcsolóval törölt (destroyed) pool is importálható. Az -a kapcsolóval egyidejűleg keres és importálja a megtalált poolokat.
Példa:
root@home:/# zpool export pool1 # Exportáljuk a pool1-et
root@home:/# zpool import -a -d /dev
Ez utóbbi megkeresi a blokkeszközök alapján a poolokat és importálja azokat.
4.4.8 Device cseréje
Lehetőség van a poolban egy eszköz lecserélésére, például tartalékra.
Példa: a pool1-ben kicseréljük a /dev/sda3 eszközt /dev/sda4-re:
root@home:/# zpool offline pool1 /dev/sda3 Bringing device /dev/sda3 offline root@home:/# zpool replace pool1 /dev/sda3 /dev/sda4
4.5 ZFS adminisztráció
Egy fájlrendszert a következő módon azonosítunk: <pool név>/<fájlrendszer név>
Fájlrendszer létrehozása:
zfs create <létező pool>/<új fájlrendszer neve>
Példa:
root@home:/# zfs create pool1/fs1
Itt létrehozunk a pool1-en egy fs1 nevű fájlrendszert. A létrehozott fájlrendszer rögtön csatolva is lesz a /pool1/fs1 pontra.
Létrehozás attribútum megadásával:
zfs create -o <attribútum>=<érték> <létező pool>/<új fájlrendszer neve>
Átnevezés:
zfs rename <régi név> <új név>
Fájlrendszer törlése:
zfs destroy <fájlrendszer azonosító>
Létező fájlrendszer csatolása:
zfs mount <pool név>/<fájlrendszer név>
Lecsatolás:
zfs umount <pool név>/<fájlrendszer név>
Fájlrendszer-attribútumok beállítása és lekérdezése: Egy fájlrendszerhez számos attribútum tartozik, például tömörítsen-e.
Lekérdezés:
zfs get <attributum> <fájlrendszer azonosító>
Attribútum értékének módosítása:
zfs set <attributum>=<új érték> <fájlrendszer azonosító>
Példa: tömörítés lekérdezése:
root@home:/# zfs get compression pool1/fs1 NAME PROPERTY VALUE SOURCE pool1/fs1 compression gzip local
A legtöbb attribútum használat közben módosítható, de néhány attribútumot csak létrehozásnál lehet megadni.
Fontosabb fájlrendszer attribútumok és lehetséges értékeik:
- Létrehozás után módosítható attribútumok:
- Csak olvasható mód: readonly = on | off
- Tömörítés: compression = on | off | lzjb | gzip | gzip-[1-9] | zle
- Másolatok számának beállítása: copies = [1-3] . Ebben az esetben a fájlrendszert több másolatban tárolja, ha lehetséges, akkor külön eszközön.
- Deduplikáció: dedup = on, off
- Hozzáférési idő használata: atime = on | off
- Adatintegritás-ellenőrzés: checksum = on | off | fletcher2 | fletcher4 | sha256 . Ezt nem ajánlott kikapcsolni, alapértelmezetten be van kapcsolva, fletcher4 algoritmus az alapértelmezett.
- Végrehajtás engedélyezése a fájlrendszeren: exec = on | off
- Fájlrendszerméret-korlátozás: quota = <méret> | none
- Setuid engedélyezése: setuid = on | off
- Bővített attribútumok engedélyezése: xattr = on | off
- Titkosítás (jelenlegi fuse-zfs verzió még nem támogatja!): encryption = on | off
- Létrehozás után nem módosítható attribútumok:
- fájlnév case sensitivity: casesensitivity = sensitive | insensitive | mixed
- Unicode fájlnevek normalizálásának algoritmusa: normalization = none | formC | formD | formKC | formKD . Ha engedélyezzük, akkor a fájlneveken végzett össszehasonlító műveletek esetén a fájlneveket unicode kódolásúnak értelmezi és ezek normalizált alakjait hasonlítja össze. Kikapcsolása esetén összehasonlításnál nem értelmezi kódolás szerint a fájlneveket.
- Csak UTF-8 karakterek engedélyezése: utf8only = on | off . Ha be van kapcsolva, akkor visszautasít olyan fájlneveket, ami az UTF-8 karakterkészletében nem szereplő karaktert tartalmaz. Kikapcsolása esetén nem értelmezi a fájlneveket.
Snapshotok: Snapshot létrehozása:
zfs snapshot <fájlrendszer azonosító>@<snapshot név>
Példa: Egy 201012 nevű, majd egy 201012_2 nevű snapshotot hozunk létre az fs1 fájlrendszerről:
root@home:/# zfs snapshot pool1/fs1@201012
root@home:/# zfs snapshot pool1/fs1@201012_2
A snapshotokat a következő paranccsal lehet kilistázni táblázatos formában:
root@home:/# zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT pool1/fs1@201012 21K - 13,4M - pool1/fs1@201012_2 20K - 13,4M -
Korábbi snapshot visszaállítása:
zfs rollback <fájlrendszer azonosító>@<snapshot név>
Példa: Állítsuk vissza az fs1 fájlrendszert a 201012 nevű snapshotra:
root@home:/# zfs rollback pool1/fs1@201012
Klónozás:
Egy fájlrendszernek csak egy snapshotjából lehet klónt létrehozni:
zfs clone <fájlrendszer azonosító>@<snapshot név> <klónozott fájlrendszer neve>
Példa: hozzuk létre fs1-nek a 201012 snapshotból készített klónját
root@home:/# zfs clone pool1/fs1@201012 pool1/fs1clone
Ekkor létrejön a pool1-ben a klónozott fájlrendszer:
root@home:/# ls fs1 fs1clone
Egy klón fájlrendszer függetlenné tehető a snapshot-tól a következő paranccsal, így a snapshot törölhető, egyébként a klón törléséig nem:
root@home:/# zfs promote pool1/fs1clone
5 Teljesítmény mérések
Néhány nem mérvadó mérési eredmény a ZFS/Linux-FUSE és OpenSolaris 2009.06 ZFS fájlrendszer teljesítményének összehasonlításáról, azonos fájlrendszeren és hardveren, iozone többszálú méréssel. A pool egy RAID-Z, rajta egy GZIP-tömörített fájlrendszer. A Linux kernel verziója 2.6.36.
Első írás a fájlrendszerre:
Fájl:zfs bench init write.png
Újraírás:
Fájl:zfs bench rewrite.png
Véletlenszerű írás:
Fájl:zfs bench random write.png
Olvasás:
Fájl:zfs bench read.png
Véletlenszerű olvasás:
Fájl:zfs bench random read.png
Az eredmények alapján az írási teljesítményben rosszul teljesít a FUSE megvalósítás az OpenSolarishoz képest. Az olvasási tesztben a FUSE jóval gyorsabb, ez viszont csak a gyorsítótárazás hatékonyságát tükrözi az OpenSolarissal szemben.
6 Források
http://hub.opensolaris.org
http://zfs-fuse.net
http://www.sun.com