ZFS: Kirjoitusten niputtaminen ja ZIL

ZFS:n kirjoitus tapahtuu niputetuissa transaktioissa, DMU:issa (Data Management Unit). Oletusarvoisesti DMU:ihin kertynyt data kirjoitetaan levylle 5 sekunnin välein, joten ZFS voi niputtaa (ja yhdistellä jne.) 5 sekunnin aikana tapahtuneet kirjoitukset yhteen ja samalla muuttaa sattumanvaraiset kirjoitusoperaatiot sekventiaalisiksi, koska kirjoitusten ei tarvitse tapahtua samaan paikkaan, missä vanha data oli (copy-on-write).

Tämä tietysti johtaa kaskadireaktioon: myös metadataa pitää muuttaa joka DMU:n yhteydessä, ja näiden muuttuneiden metadatablokkien referenssit pitää myös muuttaa edellisen tason ("parent") metadatassa, aina ylimmälle tasolle eli überblokkiin asti. Überblokit (128 kpl 1 kB sektoria ring bufferissa) ovat ainoa tietyssä paikassa levyllä sijaitseva tietue ZFS:ssä (tietysti levynimiöiden ohella). Datapuun alun on oltava luettavissa tietystä tunnetusta paikasta, jotta tiedetään minne (meta)data on sijoitettu.

ZIL eli ZFS Intent Log huolehtii POSIX-tyylisten synkronisten kirjoitusten toteuttamisesta. Synkronisessa kirjoituksessa datan on oltava fyysisesti tallessa ennen kuin kirjoitusoperaatio voi palauttaa "success"-vasteen. Normaalisti ZIL käyttää poolin vapaata tilaa, mikä on hidasta, koska synkroniset kirjoitukset tehdään heti odottamatta tuota 5 sekunnin DMU-niputusaikaa. Tosin tässäkin ZFS on "fiksu", koska ZILin kautta kirjoitettua dataa ei kirjoiteta uudelleen seuraavassa DMU:ssa; ainoastaan metadatan pointer päivitetään.

ZIL voidaan asettaa käyttämään erillistä levyä (yleensä SSD tai RAM-SSD), jolloin voidaan hyötyä hyvin suurista kirjoitusnopeuksista ja saada jopa synkroniset kirjoitukset nopeiksi. Erillisellä levyllä oleva ZIL on nimeltään SLOG (Separate LOG). Data, joka kirjoitetaan SLOGille, löytyy edelleen RAM:sta ja kirjoitetaan myös pooliin seuraavan DMU:n aikana. Näin SLOGissa oleva data on transitionaalista ja sitä tarvitaan vain, jos kone kaatuu tämän 5 sekunnin aikana.

ZFS jakaa käytettävissä olevan levytilan muutamaan sataan alueeseen, metaslabiin, joita ei kirjoiteta kerralla täyteen, vaan osa joka metaslabista jätetään tyhjäksi ja siirrytään seuraavaan, kun tulee lisää dataa. Tämä vähentää osaltaan datapuun fragmentaatiota ja lokalisoi sen pienemmälle alueelle. Kun viimeinen metaslab on melkein täytetty, tätä sivuun jätettyä tilaa aletaan käyttää. Kun metaslab täyttyy 96-prosenttisesti, tilan allokointistrategia muuttuu "first-fit" -> "best-fit". (Tämä ei ole kovin hyvin dokumentoitu ominaisuus.)

Metaslabien vapaan alueen seuranta on kiinnostava innovaatio tässä yhteydessä. Siinä, missä muut tiedostojärjestelmät käyttävät bittikarttaa tai B(*)-puita, ZFS käyttää Space Maps -nimistä rakennetta. Tässä ideana on, että allokaatiot ja vapautukset muodostavat listan, jota läpikäymällä löydetään vapaa tila.

Lisätietolinkkejä: