ZFS on Linux

Pokud jste se rozhodli pro ZFS, tak asi už víte proč. Jinak napoví Google: ZFS The Last Word in File Systems. V tomto příspěvku spíše upozorním na některá omezení (jak ZFS obecně, tak současné implementace v linuxu) a popíši vlastní použití v případě malé domácí sítě a zálohování dat.

ZFS on Linux nebo ZFS-FUSE?

Používáte-li 64bitovou architekturu, zvolte ZFS on Linux. ZFS-FUSE (také známý jako ZFS for Linux) je s vývojem trochu více pozadu, má omezení daná FUSE a vždy asi bude mít nižší výkon. V současné době (únor 2012) je největším praktickým omezením ZFS-FUSE nemožnost procházet snapshoty – je nutné je nejprve naklonovat (tj. vyžadují extra volný prostor).

Struktura ZFS

ZFS zahrnuje jak práci s logickými svazky (vdev) tak i souborovými systémy (dataset). Typická struktura vypadá následovně:

mypool  -- aka zpool
  mirror -- aka vdev
    ata-WDC_WD10EARX-00N0YB0_WD-WCC0T0755937 -- fyzický harddisk A
    ata-WDC_WD10EARX-00N0YB0_WD-WMC0S0037808 -- fyzický harddisk B
  mirror
    ata-WDC_WD10EARX-00N0YB0_WD-WCC0T0755222 -- fyzický harddisk C
    ata-WDC_WD10EARX-00N0YB0_WD-WMC0S0037111 -- fyzický harddisk D

Slovy:

  • Úplně nejvyšší vrstva je souborový systém, v ZFS zvaný obecně dataset.
  • Datasety jsou obsaženy v zpoolu. Nově vytvořený zpool obvykle automaticky obsahuje i výchozí dataset shodného jména.
  • Zpool se skládá z virtuálních zařízení zvaných vdev. Vdev je typu raid0, mirror, raid-z – popisuje tedy i typ případné redundance.
  • Vdev se skládá buď z blokových zařízení (celý hdd, diskový oddíl) nebo souborů na jiných souborových systémech (má smysl snad jen při testování).

V případě nevratného poškození jakéhokoliv vdev dojde i ke ztrátě zpoolu. Ve výše uvedeném příkladu je disk B kopií (zrcadlem) disku A a podobně D je kopií disku C. Selže-li současně disk A a D, nic se neděje, neb všechny vdev jsou stále funčkní, byť v degradovaném režimu. Selže-li současně A a B, pak je ztracen i zpool mypool.

 

Co se moc nezdůrazňuje

Před migrací na ZFS si promyslete, co vlastně chcete: úložiště bez redundance (tj. nemožnost automatické opravy poškozených dat), redundanci v rámci jednoho fyzického disku (copies=2), RAID-1 (mirroring) či vylepšený RAID-5/6 (raidz1, raidz2, či raidz3). Některé změny existující struktury totiž nelze snadno provést a obvykle bývá nutno daný ZFS pool zrušit a data obnovit ze zálohy na nově vytvořenou strukturu.

Například:

  • Situace: pool1 mirror sda sdb (tj. mirror se dvěma disky) -> pomocí zpool split pool1 pool2 lze zrušit mirror, vzniknou dva neredundantní pooly pool1 a pool2 a každý bude mít přiřazen jeden z disků sda a sdb. pool2 bude klonem pool1.
  • Situace: pool1  sda sdb (tj. neredundantní úložiště rozložené na dva disky) -> příkaz zpool split nelze použít. Ani není jiná cesta, jak uvolnit např. disk sdb, aby šel vyjmout z pool1 a použít někde jinde… Obdobné je to s raidz.

Pravidlo je celkem jednoduché – jakmile jednou vytvoříte nějaké „vdev“, tento už je obvykle neměnný. Více detailů lze nalézt v dokumentaci k Solarisu. Přidávat nové disky či v případě mirror/raidz vyměňovat ty poškozené obvykle není problém, ale ubírat, to už ano.

Vyplatí se několikrát si přečíst ZFS Best Practices Guide, ale i hledat zkušenosti ostatních, např. Home Server: RAID-GREED and Why Mirroring is Still Best, ZFS: Read Me 1st.

Malá domácí síť a zálohování

Je to jako se vším: kompromis mezi náklady (investice, provoz, hluk) a zabezpečením dat. Ceny za GB disků sice klesají (a kvůli povodním v třetím světě občas i rostou), ale ne tak rychle, jak bych si přál;  zatím to řeším následovně:

  • Pracovní stanice:
    • SSD disk pro systém, ext4;
    • 2 klasické plotnové disky pro $HOME a sdílená data v konfiguraci raid1 (mirror).
  • Malý server:
    • notebookový plotnový disk pro systém, ext4;
    • klasický plotnový disk pro data, ZFS bez redundance.
  • Ostatní počítače (mythtv, atd.),  mají obvykle jen jeden disk, ZFS jsem nenasadil.

Ochranu před ztrátou dat kvůli selhání disku řeším zálohami duplicitně na dva externí disky, přičemž:

  • každý z těchto disků samostatně pojme data ze všech počítačů v síti;
  • na externích discích používám ZFS s maximální kompresí (compress=gzip-9);
  • zálohované disky, které používají ZFS, zálohuji pomocí „zfs send | zfs receive“. Jednotlivé snapshoty umožňují přístup ke starším zálohám.
  • zálohované disky, které nepoužívají ZFS, zálohuji pomocí rsync s využitím snapshotů ZFS mezi zálohami.

