{"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\/fr\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","title":{"rendered":"Stockage durable des donn\u00e9es et API de fichiers Linux","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>En explorant la durabilit\u00e9 du stockage de donn\u00e9es dans les syst\u00e8mes cloud, j'ai d\u00e9cid\u00e9 de me tester, pour m'assurer que je comprends les \u00e9l\u00e9ments de base. Je <noindex><a rel=\"nofollow\" href=\"https:\/\/www.evanjones.ca\/durability-nvme.html\">ai commenc\u00e9 par lire la sp\u00e9cification NVMe<\/a><\/noindex> pour comprendre quelles garanties relatives \u00e0 la durabilit\u00e9 du stockage de donn\u00e9es (c'est-\u00e0-dire, la garantie que les donn\u00e9es seront disponibles apr\u00e8s une panne syst\u00e8me) nous fournissent les disques NVMe. J'ai tir\u00e9 les principales conclusions suivantes : il faut consid\u00e9rer les donn\u00e9es comme endommag\u00e9es \u00e0 partir du moment o\u00f9 la commande d'\u00e9criture des donn\u00e9es est donn\u00e9e, et jusqu'\u00e0 ce que leur \u00e9criture sur le support d'information soit termin\u00e9e. Cependant, dans la plupart des programmes d'\u00e9criture de donn\u00e9es, les appels syst\u00e8mes sont utilis\u00e9s sans aucune pr\u00e9caution.<\/p>\n<p>Dans ce document, j'explore les m\u00e9canismes de durabilit\u00e9 du stockage de donn\u00e9es fournis par les API de fichiers Linux. Il semble que tout cela devrait \u00eatre simple : le programme appelle la commande <code>write()<\/code>, et apr\u00e8s que cette commande soit termin\u00e9e, les donn\u00e9es doivent \u00eatre enregistr\u00e9es de mani\u00e8re fiable sur le disque. Mais <code>write()<\/code> elle ne fait que copier les donn\u00e9es de l'application dans le cache du noyau, situ\u00e9 en m\u00e9moire vive. Pour forcer le syst\u00e8me \u00e0 \u00e9crire les donn\u00e9es sur le disque, il faut utiliser certains m\u00e9canismes suppl\u00e9mentaires.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/524172\/\"><img decoding=\"async\" alt=\"Stockage durable des donn\u00e9es et API de fichiers Linux\" src=\"\/wp-content\/uploads\/2020\/10\/b974dcb9fc546cae03ade4f3d8f5dc25.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>Dans l'ensemble, ce document est un ensemble de notes sur ce que j'ai appris sur le sujet qui m'int\u00e9resse. Pour r\u00e9sumer tr\u00e8s bri\u00e8vement l'essentiel, il en ressort que pour organiser un stockage de donn\u00e9es durable, il faut utiliser la commande <code>fdatasync()<\/code> ou ouvrir les fichiers avec le drapeau <code>O_DSYNC<\/code>. Si vous \u00eates int\u00e9ress\u00e9 \u00e0 en savoir plus sur ce qui se passe avec les donn\u00e9es lors de leur passage du code \u00e0 disque, jetez un coup d'\u0153il \u00e0 <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/457667\/\">cet<\/a><\/noindex> article.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Les caract\u00e9ristiques de l'utilisation de la fonction write()<\/h2>\n<p>\nAppel syst\u00e8me <code>write()<\/code> sont d\u00e9finies dans la norme <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/POSIX\">IEEE POSIX<\/a><\/noindex> comme une tentative d'\u00e9criture de donn\u00e9es dans un descripteur de fichier. Apr\u00e8s la r\u00e9ussite de l'op\u00e9ration, <code>write()<\/code> les op\u00e9rations de lecture de donn\u00e9es doivent renvoyer exactement les octets qui ont \u00e9t\u00e9 pr\u00e9c\u00e9demment \u00e9crits, m\u00eame si les donn\u00e9es sont acc\u00e9d\u00e9es depuis d'autres processus ou threads (<noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/functions\/write.html#tag_16_685_08\">voici<\/a><\/noindex> section correspondante de la norme POSIX). <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/functions\/V2_chap02.html#tag_15_09_07\">Ici<\/a><\/noindex>, dans la section consacr\u00e9e \u00e0 l'interaction des flux avec les op\u00e9rations de fichiers courantes, il est not\u00e9 que si chacun des deux flux appelle ces fonctions, chaque appel doit soit voir toutes les cons\u00e9quences d\u00e9sign\u00e9es r\u00e9sultant de l'ex\u00e9cution de l'autre appel, soit ne voir aucune cons\u00e9quence. Cela permet de conclure que toutes les op\u00e9rations d'entr\u00e9e\/sortie sur les fichiers doivent maintenir un verrou sur la ressource avec laquelle elles travaillent.<\/p>\n<p>Cela signifie-t-il que l'op\u00e9ration <code>write()<\/code> est atomique? D'un point de vue technique - oui. Les op\u00e9rations de lecture de donn\u00e9es doivent retourner soit tout, soit rien de ce qui a \u00e9t\u00e9 \u00e9crit via <code>write()<\/code>. Mais l'op\u00e9ration <code>write()<\/code>, conform\u00e9ment \u00e0 la norme, n'est pas n\u00e9cessairement tenue de se terminer en \u00e9crivant tout ce qui lui a \u00e9t\u00e9 propos\u00e9 d'\u00e9crire. Elle est autoris\u00e9e \u00e0 \u00e9crire seulement une partie des donn\u00e9es. Par exemple, nous pourrions avoir deux flux, chacun ajoutant 1024 octets \u00e0 un fichier d\u00e9crit par le m\u00eame descripteur de fichier. D'un point de vue normatif, un r\u00e9sultat o\u00f9 chacune des op\u00e9rations d'\u00e9criture parvient \u00e0 ajouter au fichier seulement un octet serait acceptable. Ces op\u00e9rations resteront atomiques, mais une fois termin\u00e9es, les donn\u00e9es qu'elles auront \u00e9crites dans le fichier seront m\u00e9lang\u00e9es. <noindex><a rel=\"nofollow\" href=\"https:\/\/stackoverflow.com\/a\/42442926\/413438\">Voici<\/a><\/noindex> il y a une discussion tr\u00e8s int\u00e9ressante \u00e0 ce sujet sur Stack Overflow.<\/p>\n<h2>Les fonctions fsync() et fdatasync()<\/h2>\n<p>\nLe moyen le plus simple de forcer les donn\u00e9es sur le disque est d'appeler la fonction <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/fsync.2.html\">fsync()<\/a><\/noindex>. Cette fonction demande au syst\u00e8me d'exploitation de transf\u00e9rer tous les blocs modifi\u00e9s du cache vers le disque. Cela inclut \u00e9galement tous les m\u00e9tadonn\u00e9es du fichier (heure d'acc\u00e8s, heure de modification du fichier, etc.). Je pense que le besoin de ces m\u00e9tadonn\u00e9es se produit rarement, donc si vous savez qu'elles ne sont pas essentielles pour vous, vous pouvez utiliser la fonction <code>fdatasync()<\/code>. Il y a <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/fdatasync.2.html\">aide<\/a><\/noindex> pour <code>fdatasync()<\/code> indique que lors de l'ex\u00e9cution de cette fonction, un volume de m\u00e9tadonn\u00e9es est sauvegard\u00e9 sur le disque, qui est \"n\u00e9cessaire pour l'ex\u00e9cution correcte des op\u00e9rations suivantes de lecture de donn\u00e9es\". Et c'est pr\u00e9cis\u00e9ment ce qui pr\u00e9occupe la plupart des applications.<\/p>\n<p>Un des probl\u00e8mes qui peuvent survenir ici est que ces m\u00e9canismes ne garantissent pas que le fichier sera d\u00e9tectable apr\u00e8s un \u00e9ventuel \u00e9chec. En particulier, lorsque vous cr\u00e9ez un nouveau fichier, il est n\u00e9cessaire d'appeler <code>fsync()<\/code> pour le r\u00e9pertoire qui le contient. Sinon, apr\u00e8s un crash, il se peut que ce fichier n'existe plus. La raison en est qu'en UNIX, en raison de l'utilisation de liens durs, un fichier peut exister dans plusieurs r\u00e9pertoires. Par cons\u00e9quent, lors de l'appel <code>fsync()<\/code> il n'y a aucun moyen de savoir pour quel r\u00e9pertoire les donn\u00e9es doivent \u00e9galement \u00eatre \u00e9crites sur disque (<noindex><a rel=\"nofollow\" href=\"https:\/\/www.quora.com\/When-should-you-fsync-the-containing-directory-in-addition-to-the-file-itself\">ici<\/a><\/noindex> on peut en lire plus en d\u00e9tail). Il semble que le syst\u00e8me de fichiers ext4 soit capable <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/799807\/\">d'appliquer automatiquement<\/a><\/noindex> \u00e0 des r\u00e9pertoires contenant les fichiers correspondants, mais dans le cas d'autres syst\u00e8mes de fichiers, cela peut ne pas \u00eatre le cas. <code>fsync()<\/code> Ce m\u00e9canisme peut \u00eatre impl\u00e9ment\u00e9 diff\u00e9remment dans divers syst\u00e8mes de fichiers. J'ai utilis\u00e9<\/p>\n<p>pour comprendre quelles op\u00e9rations de disque sont utilis\u00e9es dans les syst\u00e8mes de fichiers ext4 et XFS. Les deux produisent des commandes d'\u00e9criture sur disque habituelles, tant pour le contenu des fichiers que pour le journal du syst\u00e8me de fichiers, qui vidangent le cache et terminent le travail en ex\u00e9cutant une \u00e9criture FUA (Force Unit Access, \u00e9criture des donn\u00e9es directement sur le disque, contournant le cache) dans le journal. Il est probable qu'ils agissent ainsi pour confirmer le fait de l'op\u00e9ration. Sur les disques qui ne prennent pas en charge FUA, cela entra\u00eene deux vidanges de cache. Mes exp\u00e9riences ont montr\u00e9 que <noindex><a rel=\"nofollow\" href=\"https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/axboe\/blktrace.git\/tree\/README\">blktrace<\/a><\/noindex> un peu plus rapide <code>fdatasync()<\/code> . L'utilitaire <code>fsync()<\/code>indique que <code>blktrace<\/code> \u00e9crit g\u00e9n\u00e9ralement moins de donn\u00e9es sur le disque (dans ext4 <code>fdatasync()<\/code> \u00e9crit 20 Ko, tandis que <code>fsync()<\/code> \u2014 \u00e9crit 16 Ko). De plus, j'ai d\u00e9couvert que XFS est l\u00e9g\u00e8rement plus rapide qu'ext4. Et ici, avec l'aide de <code>fdatasync()<\/code> j'ai pu d\u00e9terminer que <code>blktrace<\/code> vidange moins de donn\u00e9es sur le disque (4 Ko dans XFS). <code>fdatasync()<\/code> Situations ambigu\u00ebs qui surviennent lors de l'utilisation de fsync()<\/p>\n<h2>Je peux me souvenir de trois situations ambigu\u00ebs concernant<\/h2>\n<p>\n, auxquelles j'ai \u00e9t\u00e9 confront\u00e9 dans la pratique. <code>fsync()<\/code>Le premier de ces cas s'est produit en 2008. \u00c0 l'\u00e9poque, l'interface de Firefox 3 \u00ab gelait \u00bb lorsque de nombreux fichiers \u00e9taient \u00e9crits sur disque. Le probl\u00e8me \u00e9tait que, dans la mise en \u0153uvre de l'interface, une base de donn\u00e9es SQLite \u00e9tait utilis\u00e9e pour stocker les informations sur son \u00e9tat. Apr\u00e8s chaque modification survenue dans l'interface, la fonction<\/p>\n<p>, qui garantissait un bon stockage des donn\u00e9es, \u00e9tait appel\u00e9e. Dans le syst\u00e8me de fichiers ext3 utilis\u00e9 alors, la fonction <code>fsync()<\/code>, ce qui offrait de bonnes garanties de stockage durable des donn\u00e9es. Dans le syst\u00e8me de fichiers ext3 utilis\u00e9 \u00e0 l'\u00e9poque, la fonction <code>fsync()<\/code> elle enregistrait toutes les \u00ab pages sales \u00bb dans le syst\u00e8me sur le disque, et pas seulement celles qui \u00e9taient li\u00e9es au fichier concern\u00e9. Cela signifiait qu'un clic sur un bouton dans Firefox pouvait d\u00e9clencher l'\u00e9criture de plusieurs m\u00e9gaoctets de donn\u00e9es sur le disque magn\u00e9tique, ce qui pouvait prendre plusieurs secondes. La solution \u00e0 ce probl\u00e8me, comme je l'ai compris de <noindex><a rel=\"nofollow\" href=\"http:\/\/shaver.off.net\/diary\/2008\/05\/25\/fsyncers-and-curveballs\/\">ce fichier) :<\/a><\/noindex> le mat\u00e9riel, consistait \u00e0 d\u00e9placer le travail de la base de donn\u00e9es vers des t\u00e2ches de fond asynchrones. Cela signifie qu'auparavant, Firefox appliquait des exigences beaucoup plus strictes en mati\u00e8re de durabilit\u00e9 du stockage des donn\u00e9es, que cela n'\u00e9tait r\u00e9ellement n\u00e9cessaire, et que les particularit\u00e9s du syst\u00e8me de fichiers ext3 aggravaient ce probl\u00e8me.<\/p>\n<p>La deuxi\u00e8me incoh\u00e9rence est survenue en 2009. \u00c0 l'\u00e9poque, apr\u00e8s une d\u00e9faillance du syst\u00e8me, les utilisateurs du nouveau syst\u00e8me de fichiers ext4 ont constat\u00e9 que de nombreux fichiers r\u00e9cemment cr\u00e9\u00e9s avaient une longueur nulle, tandis qu'avec l'ancien syst\u00e8me de fichiers ext3, cela ne se produisait pas. Dans le paragraphe pr\u00e9c\u00e9dent, je parlais du fait qu'ext3 enregistrait trop de donn\u00e9es sur le disque, ce qui ralentissait consid\u00e9rablement le syst\u00e8me <code>fsync()<\/code>. Afin d'am\u00e9liorer la situation, ext4 n'enregistre sur le disque que les \u00ab pages sales \u00bb qui sont li\u00e9es \u00e0 un fichier sp\u00e9cifique. Les donn\u00e9es des autres fichiers restent en m\u00e9moire beaucoup plus longtemps qu'avec ext3. Cela a \u00e9t\u00e9 fait pour am\u00e9liorer les performances (par d\u00e9faut, les donn\u00e9es restent dans cet \u00e9tat pendant 30 secondes, ce qui peut \u00eatre ajust\u00e9 \u00e0 l'aide de <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\">ici<\/a><\/noindex> , des ressources suppl\u00e9mentaires peuvent \u00eatre trouv\u00e9es \u00e0 ce sujet). Cela signifie qu'un grand volume de donn\u00e9es peut \u00eatre irr\u00e9m\u00e9diablement perdu apr\u00e8s une d\u00e9faillance. La solution \u00e0 ce probl\u00e8me consiste \u00e0 utiliser <code>fsync()<\/code> dans les applications n\u00e9cessitant une durabilit\u00e9 des donn\u00e9es et maximisant leur protection contre les cons\u00e9quences des d\u00e9faillances. La fonction <code>fsync()<\/code> fonctionne sous ext4 de mani\u00e8re beaucoup plus efficace que sous ext3. L'inconv\u00e9nient de cette approche est qu'elle ralentit, comme auparavant, l'ex\u00e9cution de certaines op\u00e9rations, comme l'installation de programmes. Pour les d\u00e9tails, veuillez consulter <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/322823\/\">ici<\/a><\/noindex> et <noindex><a rel=\"nofollow\" href=\"https:\/\/thunk.org\/tytso\/blog\/2009\/03\/12\/delayed-allocation-and-the-zero-length-file-problem\/\">ici<\/a><\/noindex>.<\/p>\n<p>Le troisi\u00e8me probl\u00e8me relatif <code>fsync()<\/code>, est survenu en 2018. \u00c0 cette \u00e9poque, dans le cadre du projet PostgreSQL, il a \u00e9t\u00e9 constat\u00e9 que si la fonction <code>fsync()<\/code> rencontraient une erreur, elles marquaient les \u00ab pages sales \u00bb comme \u00ab propres \u00bb. En cons\u00e9quence, les appels suivants <code>fsync()<\/code> Rien n'est fait avec de telles pages. En raison de cela, les pages modifi\u00e9es sont stock\u00e9es en m\u00e9moire et ne sont jamais \u00e9crites sur le disque. C'est une v\u00e9ritable catastrophe, car l'application croira que certaines donn\u00e9es sont enregistr\u00e9es sur le disque, alors qu'en r\u00e9alit\u00e9 ce n'est pas le cas. De tels \u00e9checs <code>fsync()<\/code> sont rares, l'application dans de telles situations peut \u00e0 peine faire quelque chose pour lutter contre le probl\u00e8me. De nos jours, lorsque cela se produit, PostgreSQL et d'autres applications se terminent de mani\u00e8re inattendue. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.usenix.org\/conference\/atc20\/presentation\/rebello\">Ici<\/a><\/noindex>, dans le mat\u00e9riel \u00ab Les applications peuvent-elles r\u00e9cup\u00e9rer apr\u00e8s des \u00e9checs d'fsync ? \u00bb, ce probl\u00e8me est explor\u00e9 dans tous les d\u00e9tails. Actuellement, la meilleure solution \u00e0 ce probl\u00e8me est d'utiliser Direct I\/O avec le drapeau <code>O_SYNC<\/code> ou avec le drapeau <code>O_DSYNC<\/code>. Avec cette approche, le syst\u00e8me signalera les erreurs qui peuvent survenir lors de l'ex\u00e9cution de certaines op\u00e9rations d'\u00e9criture de donn\u00e9es, mais cela n\u00e9cessite que l'application g\u00e8re les tampons par elle-m\u00eame. Pour plus de d\u00e9tails, lisez <noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/752063\/\">ici<\/a><\/noindex> et <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Fsync_Errors\">ici<\/a><\/noindex>.<\/p>\n<h2>L'ouverture de fichiers avec les drapeaux O_SYNC et O_DSYNC<\/h2>\n<p>\nRevenons \u00e0 la discussion sur les m\u00e9canismes Linux garantissant la conservation des donn\u00e9es. En effet, il s'agit de l'utilisation du drapeau <code>O_SYNC<\/code> ou du drapeau <code>O_DSYNC<\/code> lors de l'ouverture de fichiers \u00e0 l'aide de l'appel syst\u00e8me <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/open.2.html\">open()<\/a><\/noindex>. Avec cette approche, chaque op\u00e9ration d'\u00e9criture de donn\u00e9es est effectu\u00e9e comme si apr\u00e8s chaque commande <code>write()<\/code> le syst\u00e8me recevait, respectivement, les commandes <code>fsync()<\/code> et <code>fdatasync()<\/code>. Il y a <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/009695399\/basedefs\/xbd_chap03.html#tag_03_373\">de la sp\u00e9cification POSIX.<\/a><\/noindex> Ceci est appel\u00e9 \u00ab Compl\u00e9tion des int\u00e9grit\u00e9s de fichier d'E\/S synchronis\u00e9es \u00bb et \u00ab Compl\u00e9tion de l'int\u00e9grit\u00e9 des donn\u00e9es \u00bb. L'avantage principal de cette approche est que pour garantir l'int\u00e9grit\u00e9 des donn\u00e9es, il ne faut effectuer qu'un seul appel syst\u00e8me, et non deux (par exemple \u2014 <code>write()<\/code> et <code>fdatasync()<\/code>). Le principal inconv\u00e9nient de cette approche est que toutes les op\u00e9rations d'\u00e9criture utilisant le descripteur de fichier correspondant seront synchronis\u00e9es, ce qui peut limiter les possibilit\u00e9s de structuration du code de l'application.<\/p>\n<h2>L'utilisation de Direct I\/O avec le drapeau O_DIRECT<\/h2>\n<p>\nAppel syst\u00e8me <code>open()<\/code> soutient le drapeau <code>O_DIRECT<\/code>, qui est con\u00e7u pour effectuer des op\u00e9rations d'entr\u00e9e\/sortie en contournant le cache du syst\u00e8me d'exploitation, interagissant directement avec le disque. Cela signifie, dans de nombreux cas, que les commandes d'\u00e9criture \u00e9mises par le programme seront directement traduites en commandes destin\u00e9es \u00e0 travailler avec le disque. Mais en g\u00e9n\u00e9ral, ce m\u00e9canisme n'est pas un remplacement des fonctionnalit\u00e9s <code>fsync()<\/code> ou <code>fdatasync()<\/code>. En effet, le disque lui-m\u00eame peut <noindex><a rel=\"nofollow\" href=\"https:\/\/www.evanjones.ca\/durability-nvme.html\">retarder ou mettre en cache<\/a><\/noindex> les commandes d'enregistrement de donn\u00e9es appropri\u00e9es. Et, ce qui est pire, dans certains cas particuliers, les op\u00e9rations d'entr\u00e9e-sortie effectu\u00e9es en utilisant le drapeau <code>O_DIRECT<\/code>, <noindex><a rel=\"nofollow\" href=\"https:\/\/ext4.wiki.kernel.org\/index.php\/Clarifying_Direct_IO%27s_Semantics\">sont transmises<\/a><\/noindex> en op\u00e9rations tampons traditionnelles. Le moyen le plus simple de r\u00e9soudre ce probl\u00e8me est d'ouvrir les fichiers avec le drapeau <code>O_DSYNC<\/code>, ce qui signifie qu'apr\u00e8s chaque op\u00e9ration d'\u00e9criture, un appel sera effectu\u00e9 <code>fdatasync()<\/code>.<\/p>\n<p>Il s'av\u00e8re qu'un \u00ab chemin rapide \u00bb a r\u00e9cemment \u00e9t\u00e9 ajout\u00e9 dans le syst\u00e8me de fichiers XFS pour <code>O_DIRECT|O_DSYNC<\/code>-l'\u00e9criture des donn\u00e9es. Si un bloc est r\u00e9\u00e9crit en utilisant <code>O_DIRECT|O_DSYNC<\/code>, alors XFS, au lieu de vider le cache, ex\u00e9cutera la commande d'\u00e9criture FUA si le p\u00e9riph\u00e9rique le prend en charge. Je m'en suis assur\u00e9 en utilisant l'outil <code>blktrace<\/code> dans le syst\u00e8me Linux 5.4\/Ubuntu 20.04. Cette approche devrait \u00eatre plus efficace, car elle \u00e9crit un minimum de donn\u00e9es sur le disque et utilise une seule op\u00e9ration au lieu de deux (\u00e9criture et vidage du cache). J'ai trouv\u00e9 un lien vers <noindex><a rel=\"nofollow\" href=\"https:\/\/patchwork.kernel.org\/patch\/10250257\/\">un patch<\/a><\/noindex> un noyau de 2018 dans lequel ce m\u00e9canisme a \u00e9t\u00e9 impl\u00e9ment\u00e9. Il y a une discussion concernant l'utilisation de cette optimisation dans d'autres syst\u00e8mes de fichiers, mais, autant que je sache, XFS est le seul syst\u00e8me de fichiers qui le prend en charge pour le moment.<\/p>\n<h2>La fonction sync_file_range()<\/h2>\n<p>\nDans Linux, il existe un appel syst\u00e8me <noindex><a rel=\"nofollow\" href=\"https:\/\/man7.org\/linux\/man-pages\/man2\/sync_file_range.2.html\">sync_file_range()<\/a><\/noindex>, qui permet de vider vers le disque seulement une partie du fichier, au lieu de tout le fichier. Cet appel initie une vidange asynchrone des donn\u00e9es et n'attend pas sa fin. Mais dans la documentation de <code>sync_file_range()<\/code> il est dit que cette commande est \u00ab tr\u00e8s dangereuse \u00bb. Son utilisation n'est pas recommand\u00e9e. Les particularit\u00e9s et dangers <code>sync_file_range()<\/code> sont tr\u00e8s bien d\u00e9crits dans <noindex><a rel=\"nofollow\" href=\"http:\/\/yoshinorimatsunobu.blogspot.com\/2014\/03\/how-syncfilerange-really-works.html\">ce<\/a><\/noindex> mat\u00e9riau. En particulier, apparemment, cet appel utilise RocksDB pour g\u00e9rer quand le noyau vide les donn\u00e9es \u00ab sales \u00bb sur le disque. Mais l\u00e0, pour garantir un stockage persistant des donn\u00e9es, il utilise aussi <code>fdatasync()<\/code>. Il y a <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/facebook\/rocksdb\/search?q=sync_file_range\">le code<\/a><\/noindex> RocksDB a des commentaires int\u00e9ressants \u00e0 ce sujet. Par exemple, il semble que l'appel <code>sync_file_range()<\/code> lors de l'utilisation de ZFS ne m\u00e8ne pas \u00e0 une vidange des donn\u00e9es sur le disque. L'exp\u00e9rience me dit que le code utilis\u00e9 rarement contient peut-\u00eatre des erreurs. Je conseillerais donc de ne pas utiliser cet appel syst\u00e8me sans n\u00e9cessit\u00e9 absolue.<\/p>\n<h2>Appels syst\u00e8me qui aident \u00e0 garantir un stockage persistant des donn\u00e9es<\/h2>\n<p>\nJe suis arriv\u00e9 \u00e0 la conclusion qu'il existe trois approches pour effectuer des op\u00e9rations d'entr\u00e9e\/sortie qui garantissent un stockage durable des donn\u00e9es. Chacune d'elles n\u00e9cessite d'appeler une fonction <code>fsync()<\/code> dans le r\u00e9pertoire o\u00f9 le fichier a \u00e9t\u00e9 cr\u00e9\u00e9. Voici ces approches :<\/p>\n<ol>\n<li>L'appel de la fonction <code>fdatasync()<\/code> ou <code>fsync()<\/code> apr\u00e8s la fonction <code>write()<\/code> (il est pr\u00e9f\u00e9rable d'utiliser <code>fdatasync()<\/code>).<\/li>\n<li>Le travail avec un descripteur de fichier ouvert avec le drapeau <code>O_DSYNC<\/code> ou <code>O_SYNC<\/code> (id\u00e9alement \u2014 avec le drapeau <code>O_DSYNC<\/code>).<\/li>\n<li>L'utilisation de la commande <code>pwritev2()<\/code> avec le drapeau <code>RWF_DSYNC<\/code> ou <code>RWF_SYNC<\/code> (pr\u00e9f\u00e9rable \u2014 avec le drapeau <code>RWF_DSYNC<\/code>).<\/li>\n<\/ol>\n<p><\/p>\n<h2>Notes sur les performances<\/h2>\n<p>\nJe n'ai pas effectu\u00e9 de mesurages pr\u00e9cis des performances des diff\u00e9rents m\u00e9canismes que j'ai examin\u00e9s. Les diff\u00e9rences de vitesse que j'ai remarqu\u00e9es sont assez peu significatives. Cela signifie que je peux me tromper, et que d'autres conditions pourraient donner des r\u00e9sultats diff\u00e9rents. D'abord, je parlerai de ce qui a le plus d'impact sur les performances, puis de ce qui en a moins.<\/p>\n<ol>\n<li>La r\u00e9\u00e9criture des donn\u00e9es d'un fichier est plus rapide que l'ajout de donn\u00e9es \u00e0 un fichier (le gain de performance peut aller de 2 \u00e0 100 %). L'ajout de donn\u00e9es \u00e0 un fichier n\u00e9cessite des modifications suppl\u00e9mentaires des m\u00e9tadonn\u00e9es du fichier, m\u00eame apr\u00e8s l'appel syst\u00e8me <code>fallocate()<\/code>, mais l'ampleur de cet effet peut varier. Je recommande, pour garantir la meilleure performance, d'appeler <code>fallocate()<\/code> pour r\u00e9server l'espace n\u00e9cessaire. Ensuite, cet espace doit \u00eatre explicitement rempli de z\u00e9ros et appeler <code>fsync()<\/code>. Cela permet aux blocs appropri\u00e9s dans le syst\u00e8me de fichiers d'\u00eatre marqu\u00e9s comme \"r\u00e9serv\u00e9s\", plut\u00f4t que comme \"non r\u00e9serv\u00e9s\". Cela donne une l\u00e9g\u00e8re am\u00e9lioration de la performance (environ 2 %). De plus, sur certains disques, la premi\u00e8re op\u00e9ration d'acc\u00e8s \u00e0 un bloc peut prendre plus de temps que les autres. Cela signifie que le remplissage de l'espace avec des z\u00e9ros peut entra\u00eener une am\u00e9lioration significative des performances (environ 100 %). En particulier, cela peut se produire avec les disques <noindex><a rel=\"nofollow\" href=\"https:\/\/n2ws.com\/blog\/how-to-guides\/pre-warm-ebs-volumes-on-aws\">AWS EBS<\/a><\/noindex> (ce sont des donn\u00e9es non officielles, je n'ai pas pu les confirmer). Il en va de m\u00eame pour les stockages <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.google.com\/compute\/docs\/disks\/benchmarking-pd-performance\">GCP Persistent Disk<\/a><\/noindex> (et cela, c'est d\u00e9j\u00e0 une information officielle, confirm\u00e9e par des tests). D'autres sp\u00e9cialistes ont fait des <noindex><a rel=\"nofollow\" href=\"http:\/\/yoshinorimatsunobu.blogspot.com\/2009\/05\/overwriting-is-much-faster-than_28.html\">observations similaires<\/a><\/noindex>, concernant diff\u00e9rents disques.<\/li>\n<li>Moins il y a d'appels syst\u00e8me, plus la performance est \u00e9lev\u00e9e (le gain peut \u00eatre d'environ 5 %). Il semble que l'appel <code>open()<\/code> avec le drapeau <code>O_DSYNC<\/code> ou l'appel <code>pwritev2()<\/code> avec le drapeau <code>RWF_SYNC<\/code> appel plus rapide <code>fdatasync()<\/code>. Je soup\u00e7onne que cela est d\u00fb au fait qu'avec cette approche, le nombre d'appels syst\u00e8me n\u00e9cessaires pour r\u00e9soudre la m\u00eame t\u00e2che est r\u00e9duit (un appel au lieu de deux). Mais la diff\u00e9rence de performance est tr\u00e8s faible, donc vous pouvez tout \u00e0 fait l'ignorer et utiliser dans l'application ce qui ne compliquera pas sa logique.<\/li>\n<\/ol>\n<p>\nSi le sujet du stockage durable des donn\u00e9es vous int\u00e9resse, voici quelques ressources utiles :<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.scylladb.com\/2017\/10\/05\/io-access-methods-scylla\/\">M\u00e9thodes d'acc\u00e8s I\/O<\/a><\/noindex> \u2014 un aper\u00e7u des principes de base des m\u00e9canismes d'entr\u00e9e\/sortie.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/457667\/\">Assurer que les donn\u00e9es atteignent le disque<\/a><\/noindex> \u2014 une discussion sur ce qui arrive aux donn\u00e9es entre l'application et le disque.<\/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\">Quand devez-vous fsync le r\u00e9pertoire contenant<\/a><\/noindex> \u2014 une r\u00e9ponse \u00e0 la question de quand il est n\u00e9cessaire d'appliquer <code>fsync()<\/code> pour les r\u00e9pertoires. En r\u00e9sum\u00e9, il est conseill\u00e9 de le faire lors de la cr\u00e9ation d'un nouveau fichier, la raison \u00e9tant qu'il peut y avoir plusieurs liens vers le m\u00eame fichier sous Linux.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/bobsql.com\/sql-server-on-linux-forced-unit-access-fua-internals\/\">SQL Server sur Linux : internes de FUA<\/a><\/noindex> \u2014 ici, vous trouverez une description de la mani\u00e8re dont le stockage durable des donn\u00e9es est impl\u00e9ment\u00e9 dans SQL Server sur la plateforme Linux. Il y a quelques comparaisons int\u00e9ressantes entre les appels syst\u00e8me de Windows et de Linux. Je suis presque s\u00fbr que c'est gr\u00e2ce \u00e0 ce document que j'ai appris l'optimisation FUA d'XFS.<\/li>\n<\/ul>\n<p>\nAvez-vous d\u00e9j\u00e0 perdu des donn\u00e9es que vous pensiez \u00eatre en s\u00e9curit\u00e9 sur le disque ?<\/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=\"Stockage durable des donn\u00e9es et API de fichiers 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=\"Stockage durable des donn\u00e9es et API de fichiers Linux\" src=\"\/wp-content\/uploads\/2020\/10\/d9fd0b1c09eb6e40944aee2d13ee4088.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Source : <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.2 - 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\/fr\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\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\/fr\/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\udd47Stockage durable des donn\u00e9es et API de fichiers Linux | ProHoster","description":"En explorant la robustesse du stockage des donn\u00e9es dans les syst\u00e8mes cloud, j'ai d\u00e9cid\u00e9 de me tester, de m'assurer que je comprends les concepts fondamentaux.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/ustojchivoe-hranenie-dannyh-i-fajlovye-api-linux","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","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\/fr\/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\/fr\/wp-json\/wp\/v2\/posts\/98090","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=98090"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/98090\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/98091"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=98090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=98090"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=98090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}