Utilisation d'O_DIRECT sous Linux

24

Si cette question est trop orientée programmeur, faites le moi savoir. Je me demande s'il y a des gens familiers avec le drapeau O_DIRECT pour l'appel système open () sous Linux 2.6? Linus dénigre son utilisation, mais l'écriture de fichiers haute performance semble indiquer son utilisation. J'aimerais connaître toute expérience et recommandations du monde réel.

Plus d' informations: L'application que j'utilise ne maintenir son propre cache, et ce faisant atteint si une moyenne de 5x ou plus de vitesse vers le haut. Lors de l'écriture dans un fichier, le contenu du cache doit être écrit dans le cache du système de fichiers, ce qui semble redondant et un problème de performances.

casualunixer
la source

Réponses:

17

Ok, vous demandez des expériences, cela rend la question un peu subjective et argumentative, mais passable.

Linus a déclaré que se référant aux utilisations que les gens attribuent habituellement à O_DIRECT, et pour ces utilisations, IMO Linus est généralement correct. Même si vous effectuez des E / S directes, vous ne pouvez pas transférer des données vers / depuis des périphériques directement vers vos instructions de programme, vous avez besoin d'un tampon qui est rempli (par le programme ou le périphérique) et transféré via un appel système à l'autre extrémité. De plus, pour le rendre efficace, vous ne voudrez pas relire quelque chose que vous venez de lire, au cas où vous en auriez besoin à nouveau. Vous avez donc besoin d'une sorte de cache ... et c'est exactement cela que le noyau fournit sans O_DIRECT, un cache de page! Pourquoi ne pas utiliser ça? Il présente également des avantages si plusieurs processus souhaitent accéder simultanément au même fichier, ce serait un désastre avec O_DIRECT.

Cela dit, O_DIRECT a ses utilisations: si, pour une raison quelconque, vous devez obtenir des données directement à partir du périphérique de bloc. Cela n'a rien à voir avec les performances.

Les personnes utilisant O_DIRECT pour les performances proviennent généralement de systèmes avec de mauvais algorithmes de cache de pages, ou sans mécanismes de conseil POSIX, ou même de personnes répétant sans réfléchir ce que d'autres ont dit. Pour éviter ces problèmes, O_DIRECT était une solution. Linux, OTOH, a la philosophie que vous devez résoudre le vrai problème sous-jacent, et le problème sous-jacent était les systèmes d'exploitation qui ont mal fait la mise en cache des pages.

J'ai utilisé O_DIRECT pour une implémentation simple de cat pour trouver une erreur de mémoire dans ma machine. Il s'agit d'une utilisation valide pour O_DIRECT. Cela n'avait rien à voir avec la performance.

Juliano
la source
Merci pour l'info, c'est apprécié. J'ai mis à jour ma question avec les conditions spécifiques de l'application à l'origine de cette question. Si vous avez plus de détails sur les mécanismes de conseil POSIX pour l'écriture de fichiers, cela serait également apprécié.
casualunixer
4
o_direct pourrait également être utile dans un système où le développeur souhaite fournir un mécanisme de mise en cache au niveau de la couche application (pensez aux bases de données).
Jmoney38
Cela n'a rien à voir avec les performances. Ce n'est pas toujours vrai, en particulier pour accéder à un périphérique à haute vitesse où les taux d'E / S rivalisent avec la bande passante mémoire, ou même juste un pourcentage significatif de la bande passante mémoire. Dans ce cas, le fait de sauter la copie supplémentaire vers / depuis le cache de page peut avoir des avantages de performances significatifs.
Andrew Henle
14

En fait, O_DIRECT est nécessaire pour éviter

  • pollution du cache - parfois vous savez qu'il n'y a aucun sens dans les frais généraux avec la mise en cache, par exemple lorsque vous traitez des fichiers très volumineux, disons 64 Gio alors qu'il n'y a que 2 Gio de RAM. Un fichier torrent de 32 Gio qu'un utilisateur a décidé de vérifier ne semble pas être un bon candidat pour la mise en cache. C'est juste une activité supplémentaire avec ses propres frais généraux. Et cela peut entraîner l'élagage de certaines données vraiment utiles à partir du cache.
  • double mise en cache - par exemple, certains SGBDR (MySQL pour mentionner) permet de définir son propre cache. Les bases de données savent mieux comment mettre en cache et quoi, que la mémoire virtuelle du noyau qui ne connaît rien à la planification SQL, etc.

