Persistent Datenspeicherung an Datei-APIen Linux

WĂ€rend der Nohaltegkeet vun der DatespĂ€icherung an de Cloudsystemer recherchĂ©iert hunn, hunn ech beschloss mech selwer ze testen fir sĂ©cher ze stellen datt ech d'Basis Saache verstanen hunn. ech ugefaang andeems Dir d'NVMe SpezifizĂ©ierung gelies hutt Fir ze verstoen wat Garantien betreffend nohalteg Datelagerung (dat heescht, garantĂ©iert datt d'DonnĂ©eĂ«n no engem Systemfehler verfĂŒgbar sinn) gitt eis NMVe Disken. Ech hunn dĂ©i folgend Haaptconclusiounen gemaach: Date musse beschiedegt ugesi ginn aus dem Moment wou de Kommando fir Daten ze schreiwen gĂ«tt bis de Moment wou se op d'SpĂ€ichermedium geschriwwe ginn. WĂ©i och Ă«mmer, dĂ©i meescht Programmer benotze ganz glĂ©cklech System Appellen fir Daten opzehuelen.

An dësem Artikel ënnersichen ech déi persistent Datenspeichermechanismen, déi vun Datei-APIen ugebuede ginn. LinuxEt schéngt, datt hei alles einfach soll sinn: de Programm rifft de Kommando op write(), an nodeems dëse Kommando fÀerdeg ass, ginn d'Donnéeën sécher op Disk gespÀichert. Mee write() kopéiert nëmmen Uwendungsdaten an de Kernel Cache, deen am RAM lÀit. Fir de System ze zwéngen Daten op Disk ze schreiwen, musst Dir e puer zousÀtzlech Mechanismen benotzen.

Persistent Datenspeicherung an Datei-APIen Linux

Am Allgemengen ass dëst Material eng Sammlung vun Notizen am Zesummenhang mat deem wat ech geléiert hunn iwwer en Thema dat fir mech interesséiert ass. Wa mir ganz kuerz iwwer dat Wichtegst schwÀtzen, stellt sech eraus datt fir nohalteg Datelagerung ze organiséieren musst Dir de Kommando benotzen fdatasync() oder opmaachen Dateien mam FÀndel O_DSYNC. Wann Dir interesséiert sidd méi ze léieren iwwer wat mat Daten op sengem Wee vu Code op Disk geschitt, kuckt w.e.g dat Artikel.

Features vun der Benotzung vun der Schreiwen () Funktioun

System Opruff write() am Standard definéiert IEEE POSIX als Versuch Donnéeën zu engem Fichier Descriptor ze schreiwen. No erfollegrÀich Ofschloss write() D'Dateliesoperatioune musse genau d'Bytes zréckginn, déi virdru geschriwwe goufen, dëst maachen och wann d'Donnéeën vun anere Prozesser oder Threads zougÀnglech sinn (kuck relevant Sektioun vum POSIX Standard). et ass, an der Rubrik iwwer wéi Threads mat normale Dateioperatioune interagéieren, gëtt et eng Notiz déi seet datt wann zwee Threads all dës Funktiounen uruffen, da muss all Uruff entweder all designéiert Konsequenze vum aneren Uruff gesinn, oder guer keng. Konsequenzen. Dëst féiert zu der Conclusioun datt all Datei-I / O-Operatiounen e SpÀr op d'Ressource halen, déi se operéieren.

Heescht dat, datt d'Operatioun write() ass et atomar? Aus enger technescher Siicht, jo. Donnéeën liesen Operatiounen mussen entweder alles oder nÀischt vun deem zréckginn wat mat geschriwwe gouf write(). Awer Operatioun write(), no der Norm, muss net onbedéngt ophalen alles opzeschreiwen, wat et gefrot gouf opzeschreiwen. Si dÀerf nëmmen en Deel vun den Donnéeën schreiwen. Zum Beispill kënne mir zwee Threads hunn, déi all 1024 Bytes op eng Datei mat deemselwechte Dateideskriptor beschriwwen hunn. Aus der Siicht vum Standard ass en akzeptabelt Resultat wann all Schreifoperatioun nëmmen ee Byte an d'Datei ka addéieren. Dës Operatioune bleiwen atomarer, awer nodeems se ofgeschloss sinn, ginn d'Donnéeën, déi se an d'Datei geschriwwen hunn, gemëscht. hei ganz interessant Diskussioun iwwer dëst Thema op Stack Overflow.

fsync () an fdatasync () Funktiounen

Deen einfachste Wee fir Daten op Disk ze spĂŒlen ass d'Funktioun ze ruffen fsync(). DĂ«s Funktioun freet de Betribssystem fir all modifizĂ©iert Blocks vum Cache op Disk ze transferĂ©ieren. DĂ«st beinhalt all Dateimetadaten (ZougangszĂ€it, DateimodifikatiounszĂ€it, a sou weider). Ech gleewen datt dĂ«s Metadaten selten gebraucht ginn, also wann Dir wĂ«sst datt et Iech net wichteg ass, kĂ«nnt Dir d'Funktioun benotzen fdatasync(). d' hĂ«llefen Op der fdatasync() Et gĂ«tt gesot datt wĂ€hrend der Operatioun vun dĂ«ser Funktioun sou eng QuantitĂ©it u Metadaten op Disk gespĂ€ichert gĂ«tt, dĂ©i "nĂ©ideg ass fir dĂ©i korrekt AusfĂ©ierung vun de folgenden Dateliesoperatiounen." An dat ass genee wat dĂ©i meescht Uwendungen kĂ«mmeren.

Ee Problem deen hei ka entstoen ass datt dës Mechanismen net garantéieren datt d'Datei no engem méiglechen Ausfall entdeckt gëtt. Besonnesch wann Dir eng nei Datei erstellt, musst Dir ruffen fsync() fir de Verzeechnes deen et enthÀlt. Soss, no engem Feeler, kann et erausstellen datt dës Datei net existéiert. De Grond dofir ass datt an UNIX, duerch d'Benotzung vun haarde Linken, eng Datei a verschidde Verzeichnisser existéiere kann. Dofir, wann Dir rufft fsync() et gëtt kee Wee fir eng Datei ze wëssen, wéi eng Verzeechnesdaten och op Disk gespullt ginn (hei Dir kënnt méi iwwer dëst liesen). Et gesÀit aus wéi wann den ext4 Dateisystem fÀeg ass automatesch zoutrëfft fsync() an d'Verzeichnisser déi entspriechend Dateien enthalen, awer dëst ass vlÀicht net de Fall mat anere Dateiesystemer.

DĂ«se Mechanismus kann anescht op verschiddene Dateiesystemer Ă«mgesat ginn. Ech benotzt blktrace fir ze lĂ©ieren iwwer wĂ©i eng Diskoperatiounen an ext4 an XFS Dateisystemer benotzt ginn. BĂ©id ginn reegelmĂ©isseg Schreifbefehle op Disk fir souwuel den Dateiinhalt wĂ©i och den Dateiesystemjournal aus, spĂŒlen de Cache, an fuert aus andeems Dir e FUA ausfĂ©iert (Force Unit Access, Daten direkt op Disk schreiwen, de Cache Ă«mgoen) Schreift an de Journal. Si maachen dĂ«st wahrscheinlech fir ze bestĂ€tegen datt d'Transaktioun stattfonnt huet. Op Drive dĂ©i FUA net Ă«nnerstĂ«tzen, verursaacht dĂ«st zwee Cache-SpĂŒlen. Meng Experimenter hunn dat gewisen fdatasync() e bĂ«sse mĂ©i sĂ©ier fsync(). Utility blktrace weist dat un fdatasync() schreift normalerweis manner Daten op Disk (an ext4 fsync() schreift 20 KiB, an fdatasync() - 16 KiB). Och hunn ech erausfonnt datt XFS liicht mĂ©i sĂ©ier ass wĂ©i ext4. An hei mat der HĂ«llef blktrace gelongen dat erauszefannen fdatasync() spĂŒlt manner Daten op Disk (4 KiB an XFS).

Eendeiteg Situatiounen déi entstinn wann Dir fsync () benotzt

Ech kann un drÀi zweedeiteg Situatiounen denken fsync()déi ech an der Praxis begéint hunn.

DĂ©i Ă©ischt esou Fall ass am Joer 2008 geschitt. Dann ass de Firefox 3-Interface gefruer wann eng grouss Zuel vu Dateien op Disk geschriwwe goufen. De Problem war datt d'Ëmsetzung vun der Interface eng SQLite Datebank benotzt huet fir Informatioun iwwer sĂ€i Staat ze spĂ€icheren. No all Ännerung, dĂ©i am Interface geschitt ass, gouf d'Funktioun genannt fsync(), dĂ©i gutt Garantien fir stabil Datelagerung ginn huet. Am ext3 Dateisystem dann benotzt, d'Funktioun fsync() all "dreckeg" SĂ€iten am System op Disk gedumpt, an net nĂ«mmen dĂ©i, dĂ©i mat der entspriechender Datei verbonne waren. DĂ«st bedeit datt wann Dir e KnĂ€ppchen am Firefox klickt, kĂ©int Megabytes vun Daten auslĂ©isen fir op eng magnetesch Scheif ze schreiwen, wat vill Sekonnen dauere kĂ©int. D'LĂ©isung vum Problem, souwĂ€it ech verstinn aus et Material war Aarbecht mat der Datebank ze asynchronous Hannergrond Aufgaben Transfert. DĂ«st bedeit datt Firefox virdru mĂ©i streng SpĂ€icherfuerderunge implementĂ©iert huet wĂ©i wierklech gebraucht gouf, an d'Features vum ext3 Dateiesystem hunn dĂ«se Problem nĂ«mmen verschĂ€erft.

Den zweete Problem ass am Joer 2009 geschitt. Duerno, no engem System Crash, hunn d'Benotzer vum neie ext4 Dateiesystem mat der Tatsaach konfrontĂ©iert datt vill nei erstallt Dateien null LĂ€ngt haten, awer dĂ«st ass net geschitt mat dem eelere ext3 Dateiesystem. Am virege Paragraphe hunn ech geschwat wĂ©i ext3 ze vill Daten op Disk gespullt huet, wat d'Saache vill verlangsamt huet. fsync(). Fir d'Situatioun ze verbesseren, ginn an ext4 nĂ«mmen dĂ©i dreckeg SĂ€iten, dĂ©i fir eng bestĂ«mmte Datei relevant sinn, op den Disk gespullt. An Daten aus anere Fichier bleiwen an ErĂ«nnerung fir eng vill mĂ©i ZĂ€it wĂ©i mat ext3. DĂ«st gouf gemaach fir d'Leeschtung ze verbesseren (par dĂ©faut bleiwen d'DonnĂ©eĂ«n an dĂ«sem Zoustand fir 30 Sekonnen, Dir kĂ«nnt dĂ«st konfigurĂ©ieren dirty_expire_centisecs; hei Dir kĂ«nnt zousĂ€tzlech Material iwwer dĂ«st fannen). DĂ«st bedeit datt eng grouss QuantitĂ©it un DonnĂ©eĂ«n no engem Feeler irretrievably verluer kĂ«nne ginn. D'LĂ©isung fir dĂ«se Problem ass ze benotzen fsync() an Uwendungen dĂ©i stabil Datelagerung musse garantĂ©ieren an se sou vill wĂ©i mĂ©iglech virun de Konsequenze vu Feeler schĂŒtzen. Funktioun fsync() funktionnĂ©iert vill mĂ©i effizient wann Dir ext4 benotzt wĂ©i wann Dir ext3 benotzt. Den Nodeel vun dĂ«ser Approche ass datt seng Notzung, wĂ©i virdrun, d'AusfĂ©ierung vun e puer Operatiounen verlangsamt, wĂ©i d'Installatioun vu Programmer. Gesinn Detailer iwwer dĂ«st hei Đž hei.

Déi drëtt Problem betreffend fsync(), entstanen am Joer 2018. Dann, am Kader vum PostgreSQL Projet, gouf festgestallt datt wann d'Funktioun fsync() e Feeler begéint, et markéiert "dreckeg" SÀiten als "propper". Als Resultat, déi folgend Appellen fsync() Si maachen nÀischt mat esou SÀiten. Dofir ginn modifizéiert SÀiten an der Erënnerung gespÀichert a ginn ni op Disk geschriwwe. Dëst ass eng richteg Katastroph, well d'Applikatioun mengt datt e puer Daten op der Disk geschriwwe sinn, awer tatsÀchlech wÀert et net sinn. Esou Feeler fsync() rar sinn, kann d'Applikatioun an esou Situatiounen bal nÀischt maachen de Problem ze bekÀmpfen. Dës Deeg, wann dëst geschitt, Crash PostgreSQL an aner Uwendungen. et ass, am Material "Kënnen Uwendungen aus fsync Feeler recuperéieren?", gëtt dëse Problem am Detail exploréiert. De Moment ass déi bescht Léisung fir dëse Problem direkten I / O mam FÀndel ze benotzen O_SYNC oder mat engem FÀndel O_DSYNC. Mat dëser Approche wÀert de System Feeler mellen, déi wÀhrend spezifesche Schreifoperatioune kënne geschéien, awer dës Approche erfuerdert d'Applikatioun fir d'Puffer selwer ze managen. Liest méi iwwer dëst hei О hei.

Dateien opmaachen mat den O_SYNC an O_DSYNC FĂ€ndelen

Loosst eis zréck op d'Diskussioun vun de Mechanismen Linux, fir eng stabil Datenspeicherung ze garantéieren. Mir schwÀtze speziell vun der Benotzung vun engem FÀndel O_SYNC oder FÀndel O_DSYNC wann Dir Dateien opmaacht mat Systemruff oppen (). Mat dëser Approche gëtt all Daten Schreifoperatioun gemaach wéi no all Kommando write() de System gëtt Kommandoen entspriechend fsync() О fdatasync(). d' POSIX Spezifikatioune dëst nennt een "Synchroniséierter I/O DateiintegritéitsfÀhegkeet" an "DatenintegritéitsfÀegkeet". Den Haaptvirdeel vun dëser Approche ass datt fir d'Datenintegritéit ze garantéieren, musst Dir nëmmen ee Systemruff maachen, anstatt zwee (zum Beispill - write() О fdatasync()). Den Haaptnodeel vun dëser Approche ass datt all Schreiwen mat dem entspriechende Dateideskriptor synchroniséiert ginn, wat d'FÀegkeet limitéiere kann fir den Applikatiounscode ze strukturéieren.

Benotzt Direct I/O mam O_DIRECT FĂ€ndel

System Opruff open() ënnerstëtzt FÀndel O_DIRECT, déi entwéckelt ass fir de Betribssystem-Cache ze ëmgoen fir I/O-Operatiounen auszeféieren andeems se direkt mat der Disk interagéieren. Dëst, a ville FÀll, bedeit datt Schreifbefehle vum Programm ausgestallt ginn direkt an Kommandoen iwwersat ginn fir mat der Disk ze schaffen. MÀ, am Allgemengen, ass dëse Mechanismus keen Ersatz fir Funktiounen fsync() oder fdatasync(). D'Tatsaach ass, datt d'Disk selwer kann defer oder Cache entspriechend Daten Schreiwen Kommandoen. An, fir d'Saache méi schlëmm ze maachen, an e puer spezielle FÀll sinn d'I / O Operatiounen déi duerchgefouert ginn wann Dir de FÀndel benotzt O_DIRECT, Emissioun an traditionell gebufferten Operatiounen. Deen einfachste Wee fir dëse Problem ze léisen ass de FÀndel ze benotzen fir Dateien opzemaachen O_DSYNC, wat bedeit datt all Schreifoperatioun vun engem Opruff gefollegt gëtt fdatasync().

Et huet sech erausgestallt datt den XFS Dateisystem viru kuerzem e "schnell Wee" fir O_DIRECT|O_DSYNC-Datenopnam. Wann e Block iwwerschriwwe gĂ«tt mat O_DIRECT|O_DSYNC, dann XFS, amplaz de Cache ze spĂŒlen, wĂ€ert de FUA Schreifbefehl ausfĂ©ieren wann den Apparat et Ă«nnerstĂ«tzt. Ech hunn dĂ«st verifizĂ©iert andeems Dir den Utility benotzt blktrace am System Linux 5.4 /Ubuntu 20.04. DĂ«s Approche sollt mĂ©i effizient sinn, well se eng minimal QuantitĂ©it un Daten op d'Festplack schreift an eng Operatioun amplaz vun zwou benotzt (Schreiwen a Cache lĂ€schen). Ech hunn e Link fonnt op Patch 2018 Kernel, deen dĂ«se Mechanismus implementĂ©iert. Et gĂ«tt eng Diskussioun do iwwer d'Applikatioun vun dĂ«ser Optimisatioun op aner Dateiesystemer, awer souwĂ€it ech weess, ass XFS deen eenzegen Dateiesystem deen dĂ«st bis elo Ă«nnerstĂ«tzt.

sync_file_range () Funktioun

В Linux et gĂ«tt e Systemopruff sync_file_range(), wat Iech erlaabt nĂ«mmen en Deel vun der Datei op Disk ze spĂŒlen, anstatt dĂ©i ganz Datei. DĂ«sen Uruff initiĂ©iert en asynchronen Datefluch a waart net bis se fĂ€erdeg ass. Awer am Certificat sync_file_range() d'Equipe gĂ«tt gesot "ganz gefĂ©ierlech". Et ass net recommandĂ©iert et ze benotzen. Fonctiounen a Gefore sync_file_range() ganz gutt beschriwwen an dat Material. Speziell schĂ©ngt dĂ«sen Uruff RocksDB ze benotzen fir ze kontrollĂ©ieren wann de Kernel dreckeg Daten op Disk spĂŒlt. Awer zur selwechter ZĂ€it, fir stabil Datelagerung ze garantĂ©ieren, gĂ«tt et och benotzt fdatasync(). d' Code RocksDB huet e puer interessant Kommentaren zu dĂ«sem Thema. Zum Beispill, schĂ©ngt et, datt den Opruff sync_file_range() Wann Dir ZFS benotzt, spĂŒlt et keng Daten op Disk. D'Erfahrung seet mir datt de Code dee selten benotzt gĂ«tt wahrscheinlech Bugs enthĂ€lt. Dofir gĂ©if ech roden dĂ«se System Uruff ze benotzen, ausser et ass absolut nĂ©ideg.

System Appellen déi hëllefen d'Datepersistenz ze garantéieren

Ech sinn zu der Conclusioun komm datt et drÀi Approche sinn déi kënne benotzt ginn fir I / O Operatiounen auszeféieren déi d'Datepersistenz garantéieren. Si all verlaangen eng Funktioun Uruff fsync() fir den Dossier an deem d'Datei erstallt gouf. Dëst sinn d'Approche:

  1. Opruff eng Funktioun fdatasync() oder fsync() no Funktioun write() (et ass besser ze benotzen fdatasync()).
  2. Schafft mat engem Dateideskriptor opgemaach mat engem FĂ€ndel O_DSYNC oder O_SYNC (besser - mat engem FĂ€ndel O_DSYNC).
  3. Benotzt de Kommando pwritev2() mat FĂ€ndel RWF_DSYNC oder RWF_SYNC (Preferenz mat engem FĂ€ndel RWF_DSYNC).

Leeschtung Notes

Ech hunn d'Performance vun de verschiddene Mechanismen, dĂ©i ech iwwerprĂ©ift hunn, net virsiichteg gemooss. D'Ënnerscheeder, dĂ©i ech an der Geschwindegkeet vun hirer Aarbecht gemierkt hunn, si ganz kleng. DĂ«st bedeit datt ech falsch sinn, an datt Ă«nner verschiddene Konditiounen dĂ©iselwecht Saach verschidde Resultater produzĂ©iere kann. Als Ă©ischt wĂ€ert ech schwĂ€tzen iwwer wat d'Leeschtung mĂ©i beaflosst, an dann wat d'Leeschtung manner beaflosst.

  1. D'Dateidaten iwwerschreiwe ass mĂ©i sĂ©ier wĂ©i d'Daten op eng Datei ze addĂ©ieren (de Leeschtungsvirdeel kann 2-100% sinn). Dateen un eng Datei bĂ€izefĂŒgen erfuerdert zousĂ€tzlech Ännerungen un de Metadaten vun der Datei, och no engem Systemruff fallocate(), awer d'GrĂ©isst vun dĂ«sem Effekt kann variĂ©ieren. Ech recommandĂ©ieren, fir dĂ©i bescht Leeschtung, ze ruffen fallocate() dĂ©i erfuerderlech Plaz virauszedeelen. Da muss dĂ«se Raum explizit mat Nullen gefĂ«llt a genannt ginn fsync(). DĂ«st wĂ€ert sĂ©cherstellen datt dĂ©i entspriechend Blocken am Dateiesystem als "allokĂ©iert" markĂ©iert sinn anstatt "net allocĂ©iert". DĂ«st gĂ«tt eng kleng (ongefĂ©ier 2%) Leeschtungsverbesserung. ZousĂ€tzlech kĂ«nnen e puer Disken e mĂ©i luesen Ă©ischten Zougang zu engem Block hunn wĂ©i anerer. DĂ«st bedeit datt d'FĂŒllung vum Raum mat Nullen zu enger bedeitender (ongefĂ©ier 100%) Verbesserung vun der Leeschtung fĂ©iert. Besonnesch kann dĂ«st mat Disken geschĂ©ien AWS EBS (dĂ«st sinn inoffiziell DonnĂ©eĂ«n, ech konnt se net bestĂ€tegen). Dat selwecht gĂ«llt fir d'Lagerung GCP Persistent Disk (an dĂ«st ass schonn offiziell Informatioun, bestĂ€tegt duerch Tester). Aner Experten hunn datselwecht gemaach Observatioun, Zesummenhang mat verschiddenen Disken.
  2. Der manner System rifft, der mĂ©i hĂ©ich Leeschtung (de GewĂ«nn kann ongefĂ©ier 5%). GesĂ€it aus wĂ©i eng Erausfuerderung open() mat FĂ€ndel O_DSYNC oder ruffen pwritev2() mat FĂ€ndel RWF_SYNC mĂ©i sĂ©ier wĂ©i en Uruff fdatasync(). Ech de Verdacht, datt de Punkt hei ass, datt dĂ«s Approche eng Roll spillt an der Tatsaach, datt manner System Uriff musse gemaach ginn fir dee selwechte Problem ze lĂ©isen (een Uruff amplaz zwee). Awer den Ënnerscheed an der Leeschtung ass ganz kleng, sou datt Dir et komplett ignorĂ©iere kĂ«nnt an eppes an der Applikatioun benotze wat seng Logik net komplizĂ©iert.

Wann Dir un d'Thema vun nohalteger Datelagerung interesséiert sidd, hei sinn e puer nëtzlech Materialien:

  • ech / O Zougang Methoden - Iwwersiicht iwwer d'Basis vun Input / Output Mechanismen.
  • VergewĂ«ssert Iech datt d'DonnĂ©eĂ«n d'Disk erreecht - eng Geschicht iwwer wat geschitt mat den Daten um Wee vun der Applikatioun op den Disk.
  • WĂ©ini sollt Dir den Inhaltsverzeechnes fsynchronisĂ©ieren - d'Äntwert op d'Fro wĂ©ini ze benotzen fsync() fir Verzeichnisser. Kuerz gesot, et stellt sech eraus, datt dĂ«st beim Erstelle vun enger neier Datei gemaach soll ginn, an de Grond fir dĂ«s Empfehlung ass, datt an Linux Et kĂ©inte vill Linken op dĂ©iselwecht Datei ginn.
  • SQL Server aktivĂ©iert LinuxFUA Internals — hei ass eng Beschreiwung, wĂ©i persistent Datenspeicherung am SQL Server op der Plattform implementĂ©iert gĂ«tt LinuxEt ginn hei e puer interessant VerglĂ€icher tĂ«scht Systemuriff. Windows Đž LinuxEch sinn bal sĂ©cher, datt et dank dĂ«sem Material war, datt ech iwwer d'FUA-OptimisĂ©ierung vun XFS gelĂ©iert hunn.

Hutt Dir Daten verluer, déi Dir geduecht hutt sécher op enger Disk gespÀichert ze sinn?

Persistent Datenspeicherung an Datei-APIen Linux

Persistent Datenspeicherung an Datei-APIen Linux

Source: will.com

Kaaft zouverlĂ€sseg Hosting fir Site mat DDoS Schutz, VPS VDS Server đŸ”„ Kaaft zouverlĂ©issegt WebsĂ€ithosting mat DDoS-Schutz, VPS VDS Server | ProHoster