Migrace FreeBSD 8.1 na ZFS

Podělím se o zkušenosti jak zmodernizovat filesystém ve FreeBSD 8.1 a dosáhnout tak 100% ZFS.

26.5.2010 16:00 | Radim Kolář | přečteno 10566×

Migrace FreeBSD 8.1 na ZFS filesystém

Kdy

V řadě FreeBSD 8 bylo ZFS poprvé označeno nálepkou produkční kvalita. Beta status ZFS ale uživatele neodradil a ZFS se stalo používané i v sedmičkové řadě. Kupříkladu apache.org jede na FreeBSD-7/ZFS a to není žádný nevýznamný server. V podpoře ZFS se neusnulo a současná prerelase verze FreeBSD 8.1 má už kompletní podporu pro ZFS filesystém včetně bootování. ZFS se tak stalo svou kvalitou integrace srovnatelné s 25 let starým UFS filesystémem. Pokud chcete přemigrovat na ZFS teď je ta nejlepší doba. Ve FreeBSD 9 se počítá se ZFS jako s výchozím filesystémem.

Co nového ve FreeBSD 8.1

Ve verzi 8.1 která se nyní připravuje k vydání byly provedeny další významné změny. Bylo naimportováno novější ZFS: zpool verze 14 a zfs verze 3. Důležité je že tato verze je shodná s verzí v OpenSolarisu 2009.06 a tak můžete testovat ZFS implementace v OpenSolarisu a FreeBSD proti sobě. Dále byla zjednodušena podpora bootování - zfs má nyní svůj loader a přibyla podpora NFSv4 ACL, která je nyní podporována i na UFS2 filesystému. Bylo načase, protože klasický unixový systém práv je už outdated. S podporou POSIX ACL se do ZFS nepočítá - ZFS to neumí ani na Solarisu. Je to docela škoda, protože POSIX ACL jsou unix-like a snadnější na použití. NFS4 ACL jsou podobné ACL které používá systém Windows na NTFS. Byla taky opravena celá řada chyb, zejména importem se Solarisu - nejednalo se tedy o chyby specifické pro FreeBSD.

Proč Migrovat

Rozhodl jsem se přejít z kombinace UFS2+GJOURNAL na 100% ZFS. UFS2 s GJOURNALem nebyla špatná kombinace, zápis byl sice pomalejší díky žurnálování dat i metadat ale pokud se použilo zařízení vyhrazené pro žurnálování tak to nebylo zlé. V praxi totiž mnohem více z disku čtete než zapisujete. GJOURNAL rozhodně hodnotím kladně - čekat na proběhnutí fsck byla nuda a na 32-bitovém FreeBSD nešlo dělat fsck na větších systémech než zhruba 1,5 TB, protože docházela pamět. fsck nebylo potřeba moc často - většinou jen díky výpadku HW, ale dokázalo odstavit server na dlouhou dobu a ne vždy bylo schopno běžet na pozadí. ZFS jsem chtěl zejména kvůli sdílení volného místa napříč filesystémy, kompresi, self healing a snadnější administraci.

Co bude potřeba

Pro optimální provozování ZFS budete potřebovat 64-bitový systém. ZFS totiž používá 128-bitové ukazatele a s těmi se pracuje mnohem snáze pokud se zpracovávají po 64-bitech. ZFS nepoužívá sdílenou cache se systémem virtuální paměti protože používá ARC algoritmus v kombinaci s MFU a MRU. Toto je pro cachování filesystému lepší než MRU algoritmus, který implementuje většina systémů pro správu virtuální paměti. Trochu sice navzájem spolupracují - když má systém nedostatek paměti tak řekne ZFS aby nějakou uvolnil ale ZFS nemění velikost své cache paměti tak agresivně jako to dělá VM. ZFS můžeme říci kolik paměti má maximálně a minimálně používat jako cache, ale současná implementace poměrně často tento limit překročí směrem nahoru až na dvojnásobek. Proto je potřeba mít k dispozici dostatek fyzické paměti RAM. Solaris je v tomto lepší než FreeBSD a na něm můžete provozovat ZFS i na 256MB RAM bez toho aby system házel kernel panic z důvodu nedostatku RAM poněvadž se ZFS příliš rozežralo. Ve FreeBSD 8 je už ZFS více civilizované a nenarůstá nad stanovený paměťový limit tak často.

Na FreeBSD bylo empiricky odskoušeno že minimální počet fyzické paměti při které to nehází kernel panic je 512MB RAM vyhrazené pro kernel. Standardně FreeBSD nebylo takto nastaveno a tak se musela ručně nastavovat konfigurace VM. Změněno to bylo ve FreeBSD 7.2 a pozdějších kde nemusíte na 64-bitových systémech již nic ručně ladit. Na 32-bit systému musíme nastavit vm.kmem_size="XXM" a vm.kmem_size_max="XXM". Maximální hodnoty na které to jde nastavit bez rekompilace kernelu jsou 512MB, což je taky doporučovaná hodnota. Protože paměť potřebujete nejen pro kernel ale i pro uživatelské aplikace, tak 768 MB RAM bude rozumné minimum pro práci se ZFS. V případě 512 MB fyzické paměti nastavte kmem_size na 330MB ale očekávejte občasné kernel panicy při vyšší zátěži.

Podroběji se této problematice věnuje tato stránka. Vzhledem k dnešním cenám DRAM pamětí bych však doporučoval investovat místo do studia mystérií ZFS při nedostatku RAM do DDR2 paměťových chipů.

Jak

Připojíme nový disk. V našem případě to bude da0. Vytvoříme na něm EFI partition tabulku a boot oblast. Swap oblast nedělám, při 4 GB RAM ve stroji se mi stejně nikdy nepoužila. V případě krize mohu swapovat do souboru.

gpart create -s gpt da0
gpart add -b 34 -s 128 -t freebsd-boot da0

zjistíme velikost disku v sektorech pomocí gpart list. Ve výpisu hledáme náš nový disk

Geom name: da0
first: 34
last: 16777182

Boot partition končí sektorem 161 (velikost je 128), takže velikost ZFS partition bude 16777182-161 tedy 16777021. Taky mne napadlo ještě pojmenovat boot partiton.

gpart add -b 162 -s 16777021 -t freebsd-zfs -l fbsd-zfs-root da0
gpart modify -i 1 -l freebsd-boot da0

nahrajeme boot loader

gpart bootcode -b /boot/pmbr da0
gpart bootcode -p /boot/gptzfsboot -i 1 da0

vytvoříme zfs pool v nově vytvořené partition

zpool create -m /mnt root /dev/gpt/fbsd-zfs-root

vytvoříme nějaké ty filesystémy - zde se fantazii meze nekladou. Potřebujeme jich tolik abychom mohli nastavit kompresi dat pro jednotlivé adresáře a ZFS neumí nastavovat properties per adresář ale jen per filesystém - v ZFS terminologii nazývaný dataset.

zfs create root/tmp
zfs create root/var
zfs create root/var/empty
zfs create root/usr
zfs create root/home
zfs create root/usr/ports
zfs create root/usr/obj
zfs create root/usr/ports/distfiles
zfs create root/var/log
zfs create root/var/mail
zfs create root/var/crash
zfs create root/var/db
zfs create root/var/tmp
zfs create root/usr/src

nastavíme kompresi, poupravíme /var/empty a vypneme sledování atime, které necháme zapnuté jen na svazku kde máme uloženou poštu. ZFS má dvě kompresní metody klasický Gzip a LZJB. LZJB je realtime komprese - nekomprimuje moc, ale je velmi rychlá. LZJB není zase tak špatná, běžné textové dokumenty dosahují komprimačního poměru 1.4-1.6, gzip na nich dosahuje poměru i přes 2,5.

zfs set compression=gzip-4 root/var/mail
zfs set compression=gzip-4 root/usr/ports
zfs set compression=off root/usr/ports/distfiles
zfs set compression=gzip-4 root/usr/src
zfs set compression=gzip-9 root/var/crash
zfs set compression=lzjb root/tmp
zfs set compression=lzjb root/var/tmp
zfs set compression=lzjb root/var/log
zfs set compression=gzip-4 root/var/db

zfs set readonly=on root/var/empty
zfs set atime=off root
zfs set atime=on root/var/mail

