2010-09-23 29 views
5

Je suis sur linux, nfs, avec plusieurs machines impliquées. J'essaye d'employer fcntl pour implémenter le filelocking. J'utilisais le troupeau jusqu'à ce que je découvre qu'il ne fonctionne qu'entre les processus sur la même machine. Maintenant, quand j'appelle fcntl avec F_SETLKW, les alarmes perl (pour ajouter un timeout) ne fonctionnent plus comme avant. Ce serait normalement bien, mais ctrl-c ne fonctionne pas vraiment non plus. Ce que je crois se passe, c'est que fcntl vérifie seulement les signaux toutes les 30 secondes environ. L'alarme revient finalement. Le ctrl-c est attrapé, ... finalement.Puis-je faire coopérer les alarmes fcntl et Perl?

Y a-t-il quelque chose que je peux faire pour ajuster la fréquence avec laquelle fcntl vérifie ces signaux?

+4

Verrouiller sur NFS est difficile. Utiliser 'File :: NFSLock' vous donnerait probablement une solution qui fonctionne sans que vous n'ayez à écrire du code. – rafl

+0

File :: NFSLock a ses propres trous.Il essaye de jouer quelques tours avec des liens durs et d'autres choses, mais si votre système de fichiers est surchargé, vous pouvez facilement avoir des conditions de course qui produisent deux processus avec le même verrou. – mmccoo

+2

Il a quelques lacunes documentées, y compris la tendance à affamer les processus d'attente dans une situation très litigieuse, oui. Cependant, pour le problème que vous essayez de résoudre, il pourrait très bien être le bon compromis. Je ne peux pas vraiment le dire car vous n'avez pas décrit votre situation plus loin. Je peux cependant parler de l'expérience de l'utilisation de File :: NFSLock: je n'ai jamais vu son approche affamer l'un de mes processus, même dans des situations avec beaucoup de contention, par rapport à la plupart des autres choses que je fais. Le nombre de modules en fonction de cela semble également indiquer qu'il est assez bon pour la plupart des gens – rafl

Répondre

1

Je ne suis certainement pas un expert en la matière, mais je sais que fcntl, comme vous l'avez également dit, ne fonctionnera pas dans votre cas. Les verrous fcntl advisory n'ont de sens que dans la même machine. Alors oubliez-moi si c'est hors sujet. J'ai utilisé File::NFSLock pour résoudre le problème des tempêtes de cache/dogpile/stamping. Il y avait plusieurs serveurs d'applications qui lisent et écrivent des fichiers de cache sur un volume NFS (pas très bonne idée, mais c'était ce que nous avions commencé).

J'ai sous-classé/enveloppé File :: NFSLock pour modifier son comportement. En particulier, je avais besoin:

  • persistants, serrures qui ne vont pas quand un objet File :: nfslock est hors de portée. En utilisant le fichier File :: NFSLock, votre verrou disparaîtra lorsque l'objet sera hors de portée. Ce n'était pas ce dont j'avais besoin.
  • que les fichiers de verrous réels contiennent également le nom de la machine qui a acquis le verrou. L'identificateur de processus n'est clairement pas suffisant pour décider si un processus est terminé, donc je peux voler le fichier de verrouillage en toute sécurité. J'ai donc modifié le code pour écrire lockfiles comme machine:pid au lieu de seulement pid.

Ceci a fonctionné merveilleusement pendant quelques années.

Jusqu'à ce que le volume de demandes augmente de 10 fois. C'est-à-dire, le mois dernier j'ai commencé à éprouver les premiers problèmes où un dossier de cache vraiment occupé était écrit par deux backends au en même temps, laissant des verrous morts derrière. Cela s'est passé pour moi lorsque nous avons atteint environ 9-10 millions de pages vues par jour, juste pour vous donner une idée.

Le fichier de cache finale cassé ressemblait à:

<!-- START OF CACHE FILE BY BACKEND b1 --> 
... cache file contents ... 
<!-- END OF CACHE FILE BY BACKEND b1 --> 
... more cache file contents ... wtf ... 
<!-- END OF CACHE FILE BY BACKEND b2 --> 

Cela ne peut se produire si deux backends écrire dans le même fichier en même temps ... Il ne sait pas encore si ce problème est causé par fichier: : NFSLock + nos mods ou un bug dans l'application. En conclusion, si votre application n'est pas très occupée et trafiquée, alors allez pour File :: NFSLock, je pense que c'est votre meilleur pari. Vous êtes sûr de vouloir utiliser NFS?