Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap

Ngayong tagsibol napag-usapan na natin ang ilang mga panimulang paksa, halimbawa, kung paano suriin ang bilis ng iyong mga drive и ano ang RAID. Sa pangalawa sa kanila, ipinangako pa namin na ipagpapatuloy ang pag-aaral ng pagganap ng iba't ibang multi-disk topologies sa ZFS. Ito ang susunod na henerasyon ng file system na ngayon ay ipinapatupad sa lahat ng dako: mula sa mansanas sa Ubuntu.

Well, ngayon ang pinakamagandang araw upang makilala ang ZFS, matanong na mga mambabasa. Alam lang na sa mapagpakumbabang opinyon ng developer ng OpenZFS na si Matt Ahrens, "ang hirap talaga."

Ngunit bago tayo makarating sa mga numero - at gagawin nila, ipinapangako ko - para sa lahat ng mga opsyon para sa isang walong disk na pagsasaayos ng ZFS, kailangan nating pag-usapan bilang Sa pangkalahatan, ang ZFS ay nag-iimbak ng data sa disk.

Zpool, vdev at device

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Kasama sa buong pool diagram na ito ang tatlong auxiliary vdev, isa sa bawat klase, at apat para sa RAIDz2

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Karaniwang walang dahilan para gumawa ng pool ng mga hindi tugmang uri at laki ng vdev - ngunit walang pumipigil sa iyong gawin ito kung gusto mo.

Upang talagang maunawaan ang ZFS file system, kailangan mong tingnang mabuti ang aktwal na istraktura nito. Una, pinag-iisa ng ZFS ang tradisyonal na dami at mga layer ng pamamahala ng file system. Pangalawa, gumagamit ito ng transactional copy-on-write na mekanismo. Ang mga tampok na ito ay nangangahulugan na ang sistema ay structurally ibang-iba mula sa conventional file system at RAID arrays. Ang unang hanay ng mga pangunahing building block na mauunawaan ay ang storage pool (zpool), virtual device (vdev) at totoong device (device).

zpool

Ang zpool storage pool ay ang pinakamataas na istraktura ng ZFS. Ang bawat pool ay naglalaman ng isa o higit pang virtual na device. Sa turn, ang bawat isa sa kanila ay naglalaman ng isa o higit pang mga tunay na device (device). Ang mga virtual pool ay mga self-contained na bloke. Ang isang pisikal na computer ay maaaring maglaman ng dalawa o higit pang magkahiwalay na pool, ngunit ang bawat isa ay ganap na independiyente sa iba. Hindi maaaring ibahagi ng mga pool ang mga virtual na device.

Ang redundancy ng ZFS ay nasa antas ng virtual na device, hindi sa antas ng pool. Walang ganap na kalabisan sa antas ng pool - kung ang anumang drive vdev o espesyal na vdev ay nawala, ang buong pool ay mawawala kasama nito.

Ang mga modernong storage pool ay makakaligtas sa pagkawala ng cache o virtual device log - bagama't maaari silang mawalan ng kaunting maruming data kung mawala ang vdev log sa panahon ng pagkawala ng kuryente o pag-crash ng system.

Mayroong isang karaniwang maling kuru-kuro na ang "mga strip ng data" ng ZFS ay nakasulat sa buong pool. Hindi ito totoo. Ang Zpool ay hindi nakakatawa sa RAID0, ito ay medyo nakakatawa JBOD na may isang kumplikadong mekanismo ng pamamahagi ng variable.

Para sa karamihan, ang mga rekord ay ipinamamahagi sa mga magagamit na virtual na aparato ayon sa magagamit na libreng espasyo, kaya sa teorya ay pupunuin silang lahat nang sabay-sabay. Isinasaalang-alang ng mas kamakailang mga bersyon ng ZFS ang kasalukuyang paggamit ng vdev (paggamit) - kung ang isang virtual na device ay mas abala kaysa sa isa pa (halimbawa, dahil sa read load), ito ay pansamantalang lalaktawan para sa pagsusulat, sa kabila ng pagkakaroon ng pinakamataas na ratio ng libreng espasyo.

Ang mekanismo ng utilization detection na binuo sa makabagong ZFS write allocation method ay maaaring mabawasan ang latency at pataasin ang throughput sa mga panahon ng hindi karaniwang mataas na load - ngunit hindi carte blanche sa hindi sinasadyang paghahalo ng mabagal na HDD at mabilis na SSD sa isang pool. Ang ganitong hindi pantay na pool ay gagana pa rin sa bilis ng pinakamabagal na aparato, iyon ay, na para bang ito ay ganap na binubuo ng mga naturang device.

vdev

Ang bawat storage pool ay binubuo ng isa o higit pang virtual na device (virtual device, vdev). Sa turn, ang bawat vdev ay naglalaman ng isa o higit pang mga tunay na device. Karamihan sa mga virtual na device ay ginagamit para sa simpleng pag-iimbak ng data, ngunit mayroong ilang mga klase ng vdev helper, kabilang ang CACHE, LOG, at SPECIAL. Ang bawat isa sa mga uri ng vdev na ito ay maaaring magkaroon ng isa sa limang topologies: iisang device (iisang device), RAIDz1, RAIDz2, RAIDz3, o mirror (mirror).

Ang RAIDz1, RAIDz2 at RAIDz3 ay mga espesyal na uri ng tinatawag ng mga lumang-timer na double (diagonal) parity RAID. Ang 1, 2 at 3 ay tumutukoy sa kung gaano karaming mga parity block ang inilalaan para sa bawat strip ng data. Sa halip na magkahiwalay na mga disk para sa parity, ang mga virtual na device ng RAIDz ay ibinabahagi ang parity na ito nang semi-pantay sa mga disk. Ang isang RAIDz array ay maaaring mawalan ng kasing dami ng mga disk dahil mayroon itong mga parity block; kung mawalan ito ng isa pa, babagsak ito at dadalhin ang storage pool kasama nito.

Sa mirror virtual device (mirror vdev), ang bawat block ay naka-store sa bawat device sa vdev. Bagama't ang mga salamin na may dalawang lapad ay ang pinakakaraniwan, ang salamin ay maaaring magkaroon ng anumang arbitrary na bilang ng mga device—sa mas malalaking pag-install, ang mga triple ay kadalasang ginagamit upang pahusayin ang pagganap ng pagbasa at pagpapahintulot sa fault. Ang isang vdev mirror ay maaaring makaligtas sa anumang pagkabigo hangga't hindi bababa sa isang device sa vdev ay nananatiling gumagana.

Ang mga solong vdev ay likas na mapanganib. Ang ganitong virtual na aparato ay hindi makakaligtas sa isang solong kabiguan - at kung ginamit bilang imbakan o isang espesyal na vdev, kung gayon ang pagkabigo nito ay hahantong sa pagkawasak ng buong pool. Maging napaka-ingat dito.

Ang mga CACHE, LOG, at SPECIAL VA ay maaaring gawin gamit ang alinman sa mga topology sa itaas - ngunit tandaan na ang pagkawala ng isang ESPESYAL VA ay nangangahulugan ng pagkawala ng pool, kaya ang isang redundant topology ay lubos na inirerekomenda.

aparato

Ito ay marahil ang pinakamadaling termino upang maunawaan sa ZFS - ito ay literal na isang block random access device. Tandaan na ang mga virtual na device ay binubuo ng mga indibidwal na device, habang ang pool ay binubuo ng mga virtual na device.

Ang mga disk - alinman sa magnetic o solid state - ay ang pinakakaraniwang block device na ginagamit bilang mga building block ng vdev. Gayunpaman, magagawa ng anumang device na may descriptor sa /dev, kaya ang buong hardware RAID array ay maaaring gamitin bilang hiwalay na mga device.

Ang isang simpleng raw file ay isa sa pinakamahalagang alternatibong block device kung saan maaaring buuin ang isang vdev. Test pool mula sa kalat-kalat na mga file ay isang napakadaling paraan upang suriin ang mga command ng pool at makita kung gaano karaming espasyo ang magagamit sa isang pool o virtual na device ng isang partikular na topology.

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Maaari kang lumikha ng isang pansubok na pool mula sa kalat-kalat na mga file sa loob lamang ng ilang segundo - ngunit huwag kalimutang tanggalin ang buong pool at ang mga bahagi nito pagkatapos

Sabihin nating gusto mong maglagay ng server sa walong disk at planong gumamit ng 10 TB disk (~9300 GiB) - ngunit hindi ka sigurado kung aling topology ang pinakaangkop sa iyong mga pangangailangan. Sa halimbawa sa itaas, bumuo kami ng isang pansubok na pool mula sa kalat-kalat na mga file sa loob ng ilang segundo - at ngayon alam namin na ang isang RAIDz2 vdev ng walong 10 TB disk ay nagbibigay ng 50 TiB ng magagamit na kapasidad.

Ang isa pang espesyal na klase ng mga device ay SPARE (spare). Ang mga hot-swap device, hindi tulad ng mga regular na device, ay nabibilang sa buong pool, at hindi sa isang virtual device. Kung nabigo ang isang vdev sa pool at nakakonekta ang isang ekstrang device sa pool at available, awtomatiko itong sasali sa apektadong vdev.

Pagkatapos kumonekta sa apektadong vdev, magsisimulang makatanggap ang ekstrang device ng mga kopya o muling pagtatayo ng data na dapat nasa nawawalang device. Sa tradisyunal na RAID ito ay tinatawag na muling pagtatayo, habang sa ZFS ito ay tinatawag na resilvering.

Mahalagang tandaan na ang mga kapalit na device ay hindi permanenteng pinapalitan ang mga nabigong device. Ito ay pansamantalang kapalit lamang upang mabawasan ang oras na kinakailangan para sa vdev na bumaba. Pagkatapos palitan ng administrator ang nabigong vdev device, ibabalik ang redundancy sa permanenteng device na iyon, at madidiskonekta ang SPARE sa vdev at babalik sa pagiging ekstra para sa buong pool.

Mga set ng data, bloke at sektor

Ang susunod na hanay ng mga bloke ng gusali na mauunawaan sa aming paglalakbay sa ZFS ay hindi gaanong tungkol sa hardware at higit pa tungkol sa kung paano inaayos at iniimbak ang mismong data. Nilalaktawan namin ang ilang mga antas dito - tulad ng metaslab - upang hindi makalat ang mga detalye habang pinapanatili ang isang pag-unawa sa pangkalahatang istraktura.

Set ng data (dataset)

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Noong una kaming gumawa ng dataset, ipinapakita nito ang lahat ng available na pool space. Pagkatapos ay itinakda namin ang quota - at baguhin ang mount point. Magic!

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Ang Zvol ay para sa karamihan ay isang dataset lamang na tinanggal ang layer ng filesystem nito, na pinapalitan namin dito ng perpektong normal na ext4 filesystem.

Ang isang ZFS dataset ay halos kapareho ng isang karaniwang naka-mount na file system. Tulad ng isang regular na file system, sa unang tingin ito ay parang "isa pang folder". Ngunit tulad ng mga regular na mountable filesystem, ang bawat ZFS dataset ay may sariling hanay ng mga pangunahing katangian.

Una sa lahat, ang isang dataset ay maaaring magkaroon ng nakatalagang quota. Kung itinakda zfs set quota=100G poolname/datasetname, pagkatapos ay hindi ka makakasulat sa naka-mount na folder /poolname/datasetname higit sa 100 GiB.

Pansinin ang presensya—at kawalan—ng mga slash sa simula ng bawat linya? Ang bawat set ng data ay may sariling lugar sa parehong hierarchy ng ZFS at sa system mount hierarchy. Walang nangungunang slash sa hierarchy ng ZFS—magsisimula ka sa pangalan ng pool at pagkatapos ay ang path mula sa isang set ng data patungo sa susunod. Halimbawa, pool/parent/child para sa isang dataset na pinangalanan child sa ilalim ng parent dataset parent sa isang pool na may malikhaing pangalan pool.

Bilang default, ang mount point ng dataset ay magiging katumbas ng pangalan nito sa hierarchy ng ZFS, na may nangungunang slash - ang pool na pinangalanan pool naka-mount bilang /pool, set ng data parent naka-mount sa /pool/parent, at ang dataset ng bata child naka-mount sa /pool/parent/child. Gayunpaman, maaaring baguhin ang mount point ng system ng data set.

Kung tutukuyin natin zfs set mountpoint=/lol pool/parent/child, pagkatapos ay ang set ng data pool/parent/child naka-mount sa system bilang /lol.

Bilang karagdagan sa mga dataset, dapat nating banggitin ang mga volume (zvols). Ang isang volume ay halos kapareho ng isang dataset, maliban na wala talaga itong file system—isa lang itong block device. Maaari kang, halimbawa, lumikha zvol Sa pangalan mypool/myzvol, pagkatapos ay i-format ito gamit ang isang ext4 file system, at pagkatapos ay i-mount ang file system na iyon - mayroon ka na ngayong ext4 file system, ngunit kasama ang lahat ng mga tampok ng seguridad ng ZFS! Ito ay maaaring mukhang kalokohan sa isang makina, ngunit mas makabuluhan bilang isang backend kapag nag-e-export ng isang iSCSI device.

Mga bloke

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Ang file ay kinakatawan ng isa o higit pang mga bloke. Ang bawat bloke ay naka-imbak sa isang virtual na aparato. Ang laki ng bloke ay karaniwang katumbas ng parameter laki ng talaan, ngunit maaaring bawasan sa 2^paglipatkung naglalaman ito ng metadata o isang maliit na file.

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Kami talaga talaga hindi nagbibiro tungkol sa malaking parusa sa pagganap kung nagtakda ka ng masyadong maliit na ashift

Sa isang ZFS pool, lahat ng data, kabilang ang metadata, ay naka-imbak sa mga bloke. Ang maximum na laki ng block para sa bawat set ng data ay tinukoy sa property recordsize (laki ng record). Maaaring baguhin ang laki ng tala, ngunit hindi nito babaguhin ang laki o lokasyon ng anumang mga bloke na naisulat na sa dataset - nakakaapekto lamang ito sa mga bagong bloke habang isinusulat ang mga ito.

Maliban kung tinukoy, ang kasalukuyang default na laki ng tala ay 128 KiB. Ito ay uri ng isang nakakalito na trade-off kung saan ang pagganap ay hindi perpekto, ngunit hindi rin ito kahila-hilakbot sa karamihan ng mga kaso. Recordsize maaaring itakda sa anumang halaga mula 4K hanggang 1M (na may mga advanced na setting recordsize maaari kang mag-install ng higit pa, ngunit ito ay bihirang isang magandang ideya).

Ang anumang bloke ay tumutukoy sa data ng isang file lamang - hindi mo maaaring i-cram ang dalawang magkaibang mga file sa isang bloke. Ang bawat file ay binubuo ng isa o higit pang mga bloke, depende sa laki. Kung ang laki ng file ay mas maliit kaysa sa laki ng tala, ito ay maiimbak sa isang mas maliit na laki ng bloke - halimbawa, ang isang bloke na may 2 KiB file ay sasakupin lamang ang isang 4 KiB na sektor sa disk.

Kung ang file ay sapat na malaki at nangangailangan ng ilang mga bloke, kung gayon ang lahat ng mga talaan na may ganitong file ay magkakaroon ng laki recordsize - kabilang ang huling entry, ang pangunahing bahagi nito ay maaaring hindi nagamit na espasyo.

walang ari-arian ang zvols recordsize — sa halip ay mayroon silang katumbas na ari-arian volblocksize.

Mga sektor

Ang huling, pinakapangunahing bloke ng gusali ay ang sektor. Ito ang pinakamaliit na pisikal na yunit na maaaring isulat o basahin mula sa pinagbabatayan na aparato. Sa loob ng ilang dekada, karamihan sa mga disk ay gumamit ng 512-byte na sektor. Kamakailan, karamihan sa mga disk ay na-configure para sa 4 na sektor ng KiB, at ang ilan - lalo na ang mga SSD - ay may 8 KiB na sektor o higit pa.

Ang ZFS ay may tampok na nagbibigay-daan sa iyong manu-manong itakda ang laki ng sektor. Ang ari-arian na ito ashift. Medyo nakakalito, ang ashift ay isang kapangyarihan ng dalawa. Halimbawa, ashift=9 nangangahulugan ng laki ng sektor na 2^9, o 512 bytes.

Ang ZFS ay nagtatanong sa operating system para sa detalyadong impormasyon tungkol sa bawat block device kapag idinagdag ito sa isang bagong vdev, at ayon sa teorya ay awtomatikong nag-i-install ng ashift nang maayos batay sa impormasyong iyon. Sa kasamaang palad, maraming mga drive ang nagsisinungaling tungkol sa laki ng kanilang sektor upang mapanatili ang pagiging tugma sa Windows XP (na hindi maunawaan ang mga drive na may iba pang laki ng sektor).

Nangangahulugan ito na ang isang ZFS administrator ay mahigpit na pinapayuhan na malaman ang aktwal na laki ng sektor ng kanilang mga device at manu-manong itinakda ashift. Kung ang ashift ay itinakda nang masyadong mababa, ang bilang ng mga read/write na operasyon ay tataas nang astronomically. Kaya, ang pagsusulat ng 512-byte na "sektor" sa isang tunay na 4 na KiB na sektor ay nangangahulugang kinakailangang isulat ang unang "sektor", pagkatapos ay basahin ang 4 na KiB na sektor, baguhin ito gamit ang pangalawang 512-byte na "sektor", isulat ito pabalik sa bago 4 KiB sektor, at iba pa. para sa bawat entry.

Sa totoong mundo, ang gayong parusa ay nakakaapekto sa mga Samsung EVO SSD, kung saan dapat itong ilapat ashift=13, ngunit ang mga SSD na ito ay nagsisinungaling tungkol sa laki ng kanilang sektor, at samakatuwid ang default ay nakatakda sa ashift=9. Kung hindi binago ng isang may karanasang administrator ng system ang setting na ito, gagana ang SSD na ito mas mabagal maginoo magnetic HDD.

Para sa paghahambing, para sa masyadong malaking sukat ashift halos walang parusa. Walang tunay na performance hit, at ang pagtaas sa hindi nagamit na espasyo ay infinitesimal (o zero kung naka-enable ang compression). Samakatuwid, lubos naming inirerekumenda na kahit ang mga drive na iyon na gumagamit ng 512-byte na sektor ay mag-install ashift=12 o kahit na ashift=13upang harapin ang hinaharap nang may kumpiyansa.

Pag-aari ashift ay nakatakda para sa bawat vdev virtual device, at hindi para sa pool, gaya ng maling iniisip ng marami - at hindi nagbabago pagkatapos ng pag-install. Kung hindi mo sinasadyang natamaan ashift kapag nagdagdag ka ng bagong vdev sa isang pool, hindi mo na mababawi ang pagdumi sa pool na iyon gamit ang isang device na mababa ang performance at kadalasan ay walang ibang pagpipilian kundi sirain ang pool at magsimulang muli. Kahit na ang pag-alis ng vdev ay hindi magliligtas sa iyo mula sa isang sirang configuration ashift!

Mekanismo ng copy-on-write

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Kung ang isang regular na file system ay kailangang muling isulat ang data, binabago nito ang bawat bloke kung saan ito matatagpuan

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Ang isang copy-on-write file system ay nagsusulat ng bagong block na bersyon at pagkatapos ay ina-unlock ang lumang bersyon

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Sa abstract, kung babalewalain natin ang aktwal na pisikal na lokasyon ng mga bloke, ang ating "data comet" ay pinasimple sa isang "data worm" na gumagalaw mula kaliwa pakanan sa mapa ng available na espasyo

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Ngayon ay makakakuha tayo ng magandang ideya kung paano gumagana ang copy-on-write na mga snapshot - ang bawat bloke ay maaaring kabilang sa maraming snapshot, at magpapatuloy hanggang sa masira ang lahat ng nauugnay na snapshot.

Ang mekanismo ng Copy on Write (CoW) ay ang pangunahing batayan kung bakit ang ZFS ay isang kamangha-manghang sistema. Ang pangunahing konsepto ay simple - kung hihilingin mo sa isang tradisyunal na file system na baguhin ang isang file, gagawin nito ang eksaktong hiniling mo. Kung hihilingin mo ang isang copy-on-write file system na gawin ang parehong, ito ay magsasabi ng "ok" ngunit nagsisinungaling sa iyo.

Sa halip, ang isang copy-on-write na file system ay nagsusulat ng bagong bersyon ng binagong bloke at pagkatapos ay ina-update ang metadata ng file upang i-unlink ang lumang bloke at iugnay ang bagong bloke na kasulatan mo lang dito.

Ang pagtanggal sa lumang bloke at pag-link ng bago ay ginagawa sa isang operasyon, kaya hindi ito maaantala - kung i-power down mo pagkatapos mangyari ito, mayroon kang bagong bersyon ng file, at kung maaga kang i-power down, nasa iyo ang lumang bersyon . Sa anumang kaso, walang mga salungatan sa file system.

Ang copy-on-write sa ZFS ay nangyayari hindi lamang sa antas ng file system, kundi pati na rin sa antas ng pamamahala ng disk. Nangangahulugan ito na ang ZFS ay hindi apektado ng white space (isang butas sa RAID) - isang kababalaghan kung kailan nagkaroon ng oras ang strip na bahagyang mag-record bago mag-crash ang system, na may pinsala sa array pagkatapos ng reboot. Dito ang guhit ay nakasulat nang atomically, ang vdev ay palaging sequential, at Si Bob ang tiyuhin mo.

ZIL: ZFS intent log

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Tinatrato ng sistema ng ZFS ang mga kasabay na pagsusulat sa isang espesyal na paraan - ito ay pansamantalang ngunit agad na iniimbak ang mga ito sa ZIL bago isulat ang mga ito nang permanente sa ibang pagkakataon kasama ng mga asynchronous na pagsusulat.

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Karaniwan, ang data na isinulat sa ZIL ay hindi na muling binabasa. Ngunit ito ay posible pagkatapos ng pagkabigo ng system

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Ang SLOG, o pangalawang LOG device, ay isang espesyal lamang - at mas mainam na napakabilis - vdev kung saan maaaring iimbak ang ZIL nang hiwalay sa pangunahing imbakan

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Pagkatapos ng pag-crash, ang lahat ng maruming data sa ZIL ay nire-replay - sa kasong ito, ang ZIL ay nasa SLOG, kaya ito ay nire-replay mula doon

Mayroong dalawang pangunahing kategorya ng mga pagpapatakbo ng pagsulat - kasabay (sync) at asynchronous (async). Para sa karamihan ng mga workload, ang karamihan sa mga pagsusulat ay asynchronous - pinahihintulutan ng file system ang mga ito na pagsama-samahin at ibigay sa mga batch, binabawasan ang pagkapira-piraso at lubos na pagtaas ng throughput.

Ang mga kasabay na pag-record ay isang ganap na naiibang bagay. Kapag humiling ang isang application ng sabaysabay na pagsulat, sasabihin nito sa file system: "Kailangan mong i-commit ito sa non-volatile memory ngayonhanggang doon, wala na akong magagawa." Samakatuwid, ang mga sabay-sabay na pagsusulat ay dapat na italaga kaagad sa disk—at kung iyon ay nagpapataas ng fragmentation o nagpapababa ng throughput, kung gayon ay ganoon din.

Pinangangasiwaan ng ZFS ang magkasabay na pagsusulat nang iba kaysa sa mga regular na file system—sa halip na agad na ilagay ang mga ito sa regular na storage, ilalagay sila ng ZFS sa isang espesyal na lugar ng imbakan na tinatawag na ZFS Intent Log, o ZIL. Ang lansihin ay ang mga talaan na ito rin nananatili sa memorya, na pinagsama-sama kasama ng mga normal na asynchronous na kahilingan sa pagsulat, upang i-flush sa ibang pagkakataon sa storage bilang ganap na normal na mga TXG (Mga Pangkat ng Transaksyon).

Sa normal na operasyon, ang ZIL ay isinusulat at hindi na muling binabasa. Kapag, pagkatapos ng ilang sandali, ang mga talaan mula sa ZIL ay nakatuon sa pangunahing imbakan sa mga regular na TXG mula sa RAM, sila ay nahiwalay sa ZIL. Ang tanging oras na may binabasa mula sa ZIL ay kapag nag-import ng pool.

Kung nabigo ang ZFS - isang pag-crash ng operating system o pagkawala ng kuryente - habang mayroong data sa ZIL, babasahin ang data na iyon sa susunod na pag-import ng pool (halimbawa, kapag na-restart ang emergency system). Ang anumang bagay sa ZIL ay babasahin, ipapangkat sa mga TXG, nakatuon sa pangunahing storage, at pagkatapos ay aalisin sa ZIL sa panahon ng proseso ng pag-import.

Ang isa sa mga klase ng vdev helper ay tinatawag na LOG o SLOG, ang pangalawang aparato ng LOG. Ito ay may isang layunin - upang mabigyan ang pool ng isang hiwalay, at mas mabuti na mas mabilis, napaka-write-resistant vdev upang iimbak ang ZIL, sa halip na iimbak ang ZIL sa pangunahing vdev store. Ang ZIL mismo ay kumikilos sa parehong lugar kahit saan ito naka-imbak, ngunit kung ang LOG vdev ay may napakataas na pagganap ng pagsulat, ang mga kasabay na pagsusulat ay magiging mas mabilis.

Ang pagdaragdag ng isang vdev na may LOG sa pool ay hindi gumagana hindi pwede pagbutihin ang asynchronous na pagganap ng pagsulat - kahit na pilitin mo ang lahat ng pagsusulat sa ZIL zfs set sync=always, mali-link pa rin sila sa pangunahing imbakan sa TXG sa parehong paraan at sa parehong bilis tulad ng walang log. Ang tanging direktang pagpapabuti ng pagganap ay ang latency ng mga sabaysabay na pagsusulat (dahil ang mas mabilis na log ay nagpapabilis ng mga operasyon). sync).

Gayunpaman, sa isang kapaligiran na nangangailangan na ng maraming magkakasabay na pagsusulat, ang vdev LOG ay maaaring hindi direktang mapabilis ang mga asynchronous na pagsusulat at hindi naka-cach na pagbabasa. Ang pag-offload ng mga entry sa ZIL sa isang hiwalay na vdev LOG ay nangangahulugan ng mas kaunting pagtatalo para sa IOPS sa pangunahing storage, na nagpapabuti sa pagganap ng lahat ng pagbabasa at pagsusulat sa ilang lawak.

Mga snapshot

Ang mekanismo ng copy-on-write ay isa ring kinakailangang pundasyon para sa ZFS atomic snapshot at incremental asynchronous replication. Ang aktibong file system ay may pointer tree na nagmamarka sa lahat ng record gamit ang kasalukuyang data - kapag kumuha ka ng snapshot, gagawa ka lang ng kopya ng pointer tree na ito.

Kapag na-overwrite ang isang tala sa aktibong file system, isusulat muna ng ZFS ang bagong bersyon ng block sa hindi nagamit na espasyo. Pagkatapos ay tinanggal nito ang lumang bersyon ng block mula sa kasalukuyang file system. Ngunit kung ang ilang snapshot ay tumutukoy sa lumang bloke, nananatili pa rin itong hindi nagbabago. Ang lumang bloke ay hindi aktwal na maibabalik bilang libreng espasyo hanggang sa masira ang lahat ng mga snapshot na tumutukoy sa bloke na ito!

Pagtitiklop

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Ang aking Steam library noong 2015 ay 158 GiB at may kasamang 126 file. Ito ay medyo malapit sa pinakamainam na sitwasyon para sa rsync - ZFS replication sa network ay "lamang" 927% mas mabilis.

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Sa parehong network, ang pagkopya ng isang solong 40GB Windows 7 virtual machine image file ay isang ganap na naiibang kuwento. Ang pagtitiklop ng ZFS ay 289 beses na mas mabilis kaysa sa rsync—o "lamang" na 161 beses na mas mabilis kung sapat na ang iyong kaalaman upang tawagan ang rsync gamit ang --inplace switch.

Mga Pangunahing Kaalaman sa ZFS: Imbakan at Pagganap
Kapag na-scale ang isang VM image, nag-isyu ang rsync ng scale dito. Ang 1,9 TiB ay hindi ganoon kalaki para sa isang modernong imahe ng VM - ngunit ito ay sapat na malaki na ang pagtitiklop ng ZFS ay 1148 beses na mas mabilis kaysa sa rsync, kahit na sa rsync's --inplace na argumento

Kapag naunawaan mo na kung paano gumagana ang mga snapshot, dapat na madaling maunawaan ang kakanyahan ng pagtitiklop. Dahil ang isang snapshot ay isang puno lamang ng mga pointer sa mga tala, ito ay sumusunod na kung gagawin natin zfs send snapshot, pagkatapos ay ipinapadala namin ang punong ito at ang lahat ng mga talaang nauugnay dito. Kapag nalampasan natin ito zfs send в zfs receive sa target, isinusulat nito ang parehong mga aktwal na nilalaman ng bloke at ang puno ng mga pointer na tumutukoy sa mga bloke sa target na dataset.

Ang mga bagay ay nagiging mas kawili-wili sa pangalawa zfs send. Mayroon na tayong dalawang sistema, bawat isa ay naglalaman ng poolname/datasetname@1, at kumuha ka ng bagong snapshot poolname/datasetname@2. Samakatuwid, sa orihinal na pool na mayroon ka datasetname@1 и datasetname@2, at sa target na pool hanggang ngayon ang unang snapshot lang datasetname@1.

Dahil mayroon kaming isang karaniwang snapshot sa pagitan ng pinagmulan at ang target datasetname@1, kaya natin to incremental zfs send sa ibabaw nito. Kapag sinabi natin sa sistema zfs send -i poolname/datasetname@1 poolname/datasetname@2, inihahambing nito ang dalawang puno ng pointer. Anumang mga pointer na umiiral lamang sa @2, malinaw na tumutukoy sa mga bagong bloke - kaya kakailanganin namin ang mga nilalaman ng mga bloke na iyon.

Sa isang malayuang sistema, ang pagproseso ng incremental send kasing simple lang. Una naming isinusulat ang lahat ng mga bagong entry na kasama sa stream send, at pagkatapos ay magdagdag ng mga pointer sa mga bloke na ito. Voila, meron kami @2 sa bagong sistema!

Ang ZFS asynchronous incremental replication ay isang malaking pagpapabuti sa mga naunang non-snapshot based na pamamaraan tulad ng rsync. Sa parehong mga kaso, ang nabagong data lamang ang inililipat - ngunit dapat muna ang rsync basahin mula sa disk ang lahat ng data sa magkabilang panig upang suriin ang kabuuan at ihambing ito. Sa kabaligtaran, ang ZFS replication ay hindi nagbabasa ng anuman maliban sa mga pointer tree—at anumang mga bloke na hindi kinakatawan sa pangkalahatang snapshot.

Built-in na compression

Pinapasimple din ng mekanismong copy-on-write ang inline compression system. Sa isang tradisyunal na file system, ang compression ay may problema - parehong ang lumang bersyon at ang bagong bersyon ng binagong data ay naninirahan sa parehong espasyo.

Kung isasaalang-alang namin ang isang piraso ng data sa gitna ng isang file na nagsisimula sa buhay bilang isang megabyte ng mga zero mula sa 0x00000000 at iba pa, napakadaling i-compress ito sa isang sektor sa disk. Ngunit ano ang mangyayari kung papalitan natin ang megabyte ng mga zero na iyon ng isang megabyte ng hindi mapipigil na data tulad ng JPEG o pseudo-random na ingay? Sa hindi inaasahan, ang megabyte ng data na ito ay mangangailangan ng hindi isa, ngunit 256 4 KiB sektor, at sa lugar na ito sa disk ay isang sektor lamang ang nakalaan.

Ang ZFS ay walang problemang ito, dahil ang mga binagong rekord ay palaging isinusulat sa hindi nagamit na espasyo - ang orihinal na bloke ay sumasakop lamang sa isang 4 na sektor ng KiB, at ang bagong rekord ay sasakupin ang 256, ngunit hindi ito isang problema - isang kamakailang binagong fragment mula sa " gitna" ng file ay isusulat sa hindi nagamit na espasyo hindi alintana kung ang laki nito ay nagbago o hindi, kaya para sa ZFS ito ay medyo isang regular na sitwasyon.

Naka-disable ang native na ZFS compression bilang default, at nag-aalok ang system ng mga pluggable na algorithm—kasalukuyang LZ4, gzip (1-9), LZJB, at ZLE.

  • LZ4 ay isang streaming algorithm na nag-aalok ng napakabilis na compression at decompression at mga benepisyo sa pagganap para sa karamihan ng mga kaso ng paggamit - kahit na sa medyo mabagal na mga CPU.
  • GZIP ay isang kagalang-galang na algorithm na alam at minamahal ng lahat ng user ng Unix. Maaari itong ipatupad sa mga antas ng compression 1-9, na may ratio ng compression at pagtaas ng paggamit ng CPU habang lumalapit ito sa antas 9. Ang algorithm ay angkop na angkop para sa lahat ng text (o iba pang napaka-compressible) na mga kaso ng paggamit, ngunit kung hindi man ay kadalasang nagiging sanhi ng mga isyu sa CPU − gamitin ito nang may pag-iingat, lalo na sa mas mataas na antas.
  • LZJB ay ang orihinal na algorithm sa ZFS. Ito ay hindi na ginagamit at hindi na dapat gamitin, ang LZ4 ay nalampasan ito sa lahat ng paraan.
  • ZLE - zero level encoding, Zero Level Encoding. Hindi nito hinahawakan ang normal na data, ngunit pini-compress ang malalaking sequence ng mga zero. Kapaki-pakinabang para sa ganap na hindi ma-compress na mga dataset (gaya ng JPEG, MP4, o iba pang naka-compress na na mga format) dahil hindi nito pinapansin ang hindi ma-compress na data ngunit pini-compress ang hindi nagamit na espasyo sa mga resultang record.

Inirerekomenda namin ang LZ4 compression para sa halos lahat ng mga kaso ng paggamit; ang parusa sa pagganap kapag nakatagpo ng hindi mapipigil na data ay napakaliit, at paglaki ang pagganap para sa karaniwang data ay makabuluhan. Pagkopya ng imahe ng virtual machine para sa isang bagong pag-install ng operating system ng Windows (bagong naka-install na OS, wala pang data sa loob) gamit ang compression=lz4 pumasa ng 27% na mas mabilis kaysa sa compression=nonesa pagsusulit na ito noong 2015.

ARC - adaptive replacement cache

Ang ZFS ay ang tanging modernong file system na alam namin na gumagamit ng sarili nitong read caching na mekanismo, sa halip na umasa sa page cache ng operating system upang mag-imbak ng mga kopya ng kamakailang nabasang mga bloke sa RAM.

Bagama't ang katutubong cache ay walang mga problema nito - hindi maaaring tumugon ang ZFS sa mga bagong kahilingan sa paglalaan ng memorya nang kasing bilis ng kernel, kaya ang bagong hamon malloc() sa memory allocation ay maaaring mabigo kung kailangan nito ang RAM na kasalukuyang inookupahan ng ARC. Ngunit may magagandang dahilan para gamitin ang iyong sariling cache, kahit sa ngayon.

Ang lahat ng kilalang modernong operating system, kabilang ang MacOS, Windows, Linux at BSD, ay gumagamit ng LRU (Least Recently Used) algorithm upang ipatupad ang page cache. Ito ay isang primitive na algorithm na nagtutulak sa naka-cache na block na "up the queue" pagkatapos ng bawat pagbasa, at itinutulak ang mga block na "down the queue" kung kinakailangan upang magdagdag ng mga bagong cache misses (mga block na dapat sana ay nabasa mula sa disk, hindi mula sa cache) pataas.

Karaniwang gumagana nang maayos ang algorithm, ngunit sa mga system na may malalaking gumaganang set ng data, madaling humahantong ang LRU sa pag-thrashing—pag-alis ng mga madalas na kailangan na bloke upang bigyan ng puwang ang mga bloke na hindi na muling mababasa mula sa cache.

ARC ay isang hindi gaanong walang muwang na algorithm na maaaring ituring na isang "timbang" na cache. Sa tuwing binabasa ang isang naka-cache na bloke, medyo nagiging "mas mabigat" ito at nagiging mas mahirap paalisin - at kahit na matapos mapaalis ang bloke sinusubaybayan sa loob ng isang tiyak na tagal ng panahon. Ang isang bloke na pinaalis ngunit pagkatapos ay kailangang basahin muli sa cache ay magiging "mas mabigat".

Ang huling resulta ng lahat ng ito ay isang cache na may mas mataas na hit ratio, ang ratio sa pagitan ng mga hit ng cache (mga pagbabasa na ginawa mula sa cache) at mga miss na cache (mga nabasa mula sa disk). Ito ay isang napakahalagang istatistika - hindi lamang ang mga cache hit mismo ay naghahatid ng mga order ng magnitude na mas mabilis, ang cache misses ay maaari ding ihatid nang mas mabilis, dahil ang mas maraming cache hit, mas kaunting mga sabay-sabay na kahilingan sa disk at mas mababa ang latency para sa mga natitirang miss na dapat ihain gamit ang disk.

Konklusyon

Pagkatapos matutunan ang mga pangunahing semantika ng ZFS - kung paano gumagana ang copy-on-write, gayundin ang mga ugnayan sa pagitan ng mga storage pool, virtual na device, block, sektor, at file - handa kaming talakayin ang pagganap sa totoong mundo gamit ang mga totoong numero.

Sa susunod na bahagi, titingnan natin ang aktwal na pagganap ng mga naka-mirror na vdev at RAIDz pool, kumpara sa isa't isa, at kumpara din sa tradisyonal na Linux kernel RAID topologies na sinuri namin mas maaga.

Noong una, nais naming saklawin lamang ang mga pangunahing kaalaman - ang mga topolohiya ng ZFS mismo - ngunit pagkatapos tulad ng isang maghanda tayo na pag-usapan ang tungkol sa mas advanced na pag-setup at pag-tune ng ZFS, kasama ang paggamit ng mga auxiliary na uri ng vdev tulad ng L2ARC, SLOG at Special Allocation.

Pinagmulan: www.habr.com

Magdagdag ng komento