Ochranu před vlastními chybami  (tj. ztráta dat kvůli nechtěnému smazání) řeším pomocí skriptu zfs-auto-snapshot. Až na chybějící GUI je to funkčně totéž jako Time Machine – formou automatizovaného vytváření a mazání snapshotů na ZFS discích v počítačích. Více informací ohledně přístupu ke snapshotům viz tento příspěvek v projektu ZFS on Linux (vyžaduje autofs, nefunguje pro zfs-fuse).

Pokud připojujete externí disk, na který je záloha kopírována, ke stejnému počítači, jehož disky jsou zálohovány, vyplatí se:

  • vytvořit na tomto externím disku samostatný pool odlišného jména (např backup_pool), než jsou pooly zálohované;
  • importovat backup_pool do alternativního přípojného bodu:
# zpool import -o altroot=/media/backup_pool backup_pool
  • a nastavit pro tento nejvýše nadřazený souborový systém (tj. pool) uživatelskou vlastnost, která zabrání skriptu zfs-auto-snapshot ve vytváření snapshotů na tomto disku:
# zfs set com.sun:auto-snapshot=false backup_pool

Pro využití inkrementálních záloh na externím disku je třeba „podržet“ snapshot, který byl v minulosti zálohován, i na zálohovaném disku. Tzn., že je poměrně nevhodné zálohovat některý ze snapshotů vytvořený skriptem zfs-auto-snapshot (protože tento dříve či později bude automaticky smazán), ale raději vytvořit ručně vlastní a tento nemazat alespoň do příští zálohy.

Potíže s fragmentací

Kromě nesporných výhod má ZFS i jednu hodně nepříjemnou vlastnost, která je důsledkem zápisu dat systémem „copy-on-write“ (COW). Tou je rostoucí fragmentace úměrně zaplnění poolu. Vysoká fragmentace se projeví velkým počtem IO operací a nízkou přenosovou rychlostí. Rapidní nárůst negativních efektů se obvykle objeví při cca 80% zaplnění poolu. Největší problém nastane při zápisu a současně čtení (i malé IO pro zápis významně ovlivní čtení byť i nefragmentovaných bloků).

Vzhledem k tomu, že ZFS nemá nástroj na defragmentaci, řešením je rozšiřovat pool o další disky (vdev) nebo celý pool a datasety vytvořit znovu ze zálohy. (V případě použití zfs send je zřejmě třeba obnovit pouze poslední stav – tj. bez snapshotů neb ty by do jisté míry obnovily i existující fragmentaci. Dost možná, že ani toto nepomůže a je nutné použít zfs destroy na všechny datasety, ručně je vytvořit znovu a _zkopírovat_ obsah ze zálohy…)

Pomocí debugovacího příkazu zdb a tohoto skriptu fragments.awk lze orientačně zjistit míru defragmentace v datasetu:

# zdb -ddddd mypool/mydataset | gawk --non-decimal-data -f fragments.awk

A nakonec obligátní pamatováček

Vytvoření poolu na dvěma disky v režimu mirror a současně file systému, připojí se do /mypool

# zpool create mypool mirror /dev/disk/by-id/some-disk-id /dev/disk/by-id-some-other-id

další volby:

altroot … všechny podřízené datasety (souborové systémy) budou připojovány pod /altroot. Hodí se pro externí disk, na který se zálohuje. Nejedná se o trvale nastavený přepínač, je třeba jej vždy použít explicitně.

Vytvoření dodatečných, podřízených datasetů v rámci existujícího poolu

# zfs create newdataset mypool

další volby:

mountpoint=/some/path … souborový systém se připojí jinam, než do /mypool (či /altroot).
compression=lz4 … transparentní komprese dat, možno ponechat aktivní pro celý pool, neb obtížně komprimovatelná data nekomprimuje (tj. šetří CPU).
atime=off … vypnutí zápisu času posledního čtení souboru.

Připojení a odpojení poolu

# zpool import -d /dev/kde/je/zfs/disk -o altroot=/media/zaloha backup_pool
# zpool export backup_pool

Vlastnost „altroot“ je dočasná a hodí se pro situace, kdy nechceme, aby se importované souborové systémy připojily dle svých vlastností (v případě importu záloh by mohlo dojít ke kolizi s aktuálními přípojnými místy).

Přidání cache pro zpool

L2ARC cache je dočasné úložiště pro ukládání často používaných dat. Vzhledem k rychlé přístupové době je pro tento účel možno využít i např. SD kartu či USB flash disk. Pokud dojde k poškození L2ARC, souborový systém to nijak neovlivní.

# zpool add mypool cache /dev/sdX

Vytvoření swap na ZFS

ZFS primárně nepodporuje swap, nicméně toto omezení lze obejít pomocí vytvoření virtuálního svazku (zařízení připojeného do /dev/zdX).

# zfs create -V 1gb pool/swap
# mkswap -L swap /dev/zdX
# swapon /dev/zdX

Toto nefunguje se ZFS-FUSE.

ZFS stream

# zfs send pool/dataset@snapshot | ssh root@host -c blowfish zfs receive -v other_pool/other_dataset

Další volby:

zfs receive -nv … nic nekopíruje, pouze ukáže, jak se bude jmenovat pool/dataset@snapshot na cílovém počítači
ssh -c blowfish … použití výpočetně méně náročné šifry urychlí kopírování mezi nevýkonnými počítači.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *

Tato stránka používá Akismet k omezení spamu. Podívejte se, jak vaše data z komentářů zpracováváme..