Sous Linux, l’exécution d’une commande telle que cp
ou dd
ne signifie pas que les données ont été écrites sur le périphérique. Par exemple, vous devez appeler sync
ou appeler la fonction "Supprimer en toute sécurité" ou "Éjecter" sur le lecteur.
Quelle est la philosophie derrière une telle approche? Pourquoi les données ne sont-elles pas écrites en même temps? N'y a-t-il pas de risque d'échec de l'écriture à cause d'une erreur d'E / S?
kernel
drivers
io
unix-philosophy
Marmistrz
la source
la source
Réponses:
Efficacité (meilleure utilisation des caractéristiques du disque) et performances (permettent à l'application de continuer immédiatement après une écriture).
Le principal avantage est que le système d'exploitation est libre de réorganiser et de fusionner des opérations d'écriture contiguës pour améliorer l'utilisation de la bande passante (moins d'opérations et moins de recherches). Les disques durs fonctionnent mieux lorsqu'un petit nombre d'opérations importantes sont demandées, alors que les applications nécessitent généralement un grand nombre d'opérations de petite taille. Une autre optimisation évidente est que le système d'exploitation peut également supprimer toutes les écritures sauf la dernière lorsque le même bloc est écrit plusieurs fois sur une courte période, ou même supprimer certaines écritures si le fichier affecté a été supprimé entre-temps.
Ces écritures asynchrones sont effectuées après le retour de l'
write
appel système. C'est le deuxième et le plus visible avantage utilisateur. Les écritures asynchrones accélèrent les applications car elles sont libres de continuer leur travail sans attendre que les données soient réellement sur le disque. Le même type de mise en mémoire tampon / mise en cache est également mis en œuvre pour les opérations de lecture où des blocs récemment ou souvent lus sont conservés en mémoire au lieu d'être lus à nouveau sur le disque.Pas nécessairement. Cela dépend du système de fichiers utilisé et de la redondance en place. Une erreur d'E / S peut être sans danger si les données peuvent être sauvegardées ailleurs. Les systèmes de fichiers modernes tels que ZFS corrigent automatiquement les mauvais blocs de disque. Notez également que les erreurs d'E / S ne font pas planter les systèmes d'exploitation modernes. S'ils se produisent lors de l'accès aux données, ils sont simplement signalés à l'application concernée. S'ils se produisent lors de l'accès à des métadonnées structurelles et mettent le système de fichiers en péril, il peut être remonté en lecture seule ou rendu inaccessible.
Il existe également un léger risque de perte de données en cas de panne du système d'exploitation, de panne de courant ou de défaillance matérielle. C'est la raison pour laquelle les applications qui doivent être 100% sûres que les données sont sur disque (bases de données / applications financières, par exemple) font des écritures synchrones moins efficaces mais plus sécurisées. Pour limiter l'impact sur les performances, de nombreuses applications utilisent encore les écritures asynchrones mais les synchronisent éventuellement lorsque l'utilisateur enregistre explicitement un fichier (par exemple, vim, traitement de texte).
Par ailleurs, une très grande majorité des utilisateurs et des applications n’ont pas besoin de la sécurité que procurent les écritures synchrones. En cas d'accident ou de panne de courant, le seul risque est souvent de perdre au pire les 30 dernières secondes de données. À moins d'une transaction financière ou de quelque chose de similaire qui impliquerait un coût bien supérieur à 30 secondes, l'énorme gain de performance (qui n'est pas une illusion, mais bien réel), les écritures asynchrones permettent une surperformance substantielle du risque.
Enfin, les écritures synchrones ne suffisent pas pour protéger les données écrites. Si votre application a vraiment besoin de s’assurer que ses données ne peuvent pas être perdues quoi qu’il se produise, la réplication de données sur plusieurs disques et sur plusieurs emplacements géographiques doit être mise en place pour résister aux catastrophes telles que les incendies, les inondations, etc.
la source
Cela donne simplement une illusion de vitesse aux programmes qui n'ont pas à attendre la fin de l'écriture. Montez vos systèmes de fichiers en mode synchronisation (ce qui vous donne vos écritures instantanées) et voyez à quel point tout est lent.
Parfois, les fichiers n'existent que temporairement ... un programme effectue un peu de travail et supprime le fichier juste après le travail. Si vous retardez ces écrits, vous pourriez vous en tirer en ne les ayant jamais écrits.
Oh absolument. Dans un tel cas, généralement tout le système de fichiers passe en mode lecture seule, et tout est horrible. Mais cela arrive rarement, inutile de perdre les avantages en termes de performances en général.
la source
Des E / S asynchrones et mises en mémoire tampon étaient utilisées avant Linux et même avant Unix. Unix l'avait et toutes ses ramifications.
Voici ce que Ritchie et Thompson ont écrit dans leur document intitulé Le système de partage du temps UNIX :
Dans votre question, vous avez également écrit:
Oui, l'écriture peut échouer et le programme peut ne jamais le savoir. Bien que ce ne soit jamais une bonne chose, ses effets peuvent être minimisés dans les cas où une erreur d'E / S génère un panique système (sur certains OS, cela est configurable. Au lieu de paniquer, le système peut continuer à s'exécuter mais le système de fichiers affecté est non monté ou monté en lecture seule). Les utilisateurs peuvent ensuite être avertis que les données de ce système de fichiers sont suspectes. Et un lecteur de disque peut être surveillé de manière proactive pour voir si sa liste de défauts développés augmente rapidement, ce qui indique que le lecteur est en panne.
BSD a ajouté l'
fsync
appel système afin qu'un programme puisse être certain que ses données de fichier avaient été complètement écrites sur disque avant de poursuivre, et les systèmes Unix suivants ont fourni des options pour effectuer des écritures synchrones. GNU dd dispose d’une optionconv=fsync
permettant de s’assurer que toutes les données ont été écrites avant la fermeture de la commande. Il est pratique lors de l'écriture pour ralentir les lecteurs flash amovibles, où l'écriture des données en mémoire tampon peut prendre plusieurs minutes.Un arrêt soudain du système, causé par exemple par une panne de courant, est une autre source de corruption des fichiers. Pratiquement tous les systèmes actuels prennent en charge un indicateur clean / dirty dans leurs systèmes de fichiers. L'indicateur est défini sur clean lorsqu'il n'y a plus de données à écrire et que le système de fichiers est sur le point d'être démonté, généralement pendant l'arrêt du système ou par un appel manuel
umount
. Les systèmes s’exécutent généralementfsck
au redémarrage s’ils détectent que les systèmes de fichiers n’ont pas été arrêtés proprement.la source
Beaucoup de bonnes réponses, mais permettez-moi d'ajouter une chose… Rappelez-vous qu'Unix est un système multi-processus et multi-utilisateurs, de sorte que de nombreux utilisateurs pourraient potentiellement essayer de faire des opérations sur les fichiers (en particulier des écritures) à (presque) la en même temps. Avec d'anciens disques durs lents - peut-être montés sur le réseau - cela prendrait non seulement du temps (pour lequel les programmes se verrouillaient en principe et les utilisateurs devaient attendre), mais aussi beaucoup de déplacement de la tête de lecture / écriture du lecteur. disque en arrière.
Au lieu de cela, les fichiers en attente d'écriture ont été conservés en mémoire pendant un certain temps, puis triés après l'endroit où ils devaient se retrouver sur le disque ... et lorsque le tampon était saturé - ou que le démon de synchronisation du disque avait attendu la fin. nombre de secondes requis (généralement environ 30 secondes, je pense) - la totalité de la mémoire tampon a été écrite sur le disque "dans l’ordre", la tête d’écriture devant uniquement effectuer un mouvement de balayage continu, en écrivant les fichiers sur le disque en tant que ça s'est passé ... au lieu de sauter partout.
Bien sûr, avec les disques rapides actuels - sans parler des périphériques à semi-conducteurs - le gain est beaucoup moins… surtout sur un système Linux à la maison, où un seul utilisateur travaille à la fois, et avec seulement quelques programmes.
Quoi qu'il en soit, anticiper les lectures en lisant (dans le cache / tampon) plus que ce qui était demandé - et trier les données en attente d'écriture afin qu'elles puissent être écrites en "un seul mouvement" - était en fait une très bonne idée au début. le temps, en particulier sur les systèmes avec beaucoup de lecture et d'écriture par de nombreux utilisateurs.
la source
Il n’est pas spécifique à Linux, il s’appelle le cache de pages (que Linux fait très bien). Voir aussi http://linuxatemyram.com/ ; ainsi, si un fichier est écrit, puis relu quelques secondes plus tard, très souvent, aucune E / S disque n'est nécessaire.
Le principal avantage est que sur de nombreux systèmes, il y a beaucoup de RAM, et une partie de celle-ci peut être utilisée comme cache par le noyau. Ainsi, certaines opérations sur les fichiers peuvent tirer profit de cette mise en cache. En outre, la durée des E / S de disque est beaucoup plus lente (généralement plusieurs milliers de fois pour SDD et presque un million de fois pour les disques durs mécaniques) par rapport à la RAM.
Le code de l'application peut donner des indications sur cette mise en cache: voir par exemple posix_fadvise (2) & madvise (2)
la source
Les plateaux tournants sont plus lents que la RAM. Nous utilisons la mise en cache des lectures / écritures pour "masquer" ce fait.
La chose utile à propos de l’écriture IO est qu’elle n’exige pas que l’E / S de disque se produise immédiatement, contrairement à une lecture, dans laquelle vous ne pouvez pas renvoyer de données à l’utilisateur tant que la lecture n’est pas terminée sur le disque.
Ainsi, les écritures fonctionnent sous une contrainte temporelle souple - tant que notre débit soutenu ne dépasse pas celui de notre disque, nous pouvons masquer une grande partie des inconvénients liés aux performances dans un cache d'écriture.
Et nous avons besoin d'écrire en cache - les disques en rotation sont relativement lents comparativement. Mais ainsi, les types de RAID modernes ont une pénalité importante en termes de fonctionnement.
Un RAID 6 par exemple, pour terminer une entrée / sortie en écriture, il faut:
Ainsi, chaque écriture correspond à 6 opérations d'E / S. En particulier, lorsque vous utilisez des disques lents, tels que de gros disques SATA, cela devient extrêmement coûteux.
Mais il existe une solution simple et agréable: écrivez en coalescence. Si vous pouvez créer une écriture «en bande complète» dans une mémoire tampon, vous n'avez pas besoin de lire la parité à partir de votre disque. Vous pouvez la calculer en fonction de ce que vous avez en mémoire.
C'est très souhaitable, car vous n'avez plus d'amplification en écriture. En effet, vous pouvez vous retrouver avec une pénalité en écriture plus faible que RAID 1 + 0.
Considérer:
RAID 6, 8 + 2 - 10 broches.
8 blocs de données consécutifs à écrire - calculez la parité dans le cache et écrivez un bloc sur chaque disque. 10 écritures par 8, signifie une pénalité en écriture de 1,25. 10 disques de RAID 1 + 0 ont toujours une pénalité en écriture de 2 (car vous devez écrire sur chaque sous-miroir). Dans ce scénario, vous pouvez donc améliorer les performances de RAID 6 par rapport à RAID1 + 0. Dans le monde réel, vous obtenez cependant un peu plus d'un profil d'E / S mixte.
La mise en cache d'écriture a donc une grande incidence sur les performances perçues des ensembles RAID: vous pouvez écrire à la vitesse de la mémoire vive et subir une pénalité d'écriture faible, ce qui améliore votre débit soutenu si vous le faites.
Et si vous ne le faites pas, vous souffrez de la lenteur des performances de SATA, mais multipliez-le par 6 et ajoutez un peu de controverse. Votre SATA RAID-6 à 10 voies sans la mise en cache en écriture serait un peu plus rapide qu’un seul lecteur sans RAID ... mais pas de beaucoup.
Comme vous le constatez, vous prenez un risque, mais une panne de courant signifie une perte de données. Vous pouvez résoudre ce problème en effectuant des cycles de vidage du cache, en sauvegardant la batterie sur votre cache ou en utilisant un disque SSD ou un autre cache non volatile.
la source
Aucune des autres réponses ne mentionnait une allocation différée . XFS, ext4, BTRFS et ZFS l'utilisent tous. XFS l'utilisait depuis qu'ext4 existait déjà, je vais donc l'utiliser comme exemple:
XFS ne décide même pas où mettre les données avant l'écriture. L'allocation différée donne à l'allocateur beaucoup plus d'informations sur lesquelles baser ses décisions. Lorsqu'un fichier est écrit pour la première fois, il est impossible de savoir s'il s'agira d'un fichier 4k ou d'un fichier 1G et toujours en croissance. S'il y a 10G d'espace libre contigu quelque part, placer le fichier 4k au début ne sert à rien. Placer le fichier volumineux au début d’un grand espace libre réduit la fragmentation.
la source
Toutes les autres réponses ici sont pour le moins presque toutes correctes pour le cas normal, et je vous recommanderais d'en lire une avant le mien, mais vous avez mentionné que dd et dd ont un cas d'utilisation typique qui peut ne pas impliquer la mise en cache d'écriture. La mise en cache en écriture est principalement mise en œuvre au niveau du système de fichiers. Les périphériques bruts ne font normalement pas la mise en cache en écriture (plusieurs pilotes de périphérique tels que raid ou lvm sont une autre boule de cire). Étant donné que dd est souvent utilisé avec des périphériques en mode bloc, il fournit le bs et les options associées afin de permettre des écritures volumineuses pour de meilleures performances sur les périphériques bruts. Cela n’est pas aussi utile lorsque les deux ordinateurs d'extrémité sont des fichiers normaux (bien que les écritures volumineuses utilisent moins d'appels système dans ce cas). L'autre endroit commun où cela est particulièrement visible est le paquetage mtools, qui est une implémentation du système de fichiers fat de l'espace utilisateur. utiliser mtools avec un lecteur de disquette est toujours incroyablement lent, car les outils sont complètement synchrones et les lecteurs de disquettes sont incroyablement lents. Monter la disquette et utiliser le système de fichiers fat du noyau est beaucoup plus réactif, sauf pour umount qui est synchrone (et très important pour éviter les pertes de données, en particulier pour les périphériques amovibles tels que les disquettes). Je ne suis au courant que de quelques autres programmes utilisés régulièrement avec des périphériques bruts tels que des bases de données spécialement configurées (qui implémentent leur propre cache d'écriture), tar et des périphériques et outils de système de fichiers spécialisés tels que chdsk, mkfs et mt. Monter la disquette et utiliser le système de fichiers fat du noyau est beaucoup plus réactif, sauf pour umount qui est synchrone (et très important pour éviter les pertes de données, en particulier pour les périphériques amovibles tels que les disquettes). Je ne suis au courant que de quelques autres programmes utilisés régulièrement avec des périphériques bruts tels que des bases de données spécialement configurées (qui implémentent leur propre cache d'écriture), tar et des périphériques et outils de système de fichiers spécialisés tels que chdsk, mkfs et mt. Monter la disquette et utiliser le système de fichiers fat du noyau est beaucoup plus réactif, sauf pour umount qui est synchrone (et très important pour éviter les pertes de données, en particulier pour les périphériques amovibles tels que les disquettes). Je ne suis au courant que de quelques autres programmes utilisés régulièrement avec des périphériques bruts tels que des bases de données spécialement configurées (qui implémentent leur propre cache d'écriture), tar et des périphériques et outils de système de fichiers spécialisés tels que chdsk, mkfs et mt.
la source
O_DIRECT
si vous voulez contourner le cache.dd oflag=direct
. IIRC, certains ordinateurs par défaut pour diriger les E / S directes sur les périphériques en mode bloc. (Et requièrent la lecture / écriture de blocs alignés, ce que Linux ne fait pas, car il écrit de toute façon le pagecache.)La philosophie est non sécurisée par défaut.
Deux stratégies raisonnables et évidentes sont possibles: écrire immédiatement sur le disque ou écrire en différé. UNIX a historiquement choisi ce dernier. Donc, pour la sécurité, vous devez appeler
fsync
après.Cependant, vous pouvez spécifier la sécurité dès le départ en montant un périphérique avec une option
sync
ou par fichier en l'ouvrant avecO_SYNC
.N'oubliez pas qu'UNIX a été conçu pour les experts en informatique. "Safe by default" n'était pas une considération. La sécurité signifie des E / S plus lentes, et ces premiers systèmes avaient vraiment des E / S lentes, ce qui rendait le prix élevé. Malheureusement, ni UNIX ni Linux ne sont passés à safe-be-default, même s’il s’agit d’un changement incessant.
la source
Il échange une faible quantité de fiabilité pour une augmentation importante du débit.
Supposons, par exemple, un programme de compression vidéo. Avec écriture différée ("write back"):
Contre
La deuxième version apparaît deux fois plus vite car elle peut utiliser simultanément le processeur et le disque, alors que la première version attend toujours l'une ou l'autre.
En règle générale, vous souhaitez réécrire pour les opérations de streaming et les opérations de fichiers en bloc, et l'écriture directe pour les bases de données et les applications similaires.
la source
Dans de nombreuses applications, les périphériques de stockage seront occupés à lire des données par intermittence. Si un système est toujours en mesure de différer les écritures jusqu'au moment où le périphérique de stockage n'est pas occupé à lire des données, du point de vue de l'application, les écritures ne prendront aucun temps. Les seules situations dans lesquelles l'écriture ne serait pas instantanée seraient les suivantes:
Les tampons d'écriture se remplissent à un point tel qu'aucune autre demande d'écriture différée ne peut être acceptée avant la fin des écritures.
Il est nécessaire d'éteindre ou de supprimer le périphérique pour lequel des écritures sont en attente.
Une application demande spécifiquement la confirmation qu'une écriture est réellement terminée.
En effet, c’est uniquement en raison des exigences susmentionnées que l’écriture doit avoir lieu. D'un autre côté, il n'y a généralement aucune raison de ne pas effectuer d'écriture en attente à des moments où un périphérique serait autrement inactif. Par conséquent, de nombreux systèmes les exécutent.
la source
Il y a aussi ceci:
Écrire "Salut, Joe Moe"
est plus rapide que:
Écrire "Salut,"
Écrire "Joe"
Écrire "Moe"
Et aussi:
Ecris "Salut, comment vas-tu?"
est plus rapide que:
Ecrire "Salut, quoi de neuf?"
Supprimer cette
écriture "Salut, comment vas-tu?"
Supprimer cette
écriture "Salut, comment vas-tu?"
Il est préférable que les modifications et l'agrégation se produisent dans la RAM que sur le disque. Le traitement par lots d'écriture sur disque libère les développeurs d'applications de ces problèmes.
la source