
Den hÀr vÄren har vi redan diskuterat vissa introduktionsteman, som och . I den andra lovade vi till och med att fortsÀtta studera prestanda för olika fler-disktopologier i ZFS. Detta Àr nÀsta generations filsystem som nu implementeras överallt: frÄn till .
NÄvÀl, idag Àr den mest passande dagen för att bekanta sig med ZFS, nyfikna lÀsare. Bara kom ihÄg att enligt en blygsam uppskattning frÄn OpenZFS-utvecklaren Matt Arens, "det Àr verkligen komplicerat".
Men innan vi kommer till siffrorna - och de kommer, det lovar jag - för alla alternativ för Ättadiskkonfigurationer av ZFS, mÄste vi prata om hur som ZFS överhuvudtaget lagrar data pÄ disken.
Zpool, vdev och device

Detta diagram över hela poolen innehÄller tre hjÀlp-vdev:er, en av varje klass, och fyra för RAIDz2

Vanligtvis finns det inga skÀl att skapa en pool av olika typer och storlekar av vdev - men om du vill, finns inget som hindrar dig frÄn att göra det
För att verkligen förstÄ filsystemet ZFS mÄste man ta en noggrann titt pÄ dess faktiska struktur. För det första förenar ZFS traditionella nivÄer av volymhantering och filsystem. För det andra anvÀnder det en transaktionell mekanism för kopiering vid skrivning. Dessa egenskaper innebÀr att systemet Àr strukturellt mycket annorlunda Àn vanliga filsystem och RAID-arrayer. Den första uppsÀttningen grundlÀggande byggstenar för förstÄelse: det Àr lagringspoolen (zpool), det virtuella enhet (vdev) och den verkliga enheten (device).
zpool
Lagringspoolen zpool Àr den översta strukturen i ZFS. Varje pool innehÄller en eller flera virtuella enheter. I sin tur innehÄller var och en av dem en eller flera verkliga enheter (device). Virtuella pooler Àr fristÄende block. En fysisk dator kan innehÄlla tvÄ eller flera separata pooler, men varje Àr helt oberoende av de andra. Pooler kan inte dela virtuella enheter.
Redundansen i ZFS finns pÄ nivÄn av virtuella enheter, snarare Àn pÄ nivÄn av pooler. PÄ poolnivÄ finns det absolut ingen redundans - om nÄgon vdev-lagringsenhet eller special-vdev gÄr förlorad, förloras hela poolen.
Moderna lagringspooler kan överleva förlust av cache eller logg frĂ„n det virtuella enheten â Ă€ven om de kan förlora en liten mĂ€ngd orena data om de förlorar vdev-loggen under strömavbrott eller systemfel.
Det finns en vanlig missuppfattning om att "data stripes" (strimmor) av ZFS skrivs över hela poolen. Detta Àr fel. Zpool Àr inte helt enkelt en rolig RAID0, det Àr snarare en rolig med en komplex och variabel mekanism för fördelning.
För det mesta fördelas poster mellan tillgÀngliga virtuella enheter baserat pÄ det tillgÀngliga fria utrymmet sÄ att teoretiskt alla kommer att fyllas samtidigt. I senare versioner av ZFS beaktas den aktuella anvÀndningen (utnyttjandet) av vdev - om en virtuell enhet Àr betydligt mer belastad Àn en annan (till exempel pÄ grund av lÀsningsbelastning) kommer den tillfÀlligt att hoppa över för skrivning, trots att det finns den högsta andelen ledigt utrymme.
De inbyggda mekanismerna för att bestÀmma utnyttjandet i moderna metoder för skrivfördelning i ZFS kan minska latensen och öka bandbredden under perioder av ovanligt hög belastning - men det Àr inte fritt spelrum för oavsiktlig blandning av lÄngsamma HDD och snabba SSD i en och samma pool. En sÄdan ojÀmlik pool kommer fortfarande att fungera med hastigheten hos den lÄngsammaste enheten, det vill sÀga som om den helt bestÄr av sÄdana enheter.
vdev
Varje lagringspool bestÄr av en eller flera virtuella enheter (virtual device, vdev). I sin tur inkluderar varje vdev en eller flera verkliga enheter. De flesta virtuella enheter anvÀnds för enkel datalagring, men det finns flera hjÀlpklasser av vdev, inklusive CACHE, LOG och SPECIAL. Varje typ av vdev kan ha en av fem topologier: enhet (single-device), RAIDz1, RAIDz2, RAIDz3 eller spegel (mirror).
RAIDz1, RAIDz2 och RAIDz3 Àr speciella varianter av det som gamla kallar RAID med dubbel (diagonal) paritet. 1, 2 och 3 syftar pÄ hur mÄnga paritetsblock som tilldelas för varje dataruta. IstÀllet för separata diskar för att sÀkerstÀlla paritet, fördelar RAIDz virtuella enheter denna paritet jÀmnt över diskarna. En RAIDz-array kan förlora lika mÄnga diskar som den har paritetsblock; om den förlorar en till, gÄr den sönder och drar med sig lagringspoolen.
I speglade virtuella enheter (mirror vdev) lagras varje block pĂ„ varje enhet i vdev. Ăven om de vanligaste Ă€r dubbelspeglar (two-wide) kan det i spegeln finnas ett godtyckligt antal enheter â i större installationer anvĂ€nds ofta tredubbla speglar för att öka lĂ€sprestanda och redundans. En vdev-spegel kan överleva vilken fel som helst sĂ„ lĂ€nge minst en enhet i vdev fortsĂ€tter att fungera.
Enskilda vdev Ă€r i grunden farliga. En sĂ„dan virtuell enhet överlever inte ett enda fel â och om den anvĂ€nds som lagring eller speciell vdev, kommer dess fel att förstöra hela poolen. VĂ€rna om detta, var mycket, mycket försiktig.
Virtuella enheter CACHE, LOG och SPECIAL kan skapas enligt nĂ„gon av de ovanstĂ„ende topologierna â men kom ihĂ„g att förlust av den virtuella enheten SPECIAL innebĂ€r förlust av poolen, sĂ„ det rekommenderas starkt att ha en redundant topologi.
enhet
Detta Ă€r troligen den enklaste termen att förstĂ„ inom ZFS â det Ă€r bokstavligen ett blockenhet av godtycklig Ă„tkomst. Kom ihĂ„g att virtuella enheter bestĂ„r av separata enheter, och en pool Ă€r gjord av virtuella enheter.
Diskar â magnetiska eller solid state â Ă€r de mest vanligt förekommande blockenheter som anvĂ€nds som byggstenar för vdev. Men vilken enhet som helst med en beskrivning i /dev fungerar â sĂ„ hela hĂ„rdvaru-RAID-arrayer kan anvĂ€ndas som separata enheter.
En enkel rÄfil Àr en av de viktigaste alternativa blockenheterna som kan anvÀndas för att bygga en vdev. Testpoolar av  Àr ett mycket bekvÀmt sÀtt att kontrollera poolkommandon och se hur mycket utrymme som Àr tillgÀngligt i poolen eller det virtuella enheten i den aktuella topologin.

