{"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\/de\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","title":{"rendered":"Nachhaltige Datenspeicherung und Linux-Datei-APIs","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Ich habe, w\u00e4hrend ich die Stabilit\u00e4t der Datenspeicherung in Cloud-Systemen untersuchte, beschlossen, mich selbst zu \u00fcberpr\u00fcfen und sicherzustellen, dass ich die grundlegenden Dinge verstehe. Ich <noindex><a rel=\"nofollow\" href=\"https:\/\/www.evanjones.ca\/durability-nvme.html\">begann mit dem Lesen der NVMe-Spezifikation<\/a><\/noindex> , um herauszufinden, welche Garantien hinsichtlich der stabilen Datenspeicherung (also die Garantie, dass die Daten nach einem Systemausfall verf\u00fcgbar sind) uns NVMe-Disks bieten. Ich habe die folgenden wesentlichen Erkenntnisse gewonnen: Daten sollten als besch\u00e4digt betrachtet werden, vom Zeitpunkt der Ausgabe des Schreibbefehls bis zum Abschluss des Schreibvorgangs auf das Speichermedium. In den meisten Datenaufzeichnungsprogrammen werden jedoch ganz normal Systemaufrufe verwendet.<\/p>\n<p>In diesem Material untersuche ich die Mechanismen der stabilen Datenspeicherung, die durch die Datei-APIs von Linux bereitgestellt werden. Es scheint, als sollte alles einfach sein: Das Programm ruft den Befehl <code>write()<\/code>, und nachdem dieser Befehl abgeschlossen ist, sollten die Daten sicher auf der Festplatte gespeichert sein. Aber <code>write()<\/code> kopiert lediglich die Anwendungsdaten in den Cache des Kernels, der sich im Hauptspeicher befindet. Um das System zum Schreiben der Daten auf die Festplatte zu zwingen, m\u00fcssen einige zus\u00e4tzliche Mechanismen verwendet werden.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/524172\/\"><img decoding=\"async\" alt=\"Nachhaltige Datenspeicherung und Linux-Datei-APIs\" src=\"\/wp-content\/uploads\/2020\/10\/b974dcb9fc546cae03ade4f3d8f5dc25.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>Insgesamt stellt dieses Material eine Sammlung von Notizen zu dem dar, was ich \u00fcber das Thema, das mich interessiert, herausgefunden habe. Kurz gesagt: F\u00fcr die Organisation der stabilen Datenspeicherung sollte der Befehl <code>fdatasync()<\/code> oder das \u00d6ffnen von Dateien mit dem Flag <code>O_DSYNC<\/code>verwendet werden. Wenn Sie mehr \u00fcber die Details erfahren m\u00f6chten, was mit den Daten auf dem Weg vom Programmcode zur Festplatte passiert, schauen Sie sich die <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/457667\/\">Maschine verwendet.<\/a><\/noindex> Artikel an.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Besonderheiten der Verwendung der Funktion write()<\/h2>\n<p>\nSystemaufruf <code>write()<\/code> wird im Standard <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/POSIX\">IEEE POSIX<\/a><\/noindex> definiert als ein Versuch, Daten in einen Dateideskriptor zu schreiben. Nach erfolgreichem Abschluss <code>write()<\/code> sollten Datenlesevorg\u00e4nge genau die Bytes zur\u00fcckgeben, die vorher geschrieben wurden, selbst wenn auf die Daten aus anderen Prozessen oder Threads zugegriffen wird (<noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/functions\/write.html#tag_16_685_08\">hier<\/a><\/noindex> entsprechender Abschnitt des POSIX-Standards). <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/functions\/V2_chap02.html#tag_15_09_07\">Hier<\/a><\/noindex>, im Abschnitt \u00fcber die Interaktion von Threads mit herk\u00f6mmlichen Dateioperationen gibt es eine Anmerkung, die besagt, dass wenn jeder von zwei Threads diese Funktionen aufruft, jeder Aufruf entweder alle angegebenen Auswirkungen, die aus der Ausf\u00fchrung des anderen Aufrufs resultieren, oder gar keine Auswirkungen sehen muss. Das f\u00fchrt zu dem Schluss, dass alle Ein- und Ausgabe-Dateioperationen die Sperre der Ressource, mit der sie arbeiten, aufrechterhalten m\u00fcssen.<\/p>\n<p>Bedeutet das, dass die Operation <code>write()<\/code> atomar ist? Aus technischer Sicht \u2014 ja. Leseoperationen sollten entweder alles oder nichts von dem zur\u00fcckgeben, was durch <code>write()<\/code>geschrieben wurde. Aber die Operation <code>write()<\/code>muss gem\u00e4\u00df dem Standard nicht unbedingt abgeschlossen werden, indem sie alles, was ihr angeboten wurde, schreibt. Es ist erlaubt, nur einen Teil der Daten zu schreiben. Zum Beispiel k\u00f6nnen wir zwei Threads haben, die jeweils 1024 Bytes an eine Datei anh\u00e4ngen, die durch denselben Dateideskriptor beschrieben wird. Aus der Sicht des Standards ist es akzeptabel, wenn jede der Schreiboperationen nur ein Byte an die Datei anh\u00e4ngen kann. Diese Operationen bleiben atomic, aber nachdem sie abgeschlossen sind, sind die Daten, die sie in die Datei geschrieben haben, vermischt. <noindex><a rel=\"nofollow\" href=\"https:\/\/stackoverflow.com\/a\/42442926\/413438\">Hier<\/a><\/noindex> eine sehr interessante Diskussion zu diesem Thema auf Stack Overflow.<\/p>\n<h2>Die Funktionen fsync() und fdatasync()<\/h2>\n<p>\nDer einfachste Weg, Daten auf die Festplatte zu schreiben, besteht darin, die Funktion <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/fsync.2.html\">fsync()<\/a><\/noindex>. Diese Funktion fordert das Betriebssystem auf, alle modifizierten Bl\u00f6cke aus dem Cache auf die Festplatte zu \u00fcbertragen. Dazu geh\u00f6ren auch alle Metadaten der Datei (Zugriffszeit, \u00c4nderungszeit der Datei usw.). Ich denke, dass der Bedarf an diesen Metadaten selten auftritt, also wenn Sie wissen, dass sie f\u00fcr Sie nicht wichtig sind, k\u00f6nnen Sie die Funktion <code>fdatasync()<\/code>. In <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/fdatasync.2.html\">Hilfe<\/a><\/noindex> nach <code>fdatasync()<\/code> sagt, dass im Laufe dieser Funktion eine solche Menge an Metadaten auf die Festplatte gespeichert wird, die 'notwendig ist, um die n\u00e4chsten Leseoperationen korrekt auszuf\u00fchren'. Und das ist genau das, was die meisten Anwendungen besch\u00e4ftigt.<\/p>\n<p>Ein Problem, das hier auftreten kann, besteht darin, dass diese Mechanismen nicht garantieren, dass die Datei nach einem m\u00f6glichen Absturz wieder gefunden werden kann. Insbesondere muss beim Erstellen einer neuen Datei ein Aufruf get\u00e4tigt werden <code>fsync()<\/code> f\u00fcr das Verzeichnis, das ihn enth\u00e4lt. Andernfalls kann es nach einem Fehler so sein, dass diese Datei nicht existiert. Der Grund daf\u00fcr liegt darin, dass unter UNIX, aufgrund der Verwendung von Hardlinks, eine Datei in mehreren Verzeichnissen existieren kann. Daher bei einem Aufruf <code>fsync()<\/code> gibt es keine M\u00f6glichkeit, herauszufinden, welche Daten eines bestimmten Verzeichnisses ebenfalls auf die Festplatte geschrieben werden m\u00fcssen (<noindex><a rel=\"nofollow\" href=\"https:\/\/www.quora.com\/When-should-you-fsync-the-containing-directory-in-addition-to-the-file-itself\">hier<\/a><\/noindex> dar\u00fcber kann man ausf\u00fchrlicher lesen). Es scheint, dass das Dateisystem ext4 in der Lage ist <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/799807\/\">automatisch<\/a><\/noindex> einzusetzen <code>fsync()<\/code> zu Verzeichnissen, die die entsprechenden Dateien enthalten, aber in F\u00e4llen mit anderen Dateisystemen k\u00f6nnte das anders sein.<\/p>\n<p>Dieser Mechanismus kann in verschiedenen Dateisystemen unterschiedlich implementiert werden. Ich habe verwendet <noindex><a rel=\"nofollow\" href=\"https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/axboe\/blktrace.git\/tree\/README\">blktrace<\/a><\/noindex> um herauszufinden, welche Festplattenoperationen in den Dateisystemen ext4 und XFS verwendet werden. Beide geben herk\u00f6mmliche Schreibbefehle sowohl f\u00fcr den Inhalt von Dateien als auch f\u00fcr das Journal des Dateisystems aus, schreiben den Cache zur\u00fcck und beenden die Ausf\u00fchrung, indem sie eine FUA-Schreibung (Force Unit Access, direkte Datenschreibung auf die Festplatte, um den Cache herum) ins Journal ausf\u00fchren. Wahrscheinlich machen sie dies, um den Abschluss der Operation zu best\u00e4tigen. Auf Festplatten, die FUA nicht unterst\u00fctzen, f\u00fchrt dies zu zwei Cache-R\u00fcckschreibungen. Meine Experimente zeigten, dass <code>fdatasync()<\/code> ein wenig schneller <code>fsync()<\/code>. Das Tool <code>blktrace<\/code> darauf hinweist, dass <code>fdatasync()<\/code> in der Regel weniger Daten auf die Festplatte schreibt (in ext4 <code>fsync()<\/code> schreibt 20 KiB, und <code>fdatasync()<\/code> \u2014 16 KiB). Au\u00dferdem habe ich festgestellt, dass XFS etwas schneller ist als ext4. Und dabei konnte ich <code>blktrace<\/code> herausfinden, dass <code>fdatasync()<\/code> weniger Daten auf die Festplatte zur\u00fcckschreibt (4 KiB in XFS).<\/p>\n<h2>Uneindeutige Situationen, die bei der Verwendung von fsync() auftreten<\/h2>\n<p>\nIch kann mich an drei uneindeutige Situationen erinnern, die sich beziehen auf <code>fsync()<\/code>, mit denen ich in der Praxis konfrontiert war.<\/p>\n<p>Der erste solche Fall trat 2008 auf. Damals \u201ehing\u201c die Benutzeroberfl\u00e4che von Firefox 3, wenn eine gro\u00dfe Anzahl von Dateien auf die Festplatte geschrieben wurde. Das Problem lag darin, dass bei der Implementierung der Benutzeroberfl\u00e4che eine SQLite-Datenbank verwendet wurde, um Informationen \u00fcber ihren Status zu speichern. Nach jeder \u00c4nderung, die in der Benutzeroberfl\u00e4che stattfand, wurde die Funktion <code>fsync()<\/code>aufgerufen, was gute Garantien f\u00fcr die dauerhafte Speicherung der Daten bot. Im damals verwendeten Dateisystem ext3 war die Funktion <code>fsync()<\/code> Sie hat alle \"schmutzigen\" Seiten im System auf die Festplatte zur\u00fcckgesetzt, nicht nur die, die mit der entsprechenden Datei zu tun hatten. Das bedeutete, dass ein Klick auf die Schaltfl\u00e4che in Firefox die Aufzeichnung von Megabytes an Daten auf die magnetische Festplatte initiieren konnte, was viele Sekunden in Anspruch nehmen konnte. Die L\u00f6sung des Problems bestand, wie ich verstand, darin, <noindex><a rel=\"nofollow\" href=\"http:\/\/shaver.off.net\/diary\/2008\/05\/25\/fsyncers-and-curveballs\/\">dieses<\/a><\/noindex> die Arbeiten mit der Datenbank in asynchrone Hintergrundaufgaben zu verlagern. Das bedeutet, dass Firefox fr\u00fcher strengere Anforderungen an die Stabilit\u00e4t der Datenspeicherung hatte, als es wirklich n\u00f6tig war, und die Besonderheiten des ext3-Dateisystems das Problem nur versch\u00e4rften.<\/p>\n<p>Das zweite Missverh\u00e4ltnis trat im Jahr 2009 auf. Nach einem Systemausfall begegneten Benutzer des neuen ext4-Dateisystems dem Problem, dass viele neu erstellte Dateien eine null L\u00e4nge hatten, w\u00e4hrend dies beim \u00e4lteren ext3-Dateisystem nicht der Fall war. Im vorherigen Absatz sprach ich dar\u00fcber, dass ext3 zu viele Daten auf die Festplatte zur\u00fccksetzte, was die Leistung stark verlangsamte <code>fsync()<\/code>. Um die Situation zu verbessern, werden beim ext4 nur die \"schmutzigen\" Seiten auf die Festplatte zur\u00fcckgesetzt, die mit einer bestimmten Datei zu tun haben. Die Daten anderer Dateien bleiben viel l\u00e4nger im Speicher als bei der Verwendung von ext3. Dies wurde zur Verbesserung der Leistung gemacht (standardm\u00e4\u00dfig verweilen die Daten in diesem Zustand 30 Sekunden, dies kann mit Hilfe von <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\">hier<\/a><\/noindex> weiteren Materialien dazu gefunden werden). Das bedeutet, dass ein gro\u00dfer Datenvolumen nach einem Ausfall unwiderruflich verloren gehen kann. Die L\u00f6sung dieses Problems liegt in der Verwendung von <code>fsync()<\/code> Anwendungen, die eine stabile Datenspeicherung gew\u00e4hrleisten und diese so gut wie m\u00f6glich vor den Folgen von Ausf\u00e4llen sch\u00fctzen m\u00fcssen. Die Funktion <code>fsync()<\/code> arbeitet bei Verwendung von ext4 wesentlich effektiver als bei ext3. Der Nachteil eines solchen Ansatzes besteht darin, dass seine Anwendung, wie zuvor, die Ausf\u00fchrung bestimmter Vorg\u00e4nge, wie die Installation von Programmen, verlangsamt. Einzelheiten dazu finden Sie <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/322823\/\">hier<\/a><\/noindex> und <noindex><a rel=\"nofollow\" href=\"https:\/\/thunk.org\/tytso\/blog\/2009\/03\/12\/delayed-allocation-and-the-zero-length-file-problem\/\">hier<\/a><\/noindex>.<\/p>\n<p>Das dritte Problem, das <code>fsync()<\/code>, trat im Jahr 2018 auf. Im Rahmen des PostgreSQL-Projekts wurde festgestellt, dass, wenn die Funktion <code>fsync()<\/code> auf einen Fehler st\u00f6\u00dft, sie die \"schmutzigen\" Seiten als \"sauber\" markiert. Infolgedessen f\u00fchrten die folgenden Aufrufe <code>fsync()<\/code> Mit solchen Seiten wird nichts gemacht. Daher bleiben modifizierte Seiten im Speicher und werden niemals auf die Festplatte geschrieben. Dies ist eine echte Katastrophe, da die Anwendung denken wird, dass bestimmte Daten auf die Festplatte geschrieben wurden, was jedoch nicht der Fall sein wird. Solche Fehler <code>fsync()<\/code> kommen selten vor, und die Anwendung kann in solchen Situationen kaum etwas unternehmen, um das Problem zu beheben. Heutzutage, wenn so etwas passiert, beendet PostgreSQL und andere Anwendungen die Arbeit unerwartet. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.usenix.org\/conference\/atc20\/presentation\/rebello\">Hier<\/a><\/noindex>, im Material \"K\u00f6nnen Anwendungen von fsync-Fehlern wiederherstellen?\", wird dieses Problem im Detail untersucht. Derzeit ist die beste L\u00f6sung f\u00fcr dieses Problem die Verwendung von Direct I\/O mit dem Flag <code>O_SYNC<\/code> oder mit dem Flag <code>O_DSYNC<\/code>. Bei diesem Ansatz meldet das System Fehler, die bei der Durchf\u00fchrung konkreter Schreiboperationen auftreten k\u00f6nnen, jedoch erfordert dieser Ansatz, dass die Anwendung die Puffer selbst verwaltet. Einzelheiten dazu finden Sie <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/752063\/\">hier<\/a><\/noindex> und <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Fsync_Errors\">hier<\/a><\/noindex>.<\/p>\n<h2>Die \u00d6ffnung von Dateien mit den Flags O_SYNC und O_DSYNC<\/h2>\n<p>\nKehren wir zur\u00fcck zur Diskussion \u00fcber die Mechanismen von Linux, die eine zuverl\u00e4ssige Datenspeicherung gew\u00e4hrleisten. Insbesondere geht es um die Verwendung des Flags <code>O_SYNC<\/code> oder des Flags <code>O_DSYNC<\/code> beim \u00d6ffnen von Dateien mit dem Systemaufruf <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/open.2.html\">open()<\/a><\/noindex>. Bei diesem Ansatz wird jede Schreiboperation so ausgef\u00fchrt, als ob nach jedem Befehl <code>write()<\/code> dem System entsprechende Befehle erteilt werden, <code>fsync()<\/code> und <code>fdatasync()<\/code>. In <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/009695399\/basedefs\/xbd_chap03.html#tag_03_373\">den Spezifikationen von POSIX.<\/a><\/noindex> Dies wird als \"Synchronisierte I\/O-Dateiintegrit\u00e4tsvollst\u00e4ndigung\" und \"Datenintegrit\u00e4tsvollst\u00e4ndigung\" bezeichnet. Der Hauptvorteil dieses Ansatzes besteht darin, dass zur Gew\u00e4hrleistung der Datensicherheit nur ein Systemaufruf notwendig ist, nicht zwei (zum Beispiel \u2013 <code>write()<\/code> und <code>fdatasync()<\/code>). Der Hauptnachteil dieses Ansatzes ist, dass alle Schreiboperationen, die den entsprechenden Dateideskriptor verwenden, synchronisiert werden, was die M\u00f6glichkeiten zur Strukturierung des Anwendungscodes einschr\u00e4nken kann.<\/p>\n<h2>Die Verwendung von Direct I\/O mit dem Flag O_DIRECT<\/h2>\n<p>\nSystemaufruf <code>open()<\/code> unterst\u00fctzt das Flag <code>O_DIRECT<\/code>, das dazu dient, Eingabe- und Ausgabeoperationen direkt mit der Festplatte durchzuf\u00fchren, indem der Cache des Betriebssystems umgangen wird. Dies bedeutet in vielen F\u00e4llen, dass die von der Software ausgegebenen Schreibbefehle direkt in die Befehle \u00fcbersetzt werden, die mit der Festplatte arbeiten. Im Allgemeinen ist dieser Mechanismus jedoch kein Ersatz f\u00fcr die Funktionen <code>fsync()<\/code> oder <code>fdatasync()<\/code>. Das Problem ist, dass die Festplatte selbst <noindex><a rel=\"nofollow\" href=\"https:\/\/www.evanjones.ca\/durability-nvme.html\">verschieben oder cachen<\/a><\/noindex> entsprechende Befehle zur Datenspeicherung. Und noch schlimmer, in einigen speziellen F\u00e4llen werden Ein- und Ausgabeoperationen durchgef\u00fchrt, w\u00e4hrend das Flag verwendet wird <code>O_DIRECT<\/code>, <noindex><a rel=\"nofollow\" href=\"https:\/\/ext4.wiki.kernel.org\/index.php\/Clarifying_Direct_IO%27s_Semantics\">ubertragen<\/a><\/noindex> in traditionelle gepufferte Operationen. Das Problem l\u00e4sst sich am einfachsten l\u00f6sen, indem man beim \u00d6ffnen von Dateien auch das Flag verwendet <code>O_DSYNC<\/code>, was bedeutet, dass auf jede Schreiboperation ein Aufruf folgt <code>fdatasync()<\/code>.<\/p>\n<p>Es stellte sich heraus, dass im XFS-Dateisystem k\u00fcrzlich ein \"schneller Pfad\" hinzugef\u00fcgt wurde f\u00fcr <code>O_DIRECT|O_DSYNC<\/code>-Datenspeicherung. Wenn ein Block unter Verwendung von <code>O_DIRECT|O_DSYNC<\/code>\u00fcberschrieben wird, wird XFS anstelle des Cache-Flushs den Befehl FUA-Schreibung ausf\u00fchren, sofern das Ger\u00e4t dies unterst\u00fctzt. Ich habe das selbst getestet mit dem Dienstprogramm <code>blktrace<\/code> in Linux 5.4\/Ubuntu 20.04. Dieser Ansatz sollte effizienter sein, da dabei die minimale Datenmenge auf die Festplatte geschrieben wird und zudem nur eine Operation angewendet wird und nicht zwei (Schreiben und Cache-Flush). Ich fand einen Hinweis auf <noindex><a rel=\"nofollow\" href=\"https:\/\/patchwork.kernel.org\/patch\/10250257\/\">Patch<\/a><\/noindex> den Kernel aus dem Jahr 2018, in dem dieser Mechanismus implementiert ist. Dort gibt es eine Diskussion \u00fcber die Anwendung dieser Optimierung in anderen Dateisystemen, aber soweit ich wei\u00df, ist XFS bisher das einzige Dateisystem, das dies unterst\u00fctzt.<\/p>\n<h2>Die Funktion sync_file_range()<\/h2>\n<p>\nIn Linux gibt es einen Systemaufruf <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/sync_file_range.2.html\">sync_file_range()<\/a><\/noindex>, der es erm\u00f6glicht, nur einen Teil einer Datei auf die Festplatte zu schreiben, anstatt die gesamte Datei. Dieser Aufruf initiiert einen asynchronen Daten-Flush und wartet nicht auf dessen Abschluss. Doch in der Dokumentation zu <code>sync_file_range()<\/code> wird gesagt, dass dieser Befehl \"sehr gef\u00e4hrlich\" ist. Die Nutzung wird nicht empfohlen. Die Besonderheiten und Gefahren <code>sync_file_range()<\/code> sind sehr gut beschrieben in <noindex><a rel=\"nofollow\" href=\"http:\/\/yoshinorimatsunobu.blogspot.com\/2014\/03\/how-syncfilerange-really-works.html\">das<\/a><\/noindex> dem Material. Insbesondere scheint es, dass dieser Aufruf RocksDB verwendet, um zu steuern, wann der Kernel \"verunreinigte\" Daten auf die Festplatte schreibt. Dabei wird auch <code>fdatasync()<\/code>. In <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/facebook\/rocksdb\/search?q=sync_file_range\">Eine neue SQLite-Version mit dem Patch ist bisher<\/a><\/noindex> RocksDB gibt es interessante Kommentare zu diesem Thema. Beispielsweise scheint der Aufruf <code>sync_file_range()<\/code> bei der Verwendung von ZFS nicht zu einem Flush der Daten auf die Festplatte zu f\u00fchren. Erfahrungsgem\u00e4\u00df vermute ich, dass Code, der selten verwendet wird, m\u00f6glicherweise Fehler enth\u00e4lt. Daher w\u00fcrde ich empfehlen, diesen Systemaufruf nur im \u00e4u\u00dfersten Notfall zu verwenden.<\/p>\n<h2>Systemaufrufe, die helfen, die Datenintegrit\u00e4t zu gew\u00e4hrleisten<\/h2>\n<p>\nIch komme zu dem Schluss, dass zur Durchf\u00fchrung von Ein-\/Ausgabeoperationen, die eine nachhaltige Datenspeicherung gew\u00e4hrleisten, drei Ans\u00e4tze verwendet werden k\u00f6nnen. Alle erfordern den Aufruf der Funktion <code>fsync()<\/code> f\u00fcr das Verzeichnis, in dem die Datei erstellt wurde. Hier sind die Ans\u00e4tze:<\/p>\n<ol>\n<li>Aufruf der Funktion <code>fdatasync()<\/code> oder <code>fsync()<\/code> nach der Funktion <code>write()<\/code> (es ist besser, zu verwenden <code>fdatasync()<\/code>).<\/li>\n<li>Arbeiten mit einem Dateideskriptor, der mit dem Flag ge\u00f6ffnet wurde <code>O_DSYNC<\/code> oder <code>O_SYNC<\/code> (besser \u2013 mit dem Flag <code>O_DSYNC<\/code>).<\/li>\n<li>Verwendung des Befehls <code>pwritev2()<\/code> mit dem Flag <code>RWF_DSYNC<\/code> oder <code>RWF_SYNC<\/code> (vorzugsweise \u2013 mit dem Flag <code>RWF_DSYNC<\/code>).<\/li>\n<\/ol>\n<p><\/p>\n<h2>Hinweise zur Leistung<\/h2>\n<p>\nIch habe keine gr\u00fcndlichen Leistungsmessungen der verschiedenen von mir untersuchten Mechanismen durchgef\u00fchrt. Die von mir festgestellten Geschwindigkeitsunterschiede sind ziemlich gering. Das bedeutet, dass ich mich irren kann und dass das gleiche unter anderen Bedingungen andere Ergebnisse zeigen kann. Zun\u00e4chst werde ich dar\u00fcber berichten, was sich st\u00e4rker auf die Leistung auswirkt, und dann, was sich weniger auf die Leistung auswirkt.<\/p>\n<ol>\n<li>Das \u00dcberschreiben von Dateidaten ist schneller als das Anh\u00e4ngen von Daten an die Datei (der Leistungsgewinn kann 2-100% betragen). Das Anh\u00e4ngen von Daten an die Datei erfordert zus\u00e4tzliche \u00c4nderungen an den Metadaten der Datei, selbst nach dem Systemaufruf <code>fallocate()<\/code>, aber das Ausma\u00df dieses Effekts kann variieren. Ich empfehle, um die beste Leistung zu gew\u00e4hrleisten, den Aufruf <code>fallocate()<\/code> zur Voraballokation des ben\u00f6tigten Raums. Danach muss dieser Raum explizit mit Nullen gef\u00fcllt und der Aufruf <code>fsync()<\/code>get\u00e4tigt werden. Dadurch werden die entsprechenden Bl\u00f6cke im Dateisystem als \"allokiert\" und nicht als \"nicht allokiert\" markiert. Dies f\u00fchrt zu einer geringf\u00fcgigen (circa 2%) Verbesserung der Leistung. Zudem kann bei einigen Festplatten die erste Zugriffsoperation auf einen Block langsamer sein als bei anderen. Das bedeutet, dass das F\u00fcllen des Raums mit Nullen zu einer erheblichen (circa 100%) Verbesserung der Leistung f\u00fchren kann. Dies kann insbesondere bei den Festplatten <noindex><a rel=\"nofollow\" href=\"https:\/\/n2ws.com\/blog\/how-to-guides\/pre-warm-ebs-volumes-on-aws\">AWS EBS<\/a><\/noindex> (das sind inoffizielle Daten, die ich nicht best\u00e4tigen konnte). Das Gleiche gilt f\u00fcr die Speicher <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.google.com\/compute\/docs\/disks\/benchmarking-pd-performance\">GCP Persistent Disk<\/a><\/noindex> (und das ist bereits offizielle Information, die durch Tests best\u00e4tigt wurde). Andere Spezialisten haben \u00e4hnliche <noindex><a rel=\"nofollow\" href=\"http:\/\/yoshinorimatsunobu.blogspot.com\/2009\/05\/overwriting-is-much-faster-than_28.html\">Beobachtungen<\/a><\/noindex>, die verschiedene Festplatten betreffen.<\/li>\n<li>Je weniger Systemaufrufe \u2013 desto h\u00f6her die Leistung (der Gewinn kann etwa 5% betragen). Es scheint, dass der Aufruf <code>open()<\/code> mit dem Flag <code>O_DSYNC<\/code> oder der Aufruf <code>pwritev2()<\/code> mit dem Flag <code>RWF_SYNC<\/code> schneller ist als der Aufruf <code>fdatasync()<\/code>Ich vermute, dass der Grund darin liegt, dass bei solch einem Ansatz die Anzahl der Systemaufrufe zur L\u00f6sung derselben Aufgabe reduziert werden kann (ein Aufruf statt zwei). Der Leistungsunterschied ist jedoch sehr gering, sodass Sie dies vernachl\u00e4ssigen und in der Anwendung verwenden k\u00f6nnen, was die Logik nicht zus\u00e4tzlich verkompliziert.<\/li>\n<\/ol>\n<p>\nWenn Sie sich f\u00fcr das Thema robustes Datenmanagement interessieren \u2013 hier sind einige n\u00fctzliche Materialien:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.scylladb.com\/2017\/10\/05\/io-access-methods-scylla\/\">I\/O-Zugriffsmethoden<\/a><\/noindex> \u2013 eine \u00dcbersicht der Grundlagen der Eingabe-\/Ausgabemechanismen.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/457667\/\">Sicherstellen, dass Daten die Festplatte erreichen<\/a><\/noindex> \u2013 eine Erz\u00e4hlung dar\u00fcber, was mit Daten auf dem Weg von der Anwendung zur Festplatte passiert.<\/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\">Wann sollten Sie das enthaltene Verzeichnis fsync?<\/a><\/noindex> \u2013 eine Antwort auf die Frage, wann <code>fsync()<\/code> f\u00fcr Verzeichnisse angewendet werden muss. Kurz gesagt, sollte dies beim Erstellen einer neuen Datei geschehen, und der Grund f\u00fcr diese Empfehlung ist, dass in Linux viele Verweise auf dieselbe Datei existieren k\u00f6nnen.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/bobsql.com\/sql-server-on-linux-forced-unit-access-fua-internals\/\">SQL Server auf Linux: FUA-Internas<\/a><\/noindex> \u2013 hier wird beschrieben, wie robuster Datenmanagement im SQL Server auf der Linux-Plattform umgesetzt wird. Es gibt einige interessante Vergleiche zwischen den Systemaufrufen von Windows und Linux. Ich bin mir ziemlich sicher, dass ich gerade durch dieses Material von der FUA-Optimierung von XFS erfahren habe.<\/li>\n<\/ul>\n<p>\nHaben Sie Daten verloren, die Sie f\u00fcr sicher auf der Festplatte gespeichert hielten?<\/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=\"Nachhaltige Datenspeicherung und Linux-Datei-APIs\" 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=\"Nachhaltige Datenspeicherung und Linux-Datei-APIs\" src=\"\/wp-content\/uploads\/2020\/10\/d9fd0b1c09eb6e40944aee2d13ee4088.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Quelle: <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.1.1 - 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\/de\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\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\/de\/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\udd47Robustes Datenmanagement und Dateisystem-APIs f\u00fcr Linux | ProHoster","description":"Ich habe die Robustheit der Datenspeicherung in Cloud-Systemen untersucht und m\u00f6chte mich selbst auf die Probe stellen, um sicherzustellen, dass ich die grundlegenden Aspekte verstehe.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","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\/de\/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\/de\/wp-json\/wp\/v2\/posts\/98090","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=98090"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/98090\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/98091"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=98090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=98090"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=98090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}