{"id":98090,"date":"2020-10-24T02:42:38","date_gmt":"2020-10-24T00:42:38","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux"},"modified":"2020-11-18T00:58:48","modified_gmt":"2020-11-17T22:58:48","slug":"ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","status":"publish","type":"post","link":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","title":{"rendered":"B\u00e6redygtig lagring af data og fil-API'er i Linux","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Jeg, mens jeg unders\u00f8ger datalagringsholdbarhed i cloud-systemer, besluttede at teste mig selv for at sikre, at jeg forst\u00e5r de grundl\u00e6ggende ting. Jeg <noindex><a rel=\"nofollow\" href=\"https:\/\/www.evanjones.ca\/durability-nvme.html\">startede med at l\u00e6se NVMe-specifikationen<\/a><\/noindex> for at forst\u00e5, hvilke garantier vedr\u00f8rende holdbar lagring af data (det vil sige garantier for, at dataene vil v\u00e6re tilg\u00e6ngelige efter et systemfejl), NVMe-diskene giver os. Mine f\u00f8lgende hovedkonklusioner er: Det skal betragtes, at dataene er beskadigede fra det \u00f8jeblik, hvor skrivekommandoen er givet, til det \u00f8jeblik, hvor de er f\u00e6rdige med at blive skrevet til informationsmediet. Dog anvendes systemopkald helt afslappet i de fleste programmer til dataoptagelse.<\/p>\n<p>I dette materiale unders\u00f8ger jeg de mekanismer for holdbar datalagring, der tilbydes af Linux-filsystem-API'er. Det virker til at v\u00e6re enkelt: Programmet kalder kommandoen <code>write()<\/code>, og efter at denne kommando er afsluttet, skulle dataene v\u00e6re sikkert gemt p\u00e5 disken. Men <code>write()<\/code> kopierer blot applikationernes data til kernelens cache, der ligger i RAM. For at tvinge systemet til at skrive data til disken, kr\u00e6ves nogle ekstra mekanismer.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/524172\/\"><img decoding=\"async\" alt=\"B\u00e6redygtig lagring af data og fil-API&#039;er i Linux\" src=\"\/wp-content\/uploads\/2020\/10\/b974dcb9fc546cae03ade4f3d8f5dc25.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>Generelt er dette materiale en samling noter om, hvad jeg har l\u00e6rt om det emne, der interesserer mig. Hvis man meget kort skal fort\u00e6lle om det vigtigste, er det, at for at organisere holdbar datalagring, skal man bruge kommandoen <code>fdatasync()<\/code> eller \u00e5bne filer med flaget <code>O_DSYNC<\/code>. Hvis du er interesseret i detaljerne om, hvad der sker med dataene, n\u00e5r de transporteres fra programkoden til disken, kan du se p\u00e5 <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/457667\/\">denne<\/a><\/noindex> artiklen.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Egenskaber ved brug af funktionen write()<\/h2>\n<p>\nSystemopkald <code>write()<\/code> defineres i standarden <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/POSIX\">IEEE POSIX<\/a><\/noindex> som et fors\u00f8g p\u00e5 at skrive data til en filbeskriver. Efter en vellykket afslutning <code>write()<\/code> skal datal\u00e6sningsoperationer returnere netop de bytes, der tidligere var skrevet, hvilket skal ske, selvom dataene tilg\u00e5s fra andre processer eller tr\u00e5de (<noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/functions\/write.html#tag_16_685_08\">her<\/a><\/noindex> den relevante sektion i POSIX-standarden). <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/functions\/V2_chap02.html#tag_15_09_07\">Her<\/a><\/noindex>, i afsnittet om interaktionen mellem tr\u00e5de og almindelige filoperationer er der en bem\u00e6rkning, der siger, at hvis hver af de to tr\u00e5de kalder disse funktioner, s\u00e5 skal hver opkald se enten alle de angivne konsekvenser, som udf\u00f8relsen af den anden opkald medf\u00f8rer, eller slet ingen konsekvenser. Dette f\u00f8rer til den konklusion, at alle fil I\/O-operationer skal holde l\u00e5s p\u00e5 den ressource, de arbejder med.<\/p>\n<p>Betyder det, at operationen <code>write()<\/code> er atomar? Teknisk set - ja. Data l\u00e6seoperationer skal returnere enten alt eller intet af det, der er blevet skrevet med <code>write()<\/code>. Men operationen <code>write()<\/code>, if\u00f8lge standarden, beh\u00f8ver ikke n\u00f8dvendigvis at afslutte ved at skrive alt, hvad den blev bedt om at skrive. Den m\u00e5 kun skrive en del af dataene. For eksempel kan vi have to tr\u00e5de, der hver tilf\u00f8jer 1024 byte til en fil, der beskrives af den samme filbeskrivelse. Fra standardens synspunkt er et acceptabelt resultat, hvor hver af skriveoperationerne kun kan tilf\u00f8je en byte til filen. Disse operationer vil forblive atomare, men n\u00e5r de er f\u00e6rdige, vil de data, der er skrevet af dem til filen, v\u00e6re blandede. <noindex><a rel=\"nofollow\" href=\"https:\/\/stackoverflow.com\/a\/42442926\/413438\">Her er<\/a><\/noindex> meget interessant diskussion om dette emne p\u00e5 Stack Overflow.<\/p>\n<h2>Funktionerne fsync() og fdatasync()<\/h2>\n<p>\nDen enkleste m\u00e5de at t\u00f8mme data til disk p\u00e5 er ved at kalde funktionen <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/fsync.2.html\">fsync()<\/a><\/noindex>. Denne funktion beder operativsystemet om at overf\u00f8re alle modificerede blokke fra cachen til disken. Dette inkluderer ogs\u00e5 alle metadata for filen (adgangstid, \u00e6ndringstid for filen osv.). Jeg antager, at behovet for disse metadata sj\u00e6ldent opst\u00e5r, s\u00e5 hvis du ved, at de ikke er vigtige for dig, kan du bruge funktionen <code>fdatasync()<\/code>. I <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/fdatasync.2.html\">hj\u00e6lp<\/a><\/noindex> efter <code>fdatasync()<\/code> siger, at under denne funktions arbejde overf\u00f8res der til disken s\u00e5 meget metadata, som \"er n\u00f8dvendigt for korrekt udf\u00f8relse af de f\u00f8lgende data l\u00e6seoperationer\". Og det er netop det, der bekymrer de fleste applikationer.<\/p>\n<p>Et af de problemer, der kan opst\u00e5 her, er, at disse mekanismer ikke garanterer, at filen kan findes efter et muligt sammenbrud. Is\u00e6r n\u00e5r man opretter en ny fil, skal man kalde <code>fsync()<\/code> for the directory that contains it. Otherwise, after a crash, it may turn out that this file does not exist. The reason for this is that in UNIX, due to the use of hard links, a file can exist in several directories. Therefore, when calling <code>fsync()<\/code> there is no way for the file to know which specific directory also needs to be flushed to disk (<noindex><a rel=\"nofollow\" href=\"https:\/\/www.quora.com\/When-should-you-fsync-the-containing-directory-in-addition-to-the-file-itself\">her<\/a><\/noindex> you can read more about this). It seems that the ext4 file system is capable <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/799807\/\">automatisk<\/a><\/noindex> at anvende <code>fsync()<\/code> of directories that contain the corresponding files, but this may not be the case with other file systems.<\/p>\n<p>This mechanism can be implemented differently in various file systems. I used <noindex><a rel=\"nofollow\" href=\"https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/axboe\/blktrace.git\/tree\/README\">blktrace<\/a><\/noindex> to find out which disk operations are used in the ext4 and XFS file systems. Both issue standard write commands to the disk for both file contents and the file system journal, flush the cache, and finish by performing an FUA write (Force Unit Access, writing data directly to disk, bypassing the cache) in the journal. They probably do this to confirm the operation's occurrence. On disks that do not support FUA, this causes two cache flushes. My experiments showed that <code>fdatasync()<\/code> a bit faster <code>fsync()<\/code>. Utility <code>blktrace<\/code> indicates that <code>fdatasync()<\/code> usually writes less data to disk (in ext4 <code>fsync()<\/code> writes 20 KiB, while <code>fdatasync()<\/code> \u2014 16 KiB). Additionally, I found that XFS is slightly faster than ext4. And here with the help of <code>blktrace<\/code> it was possible to find out that <code>fdatasync()<\/code> flushes less data to disk (4 KiB in XFS).<\/p>\n<h2>Ambiguous situations arising when using fsync()<\/h2>\n<p>\nI can recall three ambiguous situations regarding <code>fsync()<\/code>, that I encountered in practice.<\/p>\n<p>The first such case occurred in 2008. At that time, the Firefox 3 interface would 'hang' if a large number of files were being written to disk. The problem was that the implementation of the interface used an SQLite database to store information about its state. After every change occurring in the interface, the function was called <code>fsync()<\/code>, which provided good guarantees of data durability. In the ext3 file system used at that time, the function <code>fsync()<\/code> skrev alt \"beskidt\" indhold tilbage til disken i systemet, og ikke kun dem, der var relateret til den relevante fil. Det bet\u00f8d, at et klik p\u00e5 knappen i Firefox kunne initiere skrivning af megabyte data til den magnetiske disk, hvilket kunne tage mange sekunder. Problemet blev l\u00f8st, som jeg forstod det fra <noindex><a rel=\"nofollow\" href=\"http:\/\/shaver.off.net\/diary\/2008\/05\/25\/fsyncers-and-curveballs\/\">denne<\/a><\/noindex> materialet, ved at flytte arbejdet med databasen til asynkrone baggrundsopgaver. Det betyder, at tidligere i Firefox var der implementeret strengere krav til datalagringsimulering, end hvad der egentlig var n\u00f8dvendigt, og egenskaberne ved filsystemet ext3 forv\u00e6rrede blot dette problem.<\/p>\n<p>Det andet problem opstod i 2009. Dengang, efter et systemnedbrud, st\u00f8dte brugerne af det nye filsystem ext4 p\u00e5, at mange nyligt oprettede filer havde nul l\u00e6ngde, mens det ikke skete med det \u00e6ldre filsystem ext3. I den foreg\u00e5ende s\u00e6tning n\u00e6vnte jeg, at ext3 skrev for meget data til disken, hvilket bremse <code>fsync()<\/code>. For at forbedre situationen skriver ext4 kun de \"beskidte\" sider tilbage til disken, der er relateret til en specifik fil. Data fra andre filer forbliver i hukommelsen i meget l\u00e6ngere tid end med brug af ext3. Dette blev gjort for at forbedre ydeevnen (som standard forbliver data i denne tilstand i 30 sekunder, dette kan justeres ved hj\u00e6lp af <noindex><a rel=\"nofollow\" href=\"https:\/\/www.kernel.org\/doc\/Documentation\/sysctl\/vm.txt\">dirty_expire_centisecs<\/a><\/noindex>; <noindex><a rel=\"nofollow\" href=\"https:\/\/www.spinics.net\/lists\/linux-ext4\/msg68941.html\">her<\/a><\/noindex> , hvor du kan finde yderligere oplysninger om dette). Det betyder, at et stort antal data kan g\u00e5 tabt permanent efter et nedbrud. L\u00f8sningen p\u00e5 dette problem ligger i brugen af <code>fsync()<\/code> i applikationer, der skal sikre vedvarende datalagring og maksimalt beskytte dem mod konsekvenserne af nedbrud. Funktionen <code>fsync()<\/code> fungerer langt mere effektivt med ext4 end med ext3. Ulempen ved denne tilgang er, at dens anvendelse, som f\u00f8r, bremser udf\u00f8relsen af visse operationer, s\u00e5som installation af programmer. Se detaljer om dette <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/322823\/\">her<\/a><\/noindex> og <noindex><a rel=\"nofollow\" href=\"https:\/\/thunk.org\/tytso\/blog\/2009\/03\/12\/delayed-allocation-and-the-zero-length-file-problem\/\">her<\/a><\/noindex>.<\/p>\n<p>Det tredje problem, der ang\u00e5r <code>fsync()<\/code>, opstod i 2018. Dengang, inden for rammerne af PostgreSQL-projektet, blev det afsl\u00f8ret, at hvis funktionen <code>fsync()<\/code> st\u00f8der p\u00e5 en fejl, markerer den \"beskidte\" sider som \"rene\". Som et resultat vil de efterf\u00f8lgende kald <code>fsync()<\/code> der bliver ikke gjort noget med s\u00e5danne sider. P\u00e5 grund af dette gemmes de modificerede sider i hukommelsen og skrives aldrig til disken. Dette er en reel katastrofe, da applikationen vil tro, at nogle data er gemt p\u00e5 disken, n\u00e5r det i virkeligheden ikke er tilf\u00e6ldet. S\u00e5danne fejl <code>fsync()<\/code> forekommer sj\u00e6ldent, og applikationen kan i s\u00e5danne situationer n\u00e6sten intet g\u00f8re for at bek\u00e6mpe problemet. I dag, n\u00e5r dette sker, afslutter PostgreSQL og andre applikationer ofte ned. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.usenix.org\/conference\/atc20\/presentation\/rebello\">Her<\/a><\/noindex>, i materialet \"Kan applikationer komme sig efter fsync-fejl?\" bliver dette problem udforsket i detaljer. I \u00f8jeblikket er den bedste l\u00f8sning p\u00e5 dette problem at bruge Direct I\/O med flaget <code>O_SYNC<\/code> eller med flaget <code>O_DSYNC<\/code>. Med denne tilgang vil systemet rapportere fejl, der kan opst\u00e5 under specifikke data skriveoperationer, men denne tilgang kr\u00e6ver, at applikationen selv h\u00e5ndterer buffere. L\u00e6s mere om dette <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/752063\/\">her<\/a><\/noindex> og <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Fsync_Errors\">her<\/a><\/noindex>.<\/p>\n<h2>\u00c5bning af filer med flagene O_SYNC og O_DSYNC<\/h2>\n<p>\nLad os vende tilbage til diskussionen om de mekanismer, der muligg\u00f8r holdbar datalagring i Linux. Det handler specifikt om at bruge flaget <code>O_SYNC<\/code> eller flaget <code>O_DSYNC<\/code> ved \u00e5bning af filer ved hj\u00e6lp af systemopkald <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/open.2.html\">open()<\/a><\/noindex>. Med denne tilgang udf\u00f8res hver data skriveoperation, som om hver kommando <code>write()<\/code> systemet gives, henholdsvis kommandoer <code>fsync()<\/code> og <code>fdatasync()<\/code>. I <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/009695399\/basedefs\/xbd_chap03.html#tag_03_373\">POSIX specifikation<\/a><\/noindex> kaldes \"Synchronized I\/O File Integrity Completion\" og \"Data Integrity Completion\". Den prim\u00e6re fordel ved denne tilgang er, at der kun er behov for at udf\u00f8re \u00e9t systemopkald for at sikre dataintegritet, og ikke to (f.eks. - <code>write()<\/code> og <code>fdatasync()<\/code>). Den st\u00f8rste ulempe ved denne tilgang er, at alle skriveoperationer, der bruger den relevante filbeskriver, vil v\u00e6re synkroniserede, hvilket kan begr\u00e6nse mulighederne for struktureret kode i applikationen.<\/p>\n<h2>Brugen af Direct I\/O med flaget O_DIRECT<\/h2>\n<p>\nSystemopkald <code>open()<\/code> underst\u00f8tter flaget <code>O_DIRECT<\/code>, som er beregnet til at udf\u00f8re input-output operationer ved at omg\u00e5 operativsystemets cache og interagere direkte med disken. Dette betyder i mange tilf\u00e6lde, at skrivekommandoerne, der gives af programmet, vil blive direkte oversat til kommandoer, der er rettet mod diskoperationer. Men generelt er denne mekanisme ikke en erstatning for funktionerne <code>fsync()<\/code> eller <code>fdatasync()<\/code>. Problemet er, at selve disken kan <noindex><a rel=\"nofollow\" href=\"https:\/\/www.evanjones.ca\/durability-nvme.html\">udskyde eller cache<\/a><\/noindex> de relevante dataskrivekommandoer. Og hvad der er v\u00e6rre, i nogle s\u00e6rlige tilf\u00e6lde vil input-output-operationer, der udf\u00f8res med flaget <code>O_DIRECT<\/code>, <noindex><a rel=\"nofollow\" href=\"https:\/\/ext4.wiki.kernel.org\/index.php\/Clarifying_Direct_IO%27s_Semantics\">blive translateret<\/a><\/noindex> til traditionelle bufferede operationer. Den nemmeste m\u00e5de at l\u00f8se dette problem p\u00e5 er at bruge et flag, n\u00e5r man \u00e5bner filer <code>O_DSYNC<\/code>, hvilket vil betyde, at hver skrivingoperation vil blive efterfulgt af et kald <code>fdatasync()<\/code>.<\/p>\n<p>Det viser sig, at der for nylig er blevet tilf\u00f8jet en 'hurtig vej' til filsystemet XFS for <code>O_DIRECT|O_DSYNC<\/code>-skrivning af data. Hvis blokken skrives over ved hj\u00e6lp af <code>O_DIRECT|O_DSYNC<\/code>, s\u00e5 vil XFS, i stedet for at t\u00f8mme cachen, udf\u00f8re FUA-skrivningskommandoen, hvis enheden underst\u00f8tter det. Jeg bekr\u00e6ftede dette ved hj\u00e6lp af v\u00e6rkt\u00f8jet <code>blktrace<\/code> i Linux 5.4\/Ubuntu 20.04. Denne tilgang b\u00f8r v\u00e6re mere effektiv, da den minimalt skriver data til disken og samtidig anvender \u00e9n operation i stedet for to (skrivning og t\u00f8mning af cache). Jeg fandt et link til <noindex><a rel=\"nofollow\" href=\"https:\/\/patchwork.kernel.org\/patch\/10250257\/\">patch<\/a><\/noindex> kernen fra 2018, hvor denne mekanisme er implementeret. Der er en diskussion om anvendelse af denne optimering i andre filsystemer, men s\u00e5 vidt jeg ved, er XFS det eneste filsystem, der underst\u00f8tter det indtil videre.<\/p>\n<h2>Funktionen sync_file_range()<\/h2>\n<p>\nI Linux er der et systemopkald <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/sync_file_range.2.html\">sync_file_range()<\/a><\/noindex>, som g\u00f8r det muligt at t\u00f8mme kun en del af en fil til disken, ikke hele filen. Dette opkald initierer en asynkron t\u00f8mning af data og venter ikke p\u00e5, at det er afsluttet. Men i dokumentationen til <code>sync_file_range()<\/code> siges det, at denne kommando er 'meget farlig'. Det anbefales ikke at bruge den. Egenskaberne og farerne <code>sync_file_range()<\/code> er meget godt beskrevet i <noindex><a rel=\"nofollow\" href=\"http:\/\/yoshinorimatsunobu.blogspot.com\/2014\/03\/how-syncfilerange-really-works.html\">denne<\/a><\/noindex> materialet. Is\u00e6r ser det ud til, at dette opkald bruger RocksDB til at styre, hvorn\u00e5r kernen t\u00f8mmer 'beskidte' data til disken. Men samtidig bruges <code>fdatasync()<\/code>. I <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/facebook\/rocksdb\/search?q=sync_file_range\">koden<\/a><\/noindex> RocksDB har interessante kommentarer om dette emne. For eksempel ser det ud til, at opkaldet <code>sync_file_range()<\/code> ikke f\u00f8rer til t\u00f8mning af data til disken, n\u00e5r ZFS anvendes. Erfaring fort\u00e6ller mig, at kode, der sj\u00e6ldent benyttes, m\u00e5ske indeholder fejl. Derfor ville jeg r\u00e5de imod at bruge dette systemopkald uden en ekstrem n\u00f8dvendighed.<\/p>\n<h2>Systemopkald, der hj\u00e6lper med at sikre holdbar datalagring<\/h2>\n<p>\nJeg er kommet frem til, at man til udf\u00f8relse af ind- og udt\u00e6gningsoperationer, der sikrer vedvarende datalagring, kan benytte tre metoder. Alle kr\u00e6ver et funktionskald <code>fsync()<\/code> for den mappe, hvor filen er oprettet. Her er disse metoder:<\/p>\n<ol>\n<li>Kald af funktionen <code>fdatasync()<\/code> eller <code>fsync()<\/code> efter funktionen <code>write()<\/code> (det er bedre at benytte <code>fdatasync()<\/code>).<\/li>\n<li>Arbejdet med filbeskrivere, der er \u00e5bnet med flaget <code>O_DSYNC<\/code> eller <code>O_SYNC<\/code> (bedre \u2014 med flaget <code>O_DSYNC<\/code>).<\/li>\n<li>Brug af kommandoen <code>pwritev2()<\/code> med flag <code>RWF_DSYNC<\/code> eller <code>RWF_SYNC<\/code> (fortrinsvis \u2014 med flaget <code>RWF_DSYNC<\/code>).<\/li>\n<\/ol>\n<p><\/p>\n<h2>Noter om ydeevne<\/h2>\n<p>\nJeg har ikke udf\u00f8rt grundige m\u00e5linger af ydeevnen for de forskellige mekanismer, jeg har unders\u00f8gt. De hastighedsforskelle, jeg har bem\u00e6rket, er ret sm\u00e5. Det betyder, at jeg kan tage fejl, og at det samme i andre omst\u00e6ndigheder kan vise andre resultater. F\u00f8rst vil jeg tale om, hvad der har den st\u00f8rste indflydelse p\u00e5 ydeevnen, og derefter, hvad der har mindre indflydelse p\u00e5 ydeevnen.<\/p>\n<ol>\n<li>Oprettelse af data i en fil er hurtigere end at tilf\u00f8je data til filen (ydelsesgevinsten kan v\u00e6re 2-100%). At tilf\u00f8je data til en fil kr\u00e6ver yderligere \u00e6ndringer i filens metadata, selv efter systemkaldet <code>fallocate()<\/code>, men omfanget af denne effekt kan variere. Jeg anbefaler, at man for at sikre den bedste ydeevne kalder <code>fallocate()<\/code> til at forudallokere det n\u00f8dvendige plads. Derefter skal dette rum eksplicit fyldes med nuller og kaldes <code>fsync()<\/code>. Dette g\u00f8r, at de relevante blokke i filsystemet bliver markeret som \"allokerede\", og ikke som \"ikke-allokerede\". Dette giver en lille (ca. 2%) forbedring af ydeevnen. Desuden kan det hos nogle diske tage l\u00e6ngere tid at f\u00e5 adgang til blokkerne som f\u00f8rste operation i forhold til andre. Det betyder, at udfyldning af rummet med nuller kan f\u00f8re til en betydelig (ca. 100%) forbedring af ydeevnen. S\u00e6rligt kan dette v\u00e6re g\u00e6ldende for diske <noindex><a rel=\"nofollow\" href=\"https:\/\/n2ws.com\/blog\/how-to-guides\/pre-warm-ebs-volumes-on-aws\">AWS EBS<\/a><\/noindex> (dette er uofficielle data, som jeg ikke har kunnet bekr\u00e6fte). Det samme g\u00e6lder for lagre <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.google.com\/compute\/docs\/disks\/benchmarking-pd-performance\">GCP Persistent Disk<\/a><\/noindex> (og dette er allerede officielle oplysninger, bekr\u00e6ftet af test). Andre specialister har gjort de samme <noindex><a rel=\"nofollow\" href=\"http:\/\/yoshinorimatsunobu.blogspot.com\/2009\/05\/overwriting-is-much-faster-than_28.html\">observationer<\/a><\/noindex>, der relaterer sig til forskellige diske.<\/li>\n<li>Jo f\u00e6rre systemkald, desto h\u00f8jere ydeevne (gevinsten kan v\u00e6re omkring 5%). Det ser ud til, at kaldet <code>open()<\/code> med flag <code>O_DSYNC<\/code> eller kaldet <code>pwritev2()<\/code> med flag <code>RWF_SYNC<\/code> er hurtigere end kaldet <code>fdatasync()<\/code>Jeg mist\u00e6nker, at det har noget at g\u00f8re med, at der med denne tilgang er f\u00e6rre systemopkald, der kr\u00e6ves for at l\u00f8se den samme opgave (et opkald i stedet for to). Men forskellen i ydeevnen er meget lille, s\u00e5 du kan fuldst\u00e6ndig ignorere den og bruge det, der ikke vil komplicere logikken i din applikation.<\/li>\n<\/ol>\n<p>\nHvis du er interesseret i emnet b\u00e6redygtig datalagring \u2014 her er nogle nyttige materialer:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.scylladb.com\/2017\/10\/05\/io-access-methods-scylla\/\">I\/O Adgangsmetoder<\/a><\/noindex> \u2014 en oversigt over grundl\u00e6ggende mekanismer for input\/output.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/457667\/\">Sikring af at data n\u00e5r disken<\/a><\/noindex> \u2014 en beskrivelse af, hvad der sker med dataene p\u00e5 vej fra applikationen til disken.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.quora.com\/When-should-you-fsync-the-containing-directory-in-addition-to-the-file-itself\">Hvorn\u00e5r skal du fsync den indeholdende mappe<\/a><\/noindex> \u2014 svaret p\u00e5 sp\u00f8rgsm\u00e5let om, hvorn\u00e5r det er n\u00f8dvendigt at anvende <code>fsync()<\/code> til mapper. For at sige det kort, skal dette g\u00f8res, n\u00e5r der oprettes en ny fil, og grunden til denne anbefaling er, at der i Linux kan v\u00e6re mange links til den samme fil.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/bobsql.com\/sql-server-on-linux-forced-unit-access-fua-internals\/\">SQL Server p\u00e5 Linux: FUA Internals<\/a><\/noindex> \u2014 her gives der en beskrivelse af, hvordan b\u00e6redygtig datalagring er implementeret i SQL Server p\u00e5 Linux-platformen. Her er der nogle interessante sammenligninger mellem systemopkald i Windows og Linux. Jeg er n\u00e6sten sikker p\u00e5, at det var dette materiale, der fik mig til at l\u00e6re om FUA-optimering i XFS.<\/li>\n<\/ul>\n<p>\nHar du mistet data, som du troede var sikkert gemt p\u00e5 disken?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/ruvds.com\/ru-rub?utm_source=habr&amp;utm_medium=article&amp;utm_campaign=perevod&amp;utm_content=ustojchivoe_xranenie_dannyx_i_fajlovye_api_linux#order\"><img decoding=\"async\" alt=\"B\u00e6redygtig lagring af data og fil-API&#039;er i Linux\" src=\"\/wp-content\/uploads\/2020\/10\/8bea3fc2b65a5a683655d9c15e153c93.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/ruvds.com\/ru-rub\/news\/read\/123?utm_source=habr&amp;utm_medium=article&amp;utm_campaign=perevod&amp;utm_content=ustojchivoe_xranenie_dannyx_i_fajlovye_api_linux\"><img decoding=\"async\" alt=\"B\u00e6redygtig lagring af data og fil-API&#039;er i Linux\" src=\"\/wp-content\/uploads\/2020\/10\/d9fd0b1c09eb6e40944aee2d13ee4088.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Kilde: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/524172\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u042f, \u0438\u0441\u0441\u043b\u0435\u0434\u0443\u044f \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445, \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0435\u0431\u044f, \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u0435\u0449\u0438. \u042f \u043d\u0430\u0447\u0430\u043b \u0441 \u0447\u0442\u0435\u043d\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 NVMe \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u0442\u0435\u043c, \u043a\u0430\u043a\u0438\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0438, \u043a\u0430\u0441\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 (\u0442\u043e \u0435\u0441\u0442\u044c \u2014 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0438 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043f\u043e\u0441\u043b\u0435 \u0441\u0431\u043e\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b), \u0434\u0430\u044e\u0442 \u043d\u0430\u043c NMVe-\u0434\u0438\u0441\u043a\u0438. \u042f \u0441\u0434\u0435\u043b\u0430\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":98091,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-98090","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u042f, \u0438\u0441\u0441\u043b\u0435\u0434\u0443\u044f \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445, \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0435\u0431\u044f, \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u0435\u0449\u0438.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0423\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0435 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u044b\u0435 API Linux | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u042f, \u0438\u0441\u0441\u043b\u0435\u0434\u0443\u044f \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445, \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0435\u0431\u044f, \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u0435\u0449\u0438.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-10-24T00:42:38+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-11-17T22:58:48+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47B\u00e6redygtig datalagring og fil-API'er i Linux | ProHoster","description":"Jeg, mens jeg unders\u00f8gte b\u00e6redygtigheden af datalagring i skybaserede systemer, besluttede at teste mig selv for at sikre, at jeg forst\u00e5r de grundl\u00e6ggende ting.","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0423\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0435 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u044b\u0435 API Linux | ProHoster","og:description":"\u042f, \u0438\u0441\u0441\u043b\u0435\u0434\u0443\u044f \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445, \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0435\u0431\u044f, \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u0435\u0449\u0438.","og:url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-10-24T00:42:38+00:00","article:modified_time":"2020-11-17T22:58:48+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"98090","title":null,"description":null,"keywords":null,"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 10:05:49","updated":"2026-08-11 12:50:05","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/98090","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=98090"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/98090\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media\/98091"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=98090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=98090"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=98090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}