Du kan skapa en testpool av sparade filer pĂ„ bara nĂ„gra sekunder â men glöm inte att ta bort hela poolen och dess komponenter efterĂ„t.
Anta att du vill sĂ€tta upp en server med Ă„tta diskar och planerar att anvĂ€nda diskar pĂ„ 10 TB (~9300 GiB) â men du Ă€r inte sĂ€ker pĂ„ vilken topologi som bĂ€st matchar dina behov. I exemplet ovan bygger vi en testpool av sparade filer pĂ„ bara nĂ„gra sekunder â och nu vet vi att en RAIDz2 vdev av Ă„tta diskar pĂ„ 10 TB ger 50 TiB anvĂ€ndbar kapacitet.
En annan speciell klass av enheter Àr SPARE (reserv). Hot-swap-enheter, till skillnad frÄn vanliga enheter, tillhör hela poolen och inte en enskild virtuell enhet. Om nÄgon vdev i poolen gÄr sönder och reservutrustningen Àr ansluten till poolen och tillgÀnglig, ansluter den automatiskt till den skadade vdev.
NÀr reservutrustningen ansluts till den skadade vdev börjar den ta emot kopior eller rekonstruktioner av de data som borde finnas pÄ den förlorade enheten. I traditionell RAID kallas detta Äteruppbyggnad (rebuilding), och i ZFS kallas det "ÄterstÀllning av redundans" (resilvering).
Det Àr viktigt att notera att reservutrustningen inte permanent ersÀtter de enheter som har slutat fungera. Det Àr bara en tillfÀllig ersÀttning för att minska den tid under vilken vdev Àr i ett försÀmrat tillstÄnd. NÀr administratören har ersatt den trasiga enheten i vdev, sker det en ÄterstÀllning av redundans pÄ den permanenta enheten, och SPARE kopplas frÄn vdev och ÄtergÄr till att vara en reserv för hela poolen.
Datasatser, block och sektorer
Den nĂ€sta uppsĂ€ttningen byggstenar som vi behöver förstĂ„ i vĂ„r resa genom ZFS handlar mindre om hĂ„rdvaran och mer om hur sjĂ€lva data Ă€r organiserade och lagrade. HĂ€r hoppar vi över nĂ„gra nivĂ„er â sĂ„som metaslab â för att inte överbelasta detaljerna, och bibehĂ„lla förstĂ„elsen för den övergripande strukturen.
Datasats (dataset)