- ce qui n'est pas bon, semble-t-il. Et O_DIRECTcela ne veut pas dire être plus rapide, ce n'est souvent pas le cas .

poige
la source
10
posix_fadvisepeut prendre en charge le problème de pollution du cache.
psusi
Je ne pense pas que la mémoire virtuelle ait quoi que ce soit à voir avec cela, elle mappe simplement l'adresse de la mémoire. Buffer Cache / Page Cache est ce que vous voulez dire.
ArekBulski
Les caches / la mise en cache font partie du sous-système VM sous UNIX, pour autant que je sache, c'est pourquoi j'ai utilisé ce terme. Merci d'avoir édité. :)
poige
6

Notez que l'utilisation O_DIRECTest susceptible d'échouer dans les noyaux plus récents avec des systèmes de fichiers plus récents. Voir ce rapport de bogue par exemple. Ainsi, non seulement l'utilisation est souvent douteuse, mais elle ne fonctionnera probablement pas du tout dans la prochaine génération de distributions Linux. Je ne parierais donc pas les performances de mon code dessus, même si vous êtes en mesure de prouver qu'il pourrait avoir un avantage.

Peter Eisentraut
la source
1
Le rapport de bogue discute en fait de l'utilisation des systèmes de fichiers avec l'option journal = data activée. Cette option est directement opposée en effet à l'indicateur O_DIRECT. La plupart des systèmes de fichiers ext3 et ext4 n'ont pas cet indicateur défini et s'ils le font, le désactiver permettra d'ouvrir le fichier avec O_DIRECT.
casualunixer
3

Cela a beaucoup à voir avec les performances.

Un exemple intéressant est dans mongodb utilisant le moteur mmap. O_DIRECT est mieux utilisé, comme d'autres l'ont dit, où les données ne seront probablement pas lues pendant un certain temps. Dans mongodb, le journal de base de données est écrit à l'aide de O_DIRECT tandis que les écritures de données et d'index sont gérées par le mécanisme de cache de page (pdflush) car, bien que O_DIRECT offre moins de bande passante, cela signifie également moins de latence, et donc réduit la perte de données en cas de panne inattendue (panique du noyau, panne de disque ou d'alimentation). Notez qu'il y a encore une mise en mémoire tampon avant qu'une écriture O_DIRECT ne soit validée sur un stockage non volatile, cela réduit simplement la perte de données.

Une autre caractéristique importante de O_DIRECT est qu'il offre plus de contrôle sur la séquence d'écritures. Encore une fois, cela ne garantit pas l'ordre des écritures (sauf si vous avez un contrôleur de disque de mise en cache non volatile et utilisez le planificateur fifo, mais ceux-ci ont leurs propres complications). Par conséquent, bien que mysql utilise O_DIRECT pour ses données / index ainsi que pour la journalisation, il peut s'attendre à ce que ces derniers soient généralement validés en premier.

Mais il est important de se rappeler que O_DIRECT rompt l'équité dans l'allocation des ressources. L'une des raisons pour lesquelles votre application est accélérée est qu'elle ralentit d'autres choses.

symcbean
la source
Vous dites que cela a beaucoup à voir avec les performances, mais vous fournissez un exemple où il est utilisé pour réduire la latence ou ordonner des écritures. Mais je suis d'accord que cela affecte les performances. Juste point sur l'équité.
ArekBulski
Pouvez-vous fournir plus de références expliquant quand c'est injuste?
ACyclique
3

Concernant ce que @Juliano a déjà dit.

Vérifiez posix_fadvisesi le vrai problème est un mauvais comportement de l'algorithme de cache du système de fichiers sous-jacent, vous pouvez essayer de lui donner des conseils, comment allez-vous utiliser le système de fichiers. Pour les fs bien implémentés, cela devrait donner un coup de fouet aux performances. (Voici un lien vers un autre sujet touchant des considérations similaires /programming//a/3755818/544721 )

Grzegorz Wierzowiecki
la source
1
Il semble que posix_fadvise modifie les algorithmes de lecture anticipée utilisés par le noyau. Le facteur critique avec le code dans la question est la performance d'écriture. Le problème est que l'écriture du tampon remplit d'abord les caches Linux, que le noyau doit ensuite vider lorsqu'il manque de mémoire. C'est un gaspillage d'effort, la sortie dans ce cas doit être mise en mémoire tampon minimale sur le chemin du disque.
casualunixer