C Programme coincé sur une attente sans interruption lors de l'exécution d'E / S de disque sur Mac OS X Snow Leopard

StackOverflow https://stackoverflow.com/questions/2017283

  •  19-09-2019
  •  | 
  •  

Question

Une ligne de fond: je suis le développeur de Redis, une base de données NoSQL. L'une des nouvelles fonctionnalités que j'implémente est la mémoire virtuelle, car Redis prend toutes les données en mémoire. Grâce à VM Redis est capable de transférer des objets rarement utilisés de la mémoire au disque, il y a un certain nombre de raisons pour lesquelles cela fonctionne beaucoup mieux que de laisser le système d'exploitation faire le travail pour nous échanger (les objets redis sont construits de nombreux petits objets alloués à non contiguë lieux, lorsqu'ils sont sérialisés au disque par redis, ils prennent 10 fois moins d'espace par rapport aux pages de mémoire où ils vivent, et ainsi de suite).

Maintenant, j'ai une implémentation alpha qui fonctionne parfaitement sur Linux, mais pas si bien sur Mac OS X Snow Leopard. De temps en temps, alors que Redis essaie de déplacer une page de la mémoire au disque, le processus Redis entre dans l'état d'attente sans interruption pendant des minutes. Je n'ai pas pu déboguer, mais cela se produit soit en un appel à fseeko() ou fwrite(). Après quelques minutes, l'appel revient enfin et Redis continue de travailler sans problèmes: pas de crash.

La quantité de données transférées est très Petit, quelque chose comme 256 octets. Il ne devrait donc pas être une très grande quantité d'E / S effectuée.

Mais il y a un détail intéressant sur le fichier d'échange qui est cible de l'opération d'écriture. C'est un gros fichier (26 gigaoctets) créé en ouvrant un fichier avec fopen() puis agrandir en utilisant ftruncate(). Enfin, le fichier est unlink()ED afin que Redis continue de faire une référence, mais nous sommes sûrs que lorsque le processus Redis quittera le système d'exploitation sera vraiment libéré le fichier d'échange.

Ok, c'est tout mais je suis ici pour plus de détails. Et btw, vous pouvez même trouver le code réel dans le redis git, mais il n'est pas trivial de comprendre en cinq minutes étant donné que c'est un système assez complexe.

Merci beaucoup pour toute aide.

Était-ce utile?

La solution

Si je comprends bien, HFS + a une très mauvaise prise en charge pour les fichiers clairsemés. Il se peut donc que votre écriture déclenche une extension de fichier qui initialise / matérialise une grande fraction du fichier.

Par exemple, je sais que mmap's un nouveau grand fichier vide, puis l'écriture à quelques emplacements aléatoires produit un très grand fichier sur disque avec HFS +. C'est assez ennuyeux car les fichiers MMAP et clairsemés sont un moyen extrêmement pratique de travailler avec les données, et pratiquement tous les autres plates-formes / systèmes de fichiers là-bas le gèrement.

Le fichier d'échange est-il écrit en linéairement? Ce qui signifie que nous remplaçons un bloc existant ou écrivons un nouveau bloc à la fin et incrémenons un pointeur d'espace libre? Si c'est le cas, peut-être que faire des appels plus fréquents plus petits pour étendre le fichier entraînerait des pauses plus courtes.

En passant, je suis curieux de savoir pourquoi Redis VM n'utilise pas MMAP, puis déplacez simplement des blocs dans le but de concentrer les blocs chauds en pages chaudes.

Autres conseils

Antirez, je ne suis pas sûr que je serai beaucoup d'aide car mon expérience Apple est limitée Apple ][, mais je vais vous donner un coup de feu.

La première chose est une question. J'aurais pensé que, pour la mémoire virtuelle, la vitesse de fonctionnement serait une mesure plus importante que l'espace disque (en particulier pour une base de données NoSQL où la vitesse est tout le point, sinon vous utiliseriez SQL, non?). Mais, si votre fichier d'échange est 26g, peut-être pas :-)

Certaines choses à essayer (si possible).

  1. Essayez d'isoler réellement le problème pour rechercher ou écrire. J'ai du mal à croire qu'une recherche pourrait prendre aussi longtemps que, au pire, ce devrait être un changement de pointeur de tampon. Pourtant, je n'ai pas écrit OSX, donc je ne peux pas être sûr.
  2. Essayez d'ajuster la taille du fichier d'échange pour voir si c'est ce qui cause le problème.
  3. Élargissez-vous dynamiquement le fichier de swap (par opposition à la pré-allocation)? Si vous le faites, c'est peut-être ce qui cause le problème.
  4. Écrivez-vous toujours aussi bas dans le fichier que possible? Il se peut que la création d'un fichier 26G ne le remplisse pas réellement de données, mais, si vous les créez, écrivez au dernier octet, le système d'exploitation peut avoir à zéro les octets avant cela (différer l'initialisation, le cas échéant).
  5. Que se passe-t-il si vous pré-allorez tout le fichier entier (écrivez à chaque octet) et ne pas le dissocier? En d'autres termes, laissez le fichier entre les exécutions de votre programme (la créant si elle n'existe pas déjà bien sûr). Ensuite, dans votre code de démarrage pour Redis, initialisez simplement le fichier (pointeurs et autres). Cela peut se débarrasser de tout problème comme ceux du point 4 ci-dessus.
  6. Demandez également sur les différents sites BSD. Je ne sais pas combien de pomme a changé sous les couvertures, mais OSX est juste du BSD au niveau le plus bas (Pax Ducks pour la couverture).
  7. Pensez également à demander les sites Apple (si vous ne l'avez pas déjà fait).

Eh bien, c'est ma petite contribution, j'espère que ça va aider. Bonne chance pour votre projet.

Avez-vous désactivé la mise en cache des fichiers pour votre fichier? IE FCNTL (FD, F_GLOBAL_NOCACH, 1)

Avez-vous essayé de déboguer avec Dtrace et ou des instruments (front-end expérimental du Dtrace d'Apple)?

Explorer le léopard avec Dtrace

Débogage du chrome sur OS X

Comme Linus l'a dit une fois sur la liste de diffusion GIT:

"Je me rends compte que les gens OS X ont du mal à l'accepter, mais les systèmes de fichiers OS X sont généralement des conneries totales et totales - encore plus que Windows."

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top