NĂ€r vi först skapar en datasats visar den hela det tillgĂ€ngliga utrymmet i poolen. Sedan stĂ€ller vi in en kvot â och Ă€ndrar monteringspunkten. Magi!

Zvol Àr mestadels bara en datasats utan sitt filsystemslager, som vi hÀr ersÀtter med ett helt normalt filsystem som ext4.
ZFS-datasettet Àr ungefÀr liknande en standardmonterad filsystem. Precis som ett vanligt filsystem kan det vid första anblick verka som "bara en annan mapp". Men precis som med vanliga monterade filsystem har varje ZFS-dataset sin egen uppsÀttning grundlÀggande egenskaper.
För det första kan det finnas en tilldelad kvot för datasetet. Om du stÀller in zfs set quota=100G poolname/datasetname, kan du inte skriva till den monterade mappen /poolname/datasetname mer Àn 100 GiB.
MĂ€rkte du nĂ€rvaron â och frĂ„nvaron â av snedstreck i början av varje rad? Varje dataset har sin egen plats bĂ„de i ZFS-hierarkin och i systemmonteringshierarkin. I ZFS-hierarkin finns det inget ledande snedstreck â du börjar med poolens namn och gĂ„r sedan vĂ€gen frĂ„n ett dataset till nĂ€sta. Till exempel, pool/parent/child för ett dataset med namnet child under den överordnade datasetet parent i en pool med ett kreativt namn. pool.
Som standard Ă€r monteringspunkten för datasetet likvĂ€rdig med dess namn i ZFS-hierarkin, med ett snedstreck i början â poolen med namnet pool monteras som /pool, datasetet parent monteras i /pool/parent, och det underordnade datasetet child monteras i /pool/parent/child. Men den systemmonterade punkten för datasetet kan Ă€ndras.
Om vi anger zfs set mountpoint=/lol pool/parent/child, dÄ kommer datasetet pool/parent/child att monteras i systemet som /lol.
Förutom datasets mĂ„ste vi nĂ€mna volymer (zvols). En volym Ă€r ungefĂ€r liknande ett dataset, förutom att den faktiskt inte har nĂ„got filsystem â det Ă€r bara en blockenhet. Du kan till exempel skapa zvol med namnet mypool/myzvol, formattera det med ett ext4-filsystem och sedan montera detta filsystem â nu har du ett ext4-filsystem, men med stöd för alla ZFS-sĂ€kerhetsfunktioner! Det kan verka dumt pĂ„ en dator, men ger mycket mer mening som backend nĂ€r du exporterar en iSCSI-enhet.
Block

En fil presenteras av en eller flera block. Varje block lagras pÄ en virtuell enhet. Blockstorleken Àr vanligtvis lika med parametern recordsize, men kan minskas till 2^ashift, om den innehÄller metadata eller en liten fil.