překontrolujeme nastavení pomocí zfs get compression a pokud jsme spokojeni můžeme překopírovat data. Vhodné je použít dump a restore. Dělá se to takto:

cd /mnt/var
dump -0 -L -f - /var | restore -r -f -

Po nakopírování dat se můžeme podívat jak se nám zakomprimovaly zfs get compressratio. Mne se nejvíce zakomprimovalo /usr/src - poměr 3,2 a /var/log - poměr 2,4.

Editace konfiguračních souborů aby nám nový systém správně nabootoval.

  1. Do /mnt/etc/rc.conf a dopsat zfs_enable="YES"

  2. smazat reference na UFS filesystem z /mnt/etc/fstab. V /etc/fstab není potřeba mít žádné zfs filesystémy uvedené takže tam zbyde jen swap a případná DVD jednotka.

  3. Do /mnt/boot/loader.conf přidat zfs_load="YES"

  4. Do /mnt/boot/loader.conf přidat vfs.root.mountfrom="zfs:root"

  5. Překopírovat /boot/zfs/zpool.cache do /mnt/boot/zfs

  6. Změnit adresář kam budeme zfs mountovat: zfs set mountpoint=/ root

Hotovo

Nyní už je dílo hotovo. Odpojíme starý disk ze systému a případně zařídíme aby BIOS nabootoval z nového SCSI disku, protože předtím bootoval z IDE.

Dojmy po migraci

První věc co vás zaujme bude výrazně rychlejší boot, místo ušetřené kompresí a nebudete již nikdy potřebovat fsck. Pro zajímavost se můžeme podívat kolik místa nám komprese dat ušetřila zfs get compressratio. Mně nejvíc fascinoval vysoce kvalitní read ahead, který dokázal to, že procesy které dřív tradičně trávili čas čekáním na disk nyní neustále běžely a nedostávalo se jim CPU. make buildworld -j20 na 8 core CPU mašině jen svištěl.

Celkově systém výrazně méně seekuje hlavami po disku a je tak o mnoho tišší než býval. ZFS se snaží z důvodu výkonu pohyb hlav nad diskem minimalizovat. Tato technika není neznámá - proslavila systém Novell Netware v dobách jeho slávy. U ZFS dochází k pohybu hlav při zápisu zřídka, zapisuje se v dávkách do souvislé oblasti. Nejvíce se pohybuje hlavama při procházení adresářů, ale je to méně než u UFS a systémech z něj vycházajících třeba linuxový ext2, které mají inody a adresáře na rozdílných místech na disku.

Cache v ZFS je opravdu zajímavá, není tak agresivní jako VM MRU cache a proto trvá déle než se vyladí pro probíhající workload a najde optimální sadu dat, kterou se vyplatí držet v cache. Může se jednat až o hodiny. Fileserveru tedy časté rebooty z hlediska výkonu nesvědčí, po rebootu to takříkajíc moc nejede. Inteligentněji se chová v případě multiuživatelského přístupu. Nedochází zde k jevu že jeden proces který provádí intenzivní IO operace vyhodí z cache ostatním uživatelům často používaná data, známá to nevýhoda MRU algoritmu.

Turbo

ZFS filesystém umí používat Flash disky jako L2ARC cache a výrazně tak zvýšit výkon zařízení. L2ARC cache se používá pro urychlení náhodných čtení. Nainvestoval jsem proto tisícovku do Corair Voyager 16 GB a připojil ho k systému jako da1. ZFS řekneme že ho má používat jako cache zpool add root cache da1. Systém je velmi výrazně rychlejší, podle testů na internetu je zrychlení pro čtení dat 3-5x. U mne to bylo zhruba 2,5x, chtělo by to asi větší flash disk. Po jednodením testování si to opravdu nemohu vynachválit.

Pokud chceme urychlit práci aplikací které často volají fsync - typicky databáze - tak ZFS umožňuje použít vyhrazené zařízení pro zápis ZIL logu. Narozdíl od L2ARC cache u ZIL zařízení prakticky nezáleží na velikosti - několik GB úplně postačí. Doporučuji zakoupit SDD disky optimalizované pro ténto účel. Mám nejlepší zkušenosti s disky firmy Intel X25-E u kterých nenastává zhruba po měsíci používáni degradace výkonu. Verze ZFS která je ve FreeBSD 8.1 ještě neumí později odstranit toto log zařízení ze ZFS poolu. Jak ho jednou do poolu přidáte nelze ho již odebrat. Toto omezení zmizí až bude do FreeBSD naimportováno novější ZFS, trend je synchronizovat ZFS verzi oproti OpenSolarisu. L2ARC zařízení se toto omezení netýká, ty odebrat můžete kdykoliv.

