System.IO.FileSystemWatcher pour surveiller un dossier de serveur de réseau - Considérations sur les performances

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

Question

Je souhaite surveiller les modifications apportées à une arborescence de dossiers sur un serveur de réseau. Les fichiers ont tous une extension spécifique. Il y a environ 200 dossiers dans l’arbre et environ 1200 fichiers avec l’extension que je regarde.

Je ne peux pas écrire de service à exécuter sur le serveur (hors limites!). La solution doit donc être locale pour le client. La rapidité d'exécution n'est pas particulièrement importante. Je peux vivre avec une minute ou plus de retard dans les notifications. Je surveille les options Créer, Supprimer, Renommer et Modifications.

L'utilisation de .NET System.IO.fileSystemWatcher créerait-elle une charge considérable sur le serveur?

Que diriez-vous de 10 observateurs distincts pour réduire le nombre de dossiers / fichiers surveillés? (jusqu'à 200 dossiers sur 700, 1 200 sur 5 500 au total) Plus de trafic réseau au lieu de moins? Mes pensées sont un remaniement sur le serveur pour mettre les fichiers surveillés sous 1 arbre. Je n'ai peut-être pas toujours cette option, d'où l'équipe de gardiens.

Je suppose que l'autre solution consiste à vérifier périodiquement si le système de travail sur disque crée une charge excessive sur le serveur ou s'il ne fonctionne pas pour de nombreuses raisons de type SysAdmin.

Y a-t-il une meilleure façon de faire cela?

Était-ce utile?

La solution

Du point de vue de la charge du serveur, utilisez IO .FileSystemWatcher pour les notifications de modification à distance dans le scénario que vous décrivez est probablement la méthode la plus efficace possible. Il utilise la FindFirstChangeNotification et ReadDirectoryChangesW L'API Win32 fonctionne en interne, ce qui permet de communiquer avec le redirecteur de réseau de manière optimisée (en supposant un réseau Windows standard : si un redirecteur tiers est utilisé et qu'il ne supporte pas les fonctionnalités requises, les choses ne fonctionneront pas du tout). Le wrapper .NET utilise également les entrées / sorties asynchrones, garantissant ainsi une efficacité maximale.

Le seul problème avec cette solution est qu’elle n’est pas très fiable. Outre le fait que les connexions réseau doivent être temporairement interrompues (ce qui n'est pas un problème, car IO.FileSystemWatcher déclenchera un événement d'erreur que vous pourrez gérer dans ce cas), le mécanisme sous-jacent présente certaines limitations fondamentales. Dans la documentation MSDN pour les fonctions de l'API Win32:

  • ReadDirectoryChangesW échoue avec ERROR_INVALID_PARAMETER lorsque la longueur de la mémoire tampon est supérieure à 64 Ko et que l'application surveille un répertoire sur le réseau. Ceci est dû à une limite de taille de paquet avec les protocoles de partage de fichiers sous-jacents

  • Il est possible que les notifications ne soient pas renvoyées lorsque vous appelez FindFirstChangeNotification pour un système de fichiers distant

En d’autres termes: sous une charge élevée (lorsque vous auriez besoin d’un tampon important) ou, pire, dans des circonstances aléatoires et non spécifiées, vous risquez de ne pas recevoir les notifications que vous attendez. C'est même un problème avec les observateurs de système de fichiers locaux, mais c'est beaucoup plus un problème sur le réseau. Une autre question ici sur le responsable de sécurité décrit en détail les problèmes de fiabilité inhérents à l'API.

Lorsque vous utilisez des systèmes de surveillance du système de fichiers, votre application doit pouvoir gérer ces limitations. Par exemple:

  • Si les fichiers que vous recherchez ont des numéros de séquence, enregistrez le dernier numéro de séquence pour lequel vous avez été averti. Vous pouvez ainsi rechercher des "lacunes" dans les notifications futures et traiter les fichiers pour lesquels vous n'avez pas reçu. notifié;

  • Lors de la réception d'une notification, effectuez toujours une analyse complète du répertoire. Cela peut sembler vraiment mauvais, mais puisque l'analyse est basée sur des événements, elle est toujours beaucoup plus efficace que l'interrogation directe. De plus, tant que vous gardez le nombre total de fichiers dans un seul répertoire, ainsi que le nombre de répertoires à analyser, de moins de mille, l'impact de cette opération sur les performances devrait de toute façon être assez minime.

Il est préférable d'éviter autant que possible de configurer plusieurs personnes: vous ferez même moins des choses fiables ...

Quoi qu'il en soit, si vous devez absolument utiliser les observateurs de système de fichiers, les choses peuvent fonctionner correctement, à condition que vous connaissiez les limitations et ne vous attendez pas à une notification 1: 1 pour chaque fichier modifié. /créé.

Donc, si vous avez d'autres options (essentiellement, avoir le processus d'écriture des fichiers vous avertir d'une manière non basée sur le système de fichiers: toute méthode RPC classique sera une amélioration ...), celles qui méritent d'être explorées un point de vue de la fiabilité.

Autres conseils

J'ai utilisé les observateurs de système de fichiers de C # à plusieurs reprises. La première fois que je les ai utilisées, j’ai eu des problèmes avec leur arrêt du travail, principalement en raison du fait que je traitais les modifications dans le fil qui les signalait.

Maintenant, cependant, je dépose simplement la modification dans une file d'attente et la traite sur un autre thread. Cela semble résoudre le problème que j'avais à l'origine. Pour votre problème, vous pouvez avoir plusieurs observateurs poussant sur la même file d'attente.

Cependant, je n'ai pas utilisé cela avec votre sorte d'échelle de problème.

D'après mon expérience, un système de travail partagé ne crée pas un trafic réseau élevé. Toutefois, en cas de problème de performances, votre approche consistant à utiliser plusieurs observateurs et à le décomposer en moins de dossiers visionnés semble raisonnable.

J'ai eu quelques gros problèmes avec FSW sur les lecteurs réseau: La suppression d'un fichier renvoyait toujours l'événement d'erreur, jamais l'événement supprimé. Je n’ai pas trouvé de solution et j’évite donc d’utiliser FSW s’il existe un moyen de le contourner ...

Le La documentation MSDN indique vous pouvez utiliser le composant FileSystemWatcher pour surveiller les modifications du système de fichiers sur un lecteur du réseau.

Il indique également que le composant observateur écoute les notifications de modification du système de fichiers plutôt que d'interroger régulièrement le lecteur cible à la recherche de modifications.

Sur cette base, la quantité de trafic réseau dépend entièrement de l'ampleur des modifications du contenu de ce lecteur réseau. Le composant FSW n'augmentera pas le niveau de trafic réseau.

Watcher semble fiable à 100% - il suffit de regarder la taille de la mémoire tampon sur l'objet observateur. J'ai testé des milliers de mises à jour de fichiers, aucune perdue.

Je recommande d'utiliser une approche multi-thread - le déclencheur étant l'observateur de fichiers. Il peut lancer un thread pour chaque modification de fichier détectée. L'observateur peut traiter beaucoup plus rapidement avec moins de risque de débordement. (utilisez le fil Async)

Après avoir utilisé System.IO.FileSystemWatcher pendant un certain temps. Ce n'est pas assez stable pour gérer des événements qui arrivent trop rapidement. Pour assurer la lecture à 100% des fichiers. J'utilise des méthodes de répertoire simples pour rechercher dans les fichiers. Après l'avoir lu, copiez immédiatement les fichiers dans un autre dossier. Pour l'isoler des nouveaux fichiers ajoutés pendant que vous lisez les fichiers.

Le minuteur est utilisé pour lire régulièrement le dossier. En copiant le fichier déjà lu dans le dossier d'archivage, assurez-vous qu'il ne sera pas lu à nouveau. La lecture ultérieure sera toujours de nouveaux fichiers.

var fileNames = Directory.GetFiles(srcFolder);
foreach (string fileName in fileNames)
{
   string[] lines = File.ReadAllLines(fileName);
}

Je ne pense pas qu'il y ait une sorte d'état actif ou de communication entre l'ordinateur avec le FSW et l'ordinateur dont l'emplacement est surveillé. En d’autres termes, le FSW n’envoie pas de requête ping au système d’exploitation en réseau pour vérifier le fichier.

On pourrait imaginer qu'un message ou un événement est seulement généré / envoyé au FSW en réseau lorsqu'un changement survient.

Mais tout cela n’est que spéculation. :)

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