Vi menar verkligen, verkligen att vi inte skÀmtar om den enorma prestandaförlusten om ashift stÀlls in pÄ för lÄgt.
I ZFS-pool lagras all data, inklusive metadata, i block. Den maximala blockstorleken för varje datasets definieras i egenskapen recordsize (inrecordstorlek). Recordstorleken kan Ă€ndras, men detta pĂ„verkar inte storleken eller placeringen av nĂ„gra block som redan har skrivits till datasetet â det gĂ€ller endast för nya block nĂ€r de skrivs.
Om inget annat anges Àr den aktuella standardrecordstorleken 128 KiB. Detta Àr en slags kompromiss dÀr prestandan inte kommer att vara perfekt, men inte heller dÄlig i de flesta fall. Recordsize kan stÀllas in pÄ vilket vÀrde som helst frÄn 4K till 1M (med ytterligare instÀllningar recordsize kan stÀllas in Ànnu högre, men det Àr sÀllan en bra idé).
Varje block refererar endast till data frĂ„n en fil â du kan inte trycka in tvĂ„ olika filer i ett block. Varje fil bestĂ„r av ett eller flera block, beroende pĂ„ storlek. Om filens storlek Ă€r mindre Ă€n recordstorleken, kommer den att sparas i ett mindre block â till exempel kommer ett block med en 2 KiB fil bara att ta en sektor pĂ„ 4 KiB pĂ„ disken.
Om filen Ă€r tillrĂ€ckligt stor och krĂ€ver flera block, dĂ„ kommer alla poster med denna fil att ha storlek recordsize â inklusive den sista posten, vars huvudsakliga del kan visa sig vara .
Zvol-voly har ingen egenskap recordsize â istĂ€llet har de en motsvarande egenskap volblocksize.
Sektorer
Den sista, mest grundlĂ€ggande byggstenen Ă€r sektorn. Detta Ă€r den minsta fysiska enheten som kan skrivas eller lĂ€sas frĂ„n den grundlĂ€ggande enheten. Under flera decennier har de flesta diskar anvĂ€nt sektorer pĂ„ 512 byte. PĂ„ senare tid har de flesta diskar stĂ€llts in pĂ„ sektorer pĂ„ 4 KiB, och i vissa fall â speciellt SSD â sektorer pĂ„ 8 KiB eller till och med mer.
I ZFS-systemet finns det en egenskap som tillÄter manuell instÀllning av sektorns storlek. Denna egenskap ashift. Det Àr ganska förvirrande att ashift Àr en exponent av tvÄ. Till exempel, ashift=9 betyder sektorns storlek 2^9 eller 512 byte.
ZFS begÀr detaljerad information om varje blockenhet frÄn operativsystemet nÀr den lÀggs till i en ny vdev och stÀller teoretiskt sett in ashift automatiskt baserat pÄ denna information. TyvÀrr ljuger mÄnga diskar om sin sektorstorlek för att behÄlla kompatibilitet med Windows XP (som inte kunde förstÄ diskar med andra sektorstorlekar).
Detta innebÀr att en ZFS-administratör starkt rekommenderas att kÀnna till den faktiska sektorstorleken pÄ sina enheter och stÀlla in den manuellt ashift. Om ashift Àr instÀllt för lÄgt ökar antalet lÀs-/skrivoperationer astronomiskt. SÄ om man skriver 512-byte «sektorer» till en verklig 4 KiB-sektor mÄste man först skriva den första «sektorn», sedan lÀsa 4 KiB-sektorn, Àndra den med den andra 512-byte «sektorn», skriva tillbaka den till den nya 4 KiB-sektorn och sÄ vidare för varje skrivning.
I den verkliga vÀrlden trÀffar en sÄdan straff de fasta lagringsenheterna Samsung EVO, för vilka det mÄste gÀlla ashift=13, men dessa SSD:er ljuger om sin sektorstorlek, och dÀrför stÀlls som standard in ashift=9. Om inte en erfaren systemadministratör Àndrar denna parameter kommer denna SSD att fungera lÄngsammare som en vanlig magnetisk HDD.
För jÀmförelse, det finns praktiskt taget inget straff för att ha en för stor storlek ashift . Det finns ingen verklig prestandaförlust, och ökningen av oanvÀnt utrymme Àr oÀndligt liten (eller noll vid aktiverad komprimering). DÀrför rekommenderar vi starkt Àven för de diskar som verkligen anvÀnder 512-byte sektorer att stÀlla in ashift=12 eller till och med ashift=13, för att framgÄngsrikt se in i framtiden.
Egenskap ashift stĂ€lls in för varje virtuellt enhet vdev, och inte för poolen, som mĂ„nga felaktigt tror â och Ă€ndras inte efter att den har stĂ€llts in. Om du av misstag rubbar ashift nĂ€r du lĂ€gger till ett nytt vdev i poolen, har du permanent förorenat denna pool med en enhet med lĂ„g prestanda, och det finns vanligtvis inget annat sĂ€tt Ă€n att förstöra poolen och börja om frĂ„n början. Ăven borttagning av vdev rĂ€ddar inte frĂ„n en felaktig instĂ€llning. ashift!
Skrivningskopieringsmekanism

Om ett vanligt filsystem behöver skriva om data â Ă€ndrar den varje block dĂ€r det stĂ„r.

Filssystemet med skrivkopiering skriver en ny version av blocket och lÄser sedan upp den gamla versionen.

I abstrakt bemÀrkelse, om vi ignorerar den faktiska fysiska placeringen av blocken, förenklas vÄr "datakomets" till ett "datmask", som rör sig frÄn vÀnster till höger över kartan av tillgÀngligt utrymme.

Nu kan vi fĂ„ en bra uppfattning om hur skrivkopieringssnapshot fungerar â varje block kan tillhöra flera snapshots och kommer att sparas sĂ„ lĂ€nge alla relaterade snapshots inte har raderats.
Skrivkopieringsmekanismen (Copy on Write, CoW) Ă€r den grundlĂ€ggande basen för vad som gör ZFS till ett sĂ„ fantastiskt system. Huvudkonceptet Ă€r enkelt â om du ber ett traditionellt filsystem att Ă€ndra en fil, gör den precis vad du begĂ€rde. Om du ber ett skrivkopierande filsystem att göra samma sak, sĂ€ger det "okej" â men ljuger för dig.
IstÀllet skriver det skrivkopierande filsystemet en ny version av det förÀndrade blocket och uppdaterar sedan filens metadata för att bryta kopplingen med det gamla blocket och koppla det till det nya block som just har skrivits.
Kopplingen av det gamla blocket och bindningen av det nya sker i en operation, sĂ„ denna kan inte avbrytas â om du stĂ€nger av strömmen efter att det har skett, har du en ny version av filen, och om du stĂ€nger av strömmen tidigare, har du den gamla versionen. I vilket fall som helst kommer det inte att uppstĂ„ nĂ„gra konflikter i filsystemet.
Skrivkopiering i ZFS sker inte bara pĂ„ filsystemnivĂ„ utan ocksĂ„ pĂ„ diskhanteringsnivĂ„. Detta innebĂ€r att ZFS inte pĂ„verkas av skrivluckor () â ett fenomen dĂ€r bandet bara har skrivits delvis innan systemet kraschar, med skador pĂ„ arrayen efter omstart. HĂ€r skrivs bandet atomĂ€rt, vdev Ă€r alltid konsekvent, och .
ZIL: ZFS avsiktslogg.

ZFS-systemet hanterar synkrona skrivningar pĂ„ ett speciellt sĂ€tt â det sparar dem temporĂ€rt men omedelbart i ZIL, innan de senare skrivs permanent tillsammans med asynkrona skrivningar.

Vanligtvis lÀses inte data som skrivs till ZIL nÄgonsin igen. Men det Àr möjligt efter ett systemfel.

SLOG, eller sekundÀr LOG-enhet, Àr helt enkelt en speciell - och helst vÀldigt snabb - vdev dÀr ZIL kan lagras separat frÄn det primÀra lagringsutrymmet.

Efter ett fel ÄterstÀlls alla smutsiga data i ZIL - i det hÀr fallet ligger ZIL pÄ SLOG, sÄ de ÄterstÀlls dÀrifrÄn.
Det finns tvÄ huvudkategorier av skrivoperationer - synkrona (sync) och asynkrona (async). För de flesta arbetsbelastningar Àr den övervÀldigande majoriteten av skrivoperationer asynkrona - filsystemet tillÄter att de aggregeras och skickas i paket, vilket minskar fragmenteringen och avsevÀrt ökar bandbredden.
Synkrona skrivningar Àr en helt annan sak. NÀr en applikation begÀr en synkron skrivning, sÀger den till filsystemet: "Du behöver spara det hÀr i icke-flyktigt minne, just nu.och under tiden kan jag inte göra nÄgot mer." DÀrför mÄste synkrona skrivningar omedelbart sparas pÄ disken - och om det ökar fragmenteringen eller minskar bandbredden, dÄ fÄr det vara sÄ.
ZFS hanterar synkrona skrivningar annorlunda Àn vanliga filsystem - istÀllet för att omedelbart skriva dem till det vanliga lagringsutrymmet, sparar ZFS dem i ett speciellt lagringsomrÄde som kallas ZFS Intent Log, eller ZIL. Kniffen Àr att dessa skrivningar Àven förblir i minnet, samtidigt som de aggregeras med vanliga asynkrona skrivförfrÄgningar, för att senare skrivas till lagringsutrymmet som helt normala TXG (transaktionsgrupper, Transaction Groups).
Under normal drift skrivs ZIL till och lÀses aldrig mer. NÀr skrivningarna frÄn ZIL efter nÄgra ögonblick sparas i det primÀra lagringsutrymmet i vanliga TXG frÄn RAM, kopplas de bort frÄn ZIL. Det Àr endast dÄ nÄgot lÀses frÄn ZIL - vid import av poolen.
Om det intrÀffar ett ZFS-fel - en krasch av operativsystemet eller strömavbrott - nÀr det finns data i ZIL, kommer dessa data att lÀsas under nÀsta import av poolen (t.ex. vid omstart av den avbrutna systemet). Allt som finns i ZIL kommer att lÀsas, aggregeras i TXG-grupper, sparas i det primÀra lagringsutrymmet och dÀrefter kopplas loss frÄn ZIL under importprocessen.
En av hjÀlpklasserna i vdev kallas LOG eller SLOG, en sekundÀr enhet LOG. Dess enda uppgift Àr att tillhandahÄlla poolen med en separat och, helst, mycket snabbare enhet med hög skrivbestÀndighet för lagring av ZIL, istÀllet för att lagra ZIL pÄ huvudlagringsvdev. ZIL beter sig likadant oavsett lagringsplats, men om vdev med LOG har mycket hög skrivprestanda kommer synkrona skrivningar att ske snabbare.
Att lĂ€gga till vdev med LOG i poolen pĂ„verkar inte kan inte prestationsförbĂ€ttringen av asynkrona skrivningar â Ă€ven om du tvingar fram alla skrivningar till ZIL med zfs set sync=always, kommer de fortfarande att vara bundna till huvudlagringen i TXG pĂ„ samma sĂ€tt och i samma takt som utan logg. Den enda direkta prestandaförbĂ€ttringen Ă€r latensen av synkrona skrivningar (eftersom en högre hastighet för loggen pĂ„skyndar utförandet av operationer. sync).
Men i en miljö som redan krÀver mÄnga synkrona skrivningar kan vdev LOG indirekt pÄskynda asynkrona skrivningar och okashad lÀsning. Att avlastar ZIL-skrivningar till en separat vdev LOG innebÀr mindre konkurrens om IOPS i den primÀra lagringen, vilket pÄ vissa sÀtt ökar prestandan för alla lÀs- och skrivoperationer.
Snapshots
Skriv-kopieringsmekanismen Ă€r Ă€ven en nödvĂ€ndig grund för atomĂ€ra momentana bilder i ZFS och inkrementell asynkron replikering. I ett aktivt filsystem finns det ett trĂ€d av pekare som markerar alla skrivningar med aktuella data â nĂ€r du gör en snapshot skapar du helt enkelt en kopia av detta pekartrĂ€d.
NÀr en skrivning överskrivs i det aktiva filsystemet, skriver ZFS först den nya versionen av blocket till oanvÀndbart utrymme. DÀrefter kopplar den bort den gamla versionen av blocket frÄn det aktuella filsystemet. Men om en snapshot hÀnvisar till det gamla blocket förblir det oförÀndrat. Det gamla blocket kommer faktiskt inte att ÄterstÀllas som ledigt utrymme förrÀn alla snapshots som hÀnvisar till det blocket har raderats!
Replikation

Mitt Steam-bibliotek Ă„r 2015 tog 158 GiB och inkluderade 126 927 filer. Detta Ă€r ganska nĂ€ra den optimala situationen för rsync â ZFS-replikering över nĂ€tverket var "bara" 750% snabbare.

I samma nĂ€tverk Ă€r replikeringen av en 40-gigabyters Windows 7 virtuell maskinavbildning en helt annan historia. ZFS-replikering sker 289 gĂ„nger snabbare Ă€n rsync â eller "bara" 161 gĂ„nger snabbare, om du Ă€r tillrĂ€ckligt kunnig för att kalla rsync med nyckeln âinplace.

NĂ€r bilden av den virtuella maskinen skalas, skalas rsync-problemen med den. Storleken 1,9 TiB Ă€r inte sĂ„ stor för en modern virtuell maskinbild â men den Ă€r tillrĂ€ckligt stor för att ZFS-replikering skulle vara 1148 gĂ„nger snabbare Ă€n rsync, Ă€ven med rsync-argumentet âinplace.
SÄ snart du förstÄr hur snapshots fungerar, blir det inte svÄrt att fÄnga essensen av replikering. Eftersom en snapshot helt enkelt Àr ett trÀd av pekare till poster, innebÀr det att om vi gör zfs send en snapshot, sÄ skickar vi bÄde detta trÀd och alla relaterade poster. NÀr vi överför detta zfs send pÄ zfs receive till det destinationselement, skriver det bÄde det faktiska blockinnehÄllet och trÀdet av pekare som hÀnvisar till blocken, i mÄl datasets.
Det blir Ànnu mer intressant pÄ den andra zfs send. Nu har vi tvÄ system dÀr var och en innehÄller poolname/datasetname@1, och du tar en ny snapshot poolname/datasetname@2.DÀrför har du i kÀllpoolen datasetname@1 och datasetname@2, men i mÄlpoolen har vi tills vidare bara den första snapshoten. datasetname@1.
Eftersom vi har en gemensam snapshot mellan kĂ€llan och mĂ„let, kan vi göra datasetname@1en inkrementell övan dem. NĂ€r vi sĂ€ger till systemet zfs send zfs send -i poolname/datasetname@1 poolname/datasetname@2 , jĂ€mför det de tvĂ„ pekartrĂ€den. Alla pekare som endast existerar i, pekar uppenbarligen pĂ„ nya block â dĂ€rför behöver vi innehĂ„llet i dessa block. @2I det fjĂ€rrsystemet Ă€r hanteringen av den inkrementella
lika enkel. Först skriver vi alla nya poster som ingĂ„r i strömmen send , och sedan lĂ€gger vi till pekarna till dessa block. VoilĂ , vi har sendi det nya systemet! @2 Asynkron inkrementell replikation av ZFS Ă€r en enorm förbĂ€ttring jĂ€mfört med tidigare metoder som inte bygger pĂ„ snapshots, som rsync. I bĂ„da fallen överförs endast Ă€ndrade data â men rsync mĂ„ste först
frĂ„n disken alla data pĂ„ bĂ„da sidor för att kontrollera summan och jĂ€mföra den. Till skillnad frĂ„n detta lĂ€ser ZFS-replikering ingenting utom pekartavlor â och alla block som inte finns representerade i den gemensamma snapshoten. lĂ€sa Ń ĐŽĐžŃĐșа ĐČŃĐ” ĐŽĐ°ĐœĐœŃĐ” Ń ĐŸĐ±Đ”ĐžŃ ŃŃĐŸŃĐŸĐœ, ŃŃĐŸĐ±Ń ĐżŃĐŸĐČĐ”ŃĐžŃŃ ŃŃĐŒĐŒŃ Đž ŃŃаĐČĐœĐžŃŃ Đ”Ń. Đ ĐŸŃлОŃОД ĐŸŃ ŃŃĐŸĐłĐŸ, ŃДплОĐșаŃĐžŃ ZFS ĐœĐ” ŃŃĐžŃŃĐČĐ°Đ”Ń ĐœĐžŃĐ”ĐłĐŸ, ĐșŃĐŸĐŒĐ” ĐŽĐ”ŃĐ”ĐČŃĐ”ĐČ ŃĐșазаŃДлДĐč â Đž Đ»ŃбŃŃ Đ±Đ»ĐŸĐșĐŸĐČ, ĐșĐŸŃĐŸŃŃĐ” ĐœĐ” ĐżŃДЎŃŃаĐČĐ»Đ”ĐœŃ ĐČ ĐŸĐ±ŃĐ”ĐŒ ŃĐœĐ°ĐżŃĐŸŃĐ”.
Inbyggd komprimering
Skrivprocessens kopieringsmekanism förenklar ocksĂ„ systemet med inbyggd komprimering. I ett traditionellt filsystem Ă€r komprimering problematiskt â bĂ„de den gamla versionen och den nya versionen av Ă€ndrade data finns i samma utrymme.
Om vi ser pĂ„ ett datastycke i mitten av en fil som börjar sitt liv som en megabyte av nollor frĂ„n 0x00000000 och sĂ„ vidare â kan det enkelt komprimeras till en sektor pĂ„ disken. Men vad hĂ€nder om vi ersĂ€tter denna megabyte av nollor med en megabyte av ocompressibla data, som JPEG eller pseudorandom brus? Plötsligt kommer denna megabyte av data att behöva inte en, utan 256 sektorer pĂ„ 4 KiB, medan bara en sektor Ă€r reserverad pĂ„ disken.
ZFS har inget sĂ„dant problem, eftersom de Ă€ndrade posterna alltid skrivs till oanvĂ€nt utrymme â den ursprungliga blocket tar bara en sektor pĂ„ 4 KiB, medan den nya posten kommer att ta 256, men det Ă€r inget problem â det nyligen Ă€ndrade stycket frĂ„n "mitten" av filen skulle skrivas till oanvĂ€nt utrymme oavsett om dess storlek förĂ€ndrades eller inte, sĂ„ det Ă€r en helt normal situation för ZFS.
Inbyggd komprimering i ZFS Ă€r avstĂ€ngd som standard, och systemet erbjuder anslutbara algoritmer â för nĂ€rvarande LZ4, gzip (1-9), LZJB och ZLE.
- LZ4 â Ă€r en strömmande algoritm som erbjuder extremt snabb komprimering och dekomprimering och prestandaförbĂ€ttring för de flesta anvĂ€ndningsfall â Ă€ven pĂ„ ganska lĂ„ngsamma CPU:er.
- GZIP â en respekterad algoritm som alla anvĂ€ndare av Unix-system kĂ€nner till och Ă€lskar. Den kan implementeras med komprimeringsnivĂ„er 1-9, dĂ€r komprimeringsgraden och CPU-anvĂ€ndningen ökar ju nĂ€rmare nivĂ„ 9 man kommer. Algoritmen Ă€r bra för alla textbaserade (eller andra extremt komprimerbara) anvĂ€ndningsfall, men annars orsakar den ofta problem med CPU:en â anvĂ€nd den med försiktighet, sĂ€rskilt pĂ„ högre nivĂ„er.
- LZJB â den ursprungliga algoritmen i ZFS. Den Ă€r förĂ„ldrad och bör inte lĂ€ngre anvĂ€ndas, LZ4 övertrĂ€ffar den pĂ„ alla punkter.
- ZLE â nollnivĂ„kodning, Zero Level Encoding. Den pĂ„verkar överhuvudtaget inte normala data, men komprimerar stora sekvenser av nollor. AnvĂ€ndbar för helt okomprimerade dataset (som JPEG, MP4 eller andra redan komprimerade format), eftersom den ignorerar okomprimerade data men komprimerar oanvĂ€nt utrymme i de slutliga posterna.
Vi rekommenderar komprimering med LZ4 för nÀstan alla anvÀndningsomrÄden; prestandastraffet nÀr man stöter pÄ okomprimerade data Àr mycket litet, och ökning prestandan för typiska data Àr betydande. Kopieringen av en virtuell maskin för en ny installation av Windows-operativsystemet (nyinstallerat OS, inga data inuti Ànnu) med compression=lz4 gick 27% snabbare Àn med compression=none, i .
ARC â adaptiv ersĂ€ttningscache
ZFS Àr det enda moderna filsystem som vi kÀnner till som anvÀnder sin egen lÀsning-cachemekanism och inte förlitar sig pÄ operativsystemets sidcache för att lagra kopior av nyligen lÀsta block i RAM.
Ăven om den egna cachen har sina problem â ZFS kan inte reagera pĂ„ nya begĂ€rningar om minnesallokering lika snabbt som kĂ€rnan, sĂ„ en ny begĂ€ran malloc() om minnesfördelning kan misslyckas om den behöver RAM som för nĂ€rvarande upptas av ARC. Men det finns starka skĂ€l att anvĂ€nda den egna cachen, Ă„tminstone just nu.
Alla kÀnda moderna operativsystem, inklusive MacOS, Windows, Linux och BSD, tillÀmpar LRU (Least Recently Used) algoritm för att implementera sidcachen. Detta Àr en primitiv algoritm som flyttar det cachade blocket "upp i kön" efter varje lÀsning och fördriver block "ner i kön" vid behov för att fÄ plats för nya cachemissar (block som skulle ha lÀsts frÄn disken istÀllet för frÄn cachen).
I allmĂ€nhet fungerar algoritmen bra, men i system med stora arbetsuppsĂ€ttningar leder LRU lĂ€tt till thrashing â utdrivning av ofta behövda block för att frigöra utrymme för block som aldrig kommer att lĂ€sas igen frĂ„n cachen.
 â en betydligt mindre naiv algoritm som kan ses som en "viktad" cache. Efter varje lĂ€sning av en cachelagrad block blir den lite "tyngre" och svĂ„rare att avlĂ€gsna â och Ă€ven efter att den har avlĂ€gsnats kan blocket spĂ„ras under en viss tidsperiod. Ett block som har avlĂ€gsnats men sedan behöver lĂ€sas tillbaka till cachen kommer ocksĂ„ att bli "tyngre".
Det slutliga resultatet av allt detta Ă€r en cache med en mycket högre trĂ€ffprocent (hit ratio) â förhĂ„llandet mellan trĂ€ffar i cachen (lĂ€sningar som görs frĂ„n cachen) och missar (lĂ€sningar frĂ„n disken). Detta Ă€r en extremt viktig statistik â inte bara att sjĂ€lva trĂ€ffarna i cachen hanteras ordentligt snabbare, utan Ă€ven missarna kan hanteras snabbare, eftersom ju fler trĂ€ffar i cachen â desto fĂ€rre parallella förfrĂ„gningar till disken och mindre fördröjning för de kvarvarande missarna som mĂ„ste hanteras frĂ„n disken.
Slutsats
Efter att ha studerat den grundlĂ€ggande semantiken av ZFS â hur skrivningskopiering fungerar, samt relationerna mellan lagringspooler, virtuella enheter, block, sektorer och filer â Ă€r vi redo att diskutera den verkliga prestandan med verkliga siffror.
I nÀsta del kommer vi att titta pÄ den faktiska prestandan hos pooler med speglade vdev och RAIDz, i jÀmförelse med varandra, samt i jÀmförelse med traditionella RAID-topologier i Linux-kÀrnan som vi har utforskat. .
Först ville vi bara titta pĂ„ grunderna â ZFS-topologierna sjĂ€lva â men efter sĂ„ mycket Ă€r vi redo att diskutera mer avancerad konfigurering och justering av ZFS, inklusive anvĂ€ndningen av hjĂ€lptyper av vdev, sĂ„som L2ARC, SLOG och Special Allocation.
KĂ€lla: habr.com