Tuning ZFS

Tuning ZFS je jednoduchá záležitost, ladíme jen velikost cache. Ta se nastavuje v /boot/loader.conf a obsahuje dvě zajímavé položky vfs.zfs.arc_max a vfs.zfs.vdev.cache.size. Obě dvě označují velikosti cache paměti v bytech. Současné využití ZFS cache zobrazíte příkazem

sysctl -a | grep zfs | grep -E \(size\|used\)

ZFS používá při zápisu COW - copy on write a proměnou velikost bloku. Toto vadí databázím které často zapisují do souboru na náhodná místa a současně často dělají tablescany kdy sekvenčně načítají soubor čemuž fragmentace vniklá pomocí COW vadí. V první řadě je potřeba databázi provozovat na filesystému který má stejnou velikost bloku jako databáze - zfs create -o recordsize velikost. Pokud toto nestačí tak můžeme vytvořit v ZFS poolu blokové zvol zařízení a toto tak zformátovat jako UFS nebo ho rovnou použít bez filesystému pokud to databáze umí. Podrobněji je tato tématika probírána zde.

Poslední často používanou tuning volbou je vfs.zfs.zil_disable="1" které zakáže použití ZIL logu pro aplikace volající často fsync. Integrita ZFS filesystému na disku tímto netrpí, ten je vyloženě odolný a dokáže pracovat i se zapnutou ATA write cache. Tato změna se týká jen aplikací, protože při výpadku ZFS se ztratí pár posledních ZFS transakcí, což nemusí některé aplikace ustát.

Například databáze pro svoji správnou činnost potřebují provádět aktualizace dat v určitém pořadí, aby je mohli v případě výpadku obnovit. Je pro ně životně důležité zapsat změny do svého protokolačního souboru před tím než budou zapsány do datových stránek. Pokud se zapíše do datových stránek předtím než se zapíše do logu tak se v případě havárie poškodí datové stránky, protože nebude možné změny datových stránek vrátit nazpět.

Toto se netýká databáze MySQL která tyto problémy v MYISAM tabulkách vůbec neřeší. Tam se prostě zapisuje do datových stránek rovnou a když později systém zdetekuje chybnou datovou stránku, na což často nepřijde protože MySQL nepoužívá ani kontrolní součty stránek, tak se tabulka označí jako chybná a opravný program dodávaný k databázi tyto stránky a současně i data odstraní. Většina distribucí navíc spouští opravný program myisamchk automaticky před startem MySQL, což má za následek záhadné mizení dat z tabulek. Pokud tedy provozujete nad ZFS mysql tak ten ZIL log vypněte - získáte tím zlepšení výkonu a při havárii systému se vám stejně poškodí databáze tak jako tak.

Vyzkoušejte si to taky

ZFS je dostatečný důvod pro migraci z Linuxu na FreeBSD 8.1. Na opensolaris bych z linuxu nemigroval. Hardwarová podpora je slabší, administrace je náročná, uživatelská základna menší a programových balíčků taky není zrovna nejvíce. Navíc neni opensolaris oficiálně podprován komerčním softwarem - kupříkladu Oracle 11g a ani se nesnaží být se Solarisem binárně kompatibilní. Je to prostě z hlediska producentů software jiný operační systém - ne Solaris zdarma. Řekl bych že opensolaris nemá dnes co nabídnout pokud nepatříte mezi hynoucí hardcore Sun fanoušky nebo si nechcete testovat změny OS než se promítnou do Solarisu. OpenSolaris se ani nehodí na trénování Solaris administrace, spousta věcí je jiná.

ZFS je krásná ukázka toho jak technologie může vypadat pokud slouží lidem a ne naopak.

Online verze článku: http://www.linuxsoft.cz/article.php?id_article=1712