Panyimpenan Data Awét sareng API File Linux

Nalika nalungtik kelestarian neundeun data dina sistem awan, kuring mutuskeun pikeun nguji diri pikeun mastikeun yén kuring ngartos hal-hal dasar. abdi dimimitian ku maca spésifikasi NVMe Pikeun ngartos naon anu ngajamin ngeunaan neundeun data anu sustainable (nyaéta, ngajamin yén data bakal sayogi saatos gagal sistem) masihan kami disk NMVe. Kuring nyieun kacindekan utama di handap ieu: data kudu dianggap ruksak ti momen paréntah pikeun nulis data dibikeun nepi ka momen eta ditulis ka médium gudang. Sanajan kitu, paling program rada happily ngagunakeun panggero sistem pikeun ngarekam data.

Dina tulisan ieu, kuring ngajalajah mékanisme panyimpen anu terus-terusan anu disayogikeun ku API file Linux. Sigana mah sadayana kedah saderhana di dieu: programna nyauran paréntah write(), sarta sanggeus paréntah ieu réngsé, data bakal aman disimpen kana disk. Tapi write() ngan nyalin data aplikasi kana cache kernel lokasina di RAM. Dina raraga maksa sistem nulis data kana disk, Anjeun kudu make sababaraha mékanisme tambahan.

Panyimpenan Data Awét sareng API File Linux

Gemblengna, bahan ieu mangrupikeun kumpulan catetan anu aya hubunganana sareng naon anu kuring diajar ngeunaan topik anu dipikaresep ku kuring. Upami urang ngobrol sakedap pisan ngeunaan hal anu paling penting, tétéla yén pikeun ngatur panyimpenan data sustainable anjeun kedah nganggo paréntah. fdatasync() atanapi muka file nganggo bandéra O_DSYNC. Upami anjeun resep diajar langkung seueur ngeunaan naon anu lumangsung kana data dina jalan tina kode ka disk, tingali ieu artikel.

Fitur pamakéan nulis () fungsi

Telepon sistem write() ditetepkeun dina standar IEEE POSIX salaku usaha nulis data ka descriptor file. Sanggeus réngsé suksés write() Operasi maca data kudu balik persis bait nu saméméhna ditulis, ngalakukeun ieu sanajan data diaksés tina prosés séjén atawa threads (di dieu bagian relevan tina standar POSIX). Ieu téh, dina bagian kumaha threads berinteraksi sareng operasi file normal, aya catetan nu nyebutkeun yen lamun dua threads unggal nelepon fungsi ieu, lajeng unggal panggero kudu ningali boh sakabéh konsékuansi ditunjuk tina panggero séjén, atawa euweuh pisan. balukarna. Ieu ngakibatkeun kacindekan yén sakabéh file I / O operasi kudu nahan konci dina sumberdaya aranjeunna beroperasi dina.

Ieu ngandung harti yén operasi write() éta atom? Ti sudut pandang teknis, enya. Operasi maca data kedah ngabalikeun sadayana atanapi henteu naon anu ditulis write(). Tapi operasi write(), nurutkeun standar, teu merta kudu mungkas ku nulis handap sagalana nu eta dipenta pikeun nulis handap. Manehna diidinan nulis ukur bagian tina data. Contona, urang bisa boga dua threads unggal appending 1024 bait ka file digambarkeun ku deskriptor file sarua. Tina sudut pandang standar, hasil anu tiasa ditampi nalika unggal operasi nyerat ngan ukur tiasa nambihan hiji bait kana file. Operasi ieu bakal tetep atom, tapi sanggeus aranjeunna réngsé, data maranéhna nulis kana file bakal dicampur. di dieu diskusi pisan metot ngeunaan topik ieu dina tumpukan mudal.

fsync () jeung fdatasync () fungsi

Cara panggampangna pikeun siram data kana disk nyaéta nyauran fungsina fsync(). Pungsi ieu miwarang sistem operasi pikeun mindahkeun sakabéh blok dirobah tina cache ka disk. Ieu kalebet sadaya metadata file (waktos aksés, waktos modifikasi file, sareng saterasna). Kuring yakin yén metadata ieu jarang diperlukeun, jadi lamun nyaho yén éta téh teu penting pikeun anjeun, anjeun tiasa nganggo fungsi fdatasync(). The Tulung on fdatasync() Disebutkeun yén salami operasi fungsi ieu, jumlah metadata sapertos kitu disimpen kana disk anu "diperlukeun pikeun palaksanaan anu leres tina operasi maca data di handap ieu." Sarta ieu kahayang paling aplikasi paduli ngeunaan.

Hiji masalah anu tiasa timbul di dieu nyaéta mékanisme ieu henteu ngajamin yén file bakal tiasa dipanggihan saatos kamungkinan gagal. Khususna, nalika nyiptakeun file énggal, anjeun kedah nelepon fsync() pikeun diréktori anu ngandung éta. Upami teu kitu, saatos gagal, sigana yén file ieu henteu aya. Alesan keur ieu di UNIX, alatan pamakéan Tumbu teuas, file bisa aya dina sababaraha directories. Ku alatan éta, nalika nelepon fsync() Teu aya jalan pikeun file pikeun terang data diréktori mana anu ogé kedah disiram kana disk (di dieu Anjeun tiasa maca langkung seueur ngeunaan ieu). Sigana mah sistem file ext4 sanggup автоматически pamakean fsync() ka diréktori anu ngandung file-file anu saluyu, tapi ieu tiasa waé henteu sapertos sistem file anu sanés.

Mékanisme ieu tiasa dilaksanakeun sacara béda dina sistem file anu béda. Kuring dipaké blktrace pikeun diajar ngeunaan operasi disk naon anu dianggo dina sistem file ext4 sareng XFS. Duanana ngaluarkeun paréntah nulis biasa ka disk boh eusi file jeung jurnal sistem file, siram cache, sarta kaluar ku ngajalankeun FUA (Paksa Unit Aksés, nulis data langsung ka disk, bypassing cache) nulis ka jurnal. Éta meureun ngalakukeun ieu guna mastikeun yén urus geus lumangsung. Dina drive anu henteu ngadukung FUA, ieu nyababkeun dua siram cache. percobaan kuring némbongkeun éta fdatasync() rada gancang fsync(). Utiliti blktrace nunjukkeun yén fdatasync() biasana nyerat kirang data kana disk (dina ext4 fsync() nyeratna 20 KiB, jeung fdatasync() - 16 KiB). Ogé, kuring manggihan yén XFS rada gancang ti ext4. Sareng di dieu kalayan bantosan blktrace junun manggihan éta fdatasync() flushes kirang data kana disk (4 KiB di XFS).

Kaayaan ambigu anu timbul nalika nganggo fsync ()

Abdi tiasa mikir ngeunaan tilu kaayaan ambigu ngeunaan fsync()anu kuring karandapan dina prakna.

Kasus sapertos anu munggaran lumangsung dina 2008. Teras antarmuka Firefox 3 beku upami sajumlah ageung file ditulis kana disk. Masalahna éta palaksanaan panganteur dipaké database SQLite pikeun nyimpen informasi ngeunaan kaayaan na. Sanggeus unggal parobahan anu lumangsung dina panganteur, fungsi ieu disebut fsync(), anu masihan jaminan anu saé pikeun neundeun data anu stabil. Dina sistem file ext3 lajeng dipaké, fungsi fsync() miceun sadaya halaman "kotor" dina sistem kana disk, sareng sanés ngan ukur anu aya hubunganana sareng file anu aya. Ieu ngandung harti yén ngaklik hiji tombol dina Firefox bisa memicu megabytes data ditulis kana disk magnét, nu bisa nyandak sababaraha detik. Solusi pikeun masalah, sajauh I ngartos ti eta Materi nya éta pikeun nransferkeun pagawéan sareng pangkalan data kana tugas tukang anu teu sinkron. Ieu ngandung harti yén Firefox saacanna ngalaksanakeun sarat panyimpen anu langkung ketat tibatan anu leres-leres diperyogikeun, sareng fitur-fitur sistem file ext3 ngan ukur nyababkeun masalah ieu.

Masalah kadua lumangsung dina 2009. Lajeng, sanggeus kacilakaan sistem, pamaké tina sistem file ext4 anyar anu Nyanghareupan kanyataan yén loba file anyar dijieun boga panjang nol, tapi ieu teu lumangsung kalawan sistem file ext3 heubeul. Dina paragraf saméméhna, abdi ngobrol ngeunaan kumaha ext3 flushed teuing data kana disk, nu kalem hal handap pisan. fsync(). Pikeun ningkatkeun kaayaan, dina ext4 ngan ukur halaman kotor anu relevan pikeun file tinangtu anu disiram kana disk. Sareng data tina file anu sanés tetep dina mémori langkung lami tibatan ext3. Ieu dilakukeun pikeun ningkatkeun kinerja (sacara standar, data tetep dina kaayaan ieu salami 30 detik, anjeun tiasa ngonpigurasikeun ieu nganggo dirty_expire_centisecs; di dieu Anjeun tiasa mendakan bahan tambahan ngeunaan ieu). Ieu ngandung harti yén jumlah badag data bisa irretrievably leungit sanggeus gagal. Solusi pikeun masalah ieu nyaéta ngagunakeun fsync() dina aplikasi anu kedah mastikeun panyimpen data anu stabil sareng ngajagi aranjeunna sabisa-bisa tina akibat tina gagal. Fungsi fsync() dianggo langkung éfisién nalika nganggo ext4 tibatan nalika nganggo ext3. Karugian tina pendekatan ieu nyaéta panggunaanana, sapertos sateuacana, ngalambatkeun palaksanaan sababaraha operasi, sapertos masang program. Tempo rinci ngeunaan ieu di dieu и di dieu.

Masalah katilu ngeunaan fsync(), asalna dina 2018. Lajeng, dina kerangka proyék PostgreSQL, kapanggih yén lamun fungsi fsync() encounters kasalahan, eta nandaan "kotor" kaca salaku "bersih". Hasilna, panggero handap fsync() Aranjeunna henteu ngalakukeun nanaon sareng halaman sapertos kitu. Kusabab ieu, kaca dirobah disimpen dina mémori jeung teu kungsi ditulis kana disk. Ieu musibah nyata, saprak aplikasi bakal mikir yén sababaraha data ditulis kana disk, tapi dina kanyataanana moal. Gagal sapertos kitu fsync() jarang, aplikasi dina kaayaan sapertos tiasa ngalakukeun ampir nanaon pikeun merangan masalah. Poé ieu, nalika ieu kajantenan, PostgreSQL sareng aplikasi anu sanés ngadat. Ieu téh, dina bahan "Naha Aplikasi Bisa Pulih tina Gagal fsync?", Masalah ieu ditalungtik sacara rinci. Ayeuna solusi anu pangsaéna pikeun masalah ieu nyaéta ngagunakeun Direct I / O kalayan bandéra O_SYNC atawa ku bandéra O_DSYNC. Kalawan pendekatan ieu, sistem bakal ngalaporkeun kasalahan anu bisa lumangsung salila operasi nulis husus, tapi pendekatan ieu merlukeun aplikasi pikeun ngatur buffers sorangan. Baca leuwih seueur tentang ieu di dieu и di dieu.

Ngabuka file nganggo bandéra O_SYNC sareng O_DSYNC

Hayu urang balik deui ka diskusi ngeunaan mékanisme Linux anu nyayogikeun panyimpen data anu stabil. Nyaéta, urang ngobrol ngeunaan ngagunakeun bandéra O_SYNC atawa bandéra O_DSYNC nalika muka file nganggo panggero sistem muka(). Kalawan pendekatan ieu, unggal operasi nulis data dipigawé saolah-olah sanggeus unggal paréntah write() sistem dibéré paréntah sasuai fsync() и fdatasync(). The spésifikasi POSIX ieu disebut "Disingkronkeun I / O File Integritas Parantosan" jeung "Data Integritas Parantosan". Kauntungan utama tina pendekatan ieu nyaéta pikeun mastikeun integritas data, anjeun ngan ukur kedah nelepon hiji sistem, tinimbang dua (contona - write() и fdatasync()). Karugian utama pendekatan ieu nyaéta yén sadaya tulisan nganggo deskriptor file anu cocog bakal disingkronkeun, anu tiasa ngabatesan kamampuan pikeun nyusun kode aplikasi.

Ngagunakeun Direct I / O jeung bandéra O_DIRECT

Telepon sistem open() ngarojong bandéra O_DIRECT, nu dirancang pikeun bypass cache sistem operasi pikeun ngalakukeun operasi I / O ku interacting langsung jeung disk. Ieu, dina seueur kasus, hartosna nyerat paréntah anu dikaluarkeun ku program bakal langsung ditarjamahkeun kana paréntah anu ditujukeun pikeun damel sareng disk. Tapi, sacara umum, mékanisme ieu sanés gaganti pikeun fungsi fsync() atawa fdatasync(). Kanyataan yén disk sorangan tiasa nunda atawa cache paréntah nulis data pakait. Sareng, anu langkung parah, dina sababaraha kasus khusus, operasi I / O dilakukeun nalika nganggo bandéra O_DIRECT, siaran kana operasi buffered tradisional. Cara panggampangna pikeun ngabéréskeun masalah ieu nyaéta ngagunakeun bandéra pikeun muka file O_DSYNC, nu hartina unggal operasi nulis bakal dituturkeun ku panggero fdatasync().

Tétéla yén sistem file XFS nembe ditambahkeun "jalur gancang" pikeun O_DIRECT|O_DSYNC-ngarékam data. Lamun blok a ditulis ulang ngagunakeun O_DIRECT|O_DSYNC, lajeng XFS, tinimbang flushing cache, bakal ngajalankeun paréntah nulis FUA lamun alat ngarojong eta. Kuring diverifikasi ieu ku ngagunakeun utiliti blktrace dina sistem Linux 5.4/Ubuntu 20.04. Pendekatan ieu kedah langkung épisién, sabab nalika dianggo, jumlah minimal data ditulis kana disk sareng hiji operasi dianggo, tibatan dua (nulis sareng nyiram cache). Kuring manggihan tumbu ka tambalan 2018 kernel, nu implements mékanisme ieu. Aya sababaraha sawala aya ngeunaan nerapkeun optimasi ieu sistem file séjén, tapi sajauh I terang, XFS hijina sistem file nu ngarojong ieu jadi jauh.

sync_file_range () fungsi

Linux gaduh panggero sistem sync_file_range(), nu ngidinan Anjeun pikeun siram ngan bagian tina file kana disk, tinimbang sakabéh file. Telepon ieu ngamimitian siram data asinkron sareng henteu ngantosan dugi ka réngsé. Tapi dina sertipikat sync_file_range() tim ieu ceuk "bahya pisan". Henteu disarankeun pikeun ngagunakeunana. Fitur sareng bahaya sync_file_range() kacida alusna digambarkeun dina ieu bahan. Husus, panggero ieu sigana ngagunakeun RocksDB pikeun ngadalikeun nalika kernel flushes data kotor kana disk. Tapi dina waktos anu sareng, pikeun mastikeun panyimpen data anu stabil, éta ogé dianggo fdatasync(). The kode RocksDB gaduh sababaraha koméntar anu pikaresepeun dina topik ieu. Contona, nembongan yen nelepon sync_file_range() Lamun maké ZFS, teu siram data kana disk. Pangalaman nyarios yén kode anu jarang dianggo sigana ngandung bug. Ku alatan éta, kuring bakal mamatahan ngalawan ngagunakeun panggero sistem ieu iwal mutlak diperlukeun.

Telepon sistem anu ngabantosan mastikeun kegigihan data

Kuring geus datang ka kacindekan yen aya tilu pendekatan nu bisa dipaké pikeun ngalakukeun I / O operasi nu mastikeun kegigihan data. Éta kabéh merlukeun panggero fungsi fsync() pikeun diréktori tempat file dijieun. Ieu mangrupikeun pendekatan:

  1. Nelepon hiji fungsi fdatasync() atawa fsync() sanggeus fungsi write() (Éta hadé ngagunakeun fdatasync()).
  2. Gawe sareng deskriptor file dibuka kalayan bandéra O_DSYNC atawa O_SYNC (hadé - kalawan bandéra a O_DSYNC).
  3. Ngagunakeun paréntah pwritev2() kalawan bandéra RWF_DSYNC atawa RWF_SYNC (langkung saé nganggo bandéra RWF_DSYNC).

Catetan kinerja

Kuring geus teu taliti ngukur kinerja rupa mékanisme Kuring geus nalungtik. Bedana I noticed dina speed karya maranéhanana pisan leutik. Ieu ngandung harti yén kuring bisa jadi salah, sarta yén dina kaayaan béda hal anu sarua bisa ngahasilkeun hasil béda. Kahiji, kuring bakal ngobrol ngeunaan naon mangaruhan kinerja leuwih, lajeng naon mangaruhan kinerja kirang.

  1. Nimpa data file langkung gancang tibatan nambihan data kana file (manfaat kinerja tiasa 2-100%). Nambihan data kana file butuh parobahan tambahan kana metadata file, sanajan saatos nelepon sistem fallocate(), tapi gedena pangaruh ieu bisa rupa-rupa. Abdi nyarankeun, pikeun pagelaran pangalusna, nelepon fallocate() pikeun tos alokasi rohangan anu diperyogikeun. Lajeng spasi ieu kudu eksplisit ngeusi nol sarta disebut fsync(). Ieu bakal mastikeun yén blok pakait dina sistem file ditandaan salaku "dialokasikan" tinimbang "unallocated". Ieu méré leutik (kira-kira 2%) perbaikan kinerja. Salaku tambahan, sababaraha disk tiasa gaduh aksés anu langkung laun kana blok anu sanés. Ieu ngandung harti yén ngeusian rohangan kalawan nol bisa ngakibatkeun hiji signifikan (kira 100%) pamutahiran kinerja. Khususna, ieu tiasa kajantenan sareng disk AWS EBS (Ieu data teu resmi, kuring teu bisa mastikeun eta). Sami lumaku pikeun neundeun GCP Persistent Disk (jeung ieu geus informasi resmi, dikonfirmasi ku tés). Para ahli sanésna ogé ngalakukeun hal anu sami observasi, patali jeung sagala rupa disk.
  2. Pangsaeutikna nelepon sistem, nu leuwih luhur kinerja (gain bisa jadi ngeunaan 5%). Sigana tangtangan open() kalawan bandéra O_DSYNC atawa nelepon pwritev2() kalawan bandéra RWF_SYNC gancang ti nelepon fdatasync(). Kuring curiga yén titik di dieu nyaeta pendekatan ieu muterkeun hiji peran dina kanyataan yén pangsaeutikna nelepon sistem kudu dipigawé pikeun ngajawab masalah anu sarua (hiji panggero tinimbang dua). Tapi bédana dina kinerja pisan leutik, jadi Anjeun sagemblengna bisa malire eta sarta ngagunakeun hiji hal dina aplikasi nu moal ngahesekeun logika na.

Upami anjeun resep kana topik panyimpen data sustainable, ieu sababaraha bahan anu mangpaat:

  • Métode Aksés I/O - Tinjauan dasar mékanisme input / output.
  • Mastikeun data ngahontal disk — carita ngeunaan naon kajadian ka data dina jalan ti aplikasi ka disk.
  • Nalika anjeun kedah fsync diréktori anu ngandung - jawaban kana patarosan iraha bade dianggo fsync() pikeun directories. Pikeun nempatkeun ieu sacara ringkes, tétéla yén anjeun kedah ngalakukeun ieu nalika nyiptakeun file énggal, sareng alesan pikeun rekomendasi ieu nyaéta dina Linux tiasa seueur rujukan kana file anu sami.
  • SQL Server dina Linux Ubuntu: FUA Internals — Ieu mangrupikeun pedaran kumaha panyimpen data anu terus-terusan dilaksanakeun dina SQL Server dina platform Linux. Aya sababaraha babandingan anu pikaresepeun antara telepon sistem Windows sareng Linux di dieu. Kuring ampir yakin yén éta berkat bahan ieu anu kuring diajar ngeunaan optimasi FUA XFS.

Naha anjeun kaleungitan data anu anjeun pikir disimpen sacara aman dina disk?

Panyimpenan Data Awét sareng API File Linux

Panyimpenan Data Awét sareng API File Linux

sumber: www.habr.com