Depuis quelques jours, je cherche une solution fonctionnelle à une erreur
Error: EMFILE, too many open files
Il semble que de nombreuses personnes aient le même problème. La réponse habituelle consiste à augmenter le nombre de descripteurs de fichiers. Alors, j'ai essayé ceci:
sysctl -w kern.maxfiles=20480
,
La valeur par défaut est 10240. C'est un peu étrange à mes yeux, car le nombre de fichiers que je gère dans le répertoire est inférieur à 10240. Encore plus étrange, je reçois toujours la même erreur après avoir augmenté le nombre de descripteurs de fichiers .
Deuxième question:
Après un certain nombre de recherches, j'ai trouvé un moyen de contourner le problème "trop de fichiers ouverts":
var requestBatches = {};
function batchingReadFile(filename, callback) {
// First check to see if there is already a batch
if (requestBatches.hasOwnProperty(filename)) {
requestBatches[filename].push(callback);
return;
}
// Otherwise start a new one and make a real request
var batch = requestBatches[filename] = [callback];
FS.readFile(filename, onRealRead);
// Flush out the batch on complete
function onRealRead() {
delete requestBatches[filename];
for (var i = 0, l = batch.length; i < l; i++) {
batch[i].apply(null, arguments);
}
}
}
function printFile(file){
console.log(file);
}
dir = "/Users/xaver/Downloads/xaver/xxx/xxx/"
var files = fs.readdirSync(dir);
for (i in files){
filename = dir + files[i];
console.log(filename);
batchingReadFile(filename, printFile);
Malheureusement, je reçois toujours la même erreur. Quel est le problème avec ce code?
Une dernière question (je suis nouveau dans javascript et node), je suis en train de développer une application web avec beaucoup de requêtes pour environ 5000 utilisateurs quotidiens. J'ai de nombreuses années d'expérience en programmation avec d'autres langages comme python et java. donc à l'origine j'ai pensé développer cette application avec django ou play framework. Puis j'ai découvert node et je dois dire que l'idée de modèle d'E / S non bloquant est vraiment sympa, séduisante, et surtout très rapide!
Mais à quel genre de problèmes dois-je m'attendre avec node? S'agit-il d'un serveur Web éprouvé en production? Quelles sont vos expériences?
la source
lsof -i -n -P | grep "12843" | wc -l
== 4085 maisulimit -a | grep "open files"
== (-n) 1024 un indice comment je pourrais avoir plus de fichiers ouverts que la limite maximale?L'utilisation du
graceful-fs
module d'Isaac Schlueter (mainteneur de node.js) est probablement la solution la plus appropriée. Il effectue un recul incrémentiel si EMFILE est rencontré. Il peut être utilisé en remplacement dufs
module intégré.la source
Je ne sais pas si cela aidera quelqu'un, j'ai commencé à travailler sur un gros projet avec beaucoup de dépendances qui m'ont renvoyé la même erreur. Mon collègue m'a suggéré d'installer en
watchman
utilisant brew et cela a résolu ce problème pour moi.Edit le 26 juin 2019: lien Github vers watchman
la source
Je suis tombé sur ce problème aujourd'hui, et ne trouvant pas de bonnes solutions, j'ai créé un module pour y remédier. J'ai été inspiré par l'extrait de @ fbartho, mais je voulais éviter d'écraser le module fs.
Le module que j'ai écrit est Filequeue , et vous l'utilisez comme fs:
la source
Vous lisez trop de fichiers. Node lit les fichiers de manière asynchrone, il lira tous les fichiers à la fois. Vous lisez donc probablement la limite de 10240.
Voyez si cela fonctionne:
la source
Comme nous tous, vous êtes une autre victime d'E / S asynchrones. Avec les appels asynchrones, si vous bouclez autour d'un grand nombre de fichiers, Node.js commencera à ouvrir un descripteur de fichier pour chaque fichier à lire, puis attendra l'action jusqu'à ce que vous le fermiez.
Le descripteur de fichier reste ouvert jusqu'à ce que la ressource soit disponible sur votre serveur pour le lire. Même si vos fichiers sont petits et que la lecture ou la mise à jour est rapide, cela prend du temps, mais dans le même temps, votre boucle ne s'arrête pas pour ouvrir un nouveau descripteur de fichiers. Donc si vous avez trop de fichiers, la limite sera bientôt atteinte et vous obtiendrez un magnifique EMFILE .
Il existe une solution, créer une file d'attente pour éviter cet effet.
Merci aux personnes qui ont écrit Async , il existe une fonction très utile pour cela. Il existe une méthode appelée Async.queue , vous créez une nouvelle file d'attente avec une limite, puis ajoutez des noms de fichiers à la file d'attente.
Remarque: si vous devez ouvrir de nombreux fichiers, ce serait une bonne idée de stocker les fichiers actuellement ouverts et de ne pas les rouvrir indéfiniment.
Vous pouvez voir que chaque fichier est ajouté à la file d'attente (nom de fichier console.log), mais uniquement lorsque la file d'attente actuelle est inférieure à la limite définie précédemment.
async.queue obtenir des informations sur la disponibilité de la file d'attente via un rappel, ce rappel n'est appelé que lorsque le fichier de données est lu et que toute action que vous avez à faire est réalisée. (voir méthode fileRead)
Vous ne pouvez donc pas être submergé par le descripteur de fichiers.
la source
Je viens de terminer d'écrire un petit bout de code pour résoudre moi-même ce problème, toutes les autres solutions semblent beaucoup trop lourdes et vous obligent à changer la structure de votre programme.
Cette solution bloque simplement tous les appels fs.readFile ou fs.writeFile de sorte qu'il n'y ait pas plus d'un nombre défini en vol à un moment donné.
la source
J'ai fait toutes les choses mentionnées ci-dessus pour le même problème mais rien n'a fonctionné. J'ai essayé ci-dessous, cela fonctionnait à 100%. Changements de configuration simples.
Option 1 définir la limite (cela ne fonctionnera pas la plupart du temps)
vérifier la limite disponible
Option 2 Augmenter la limite disponible pour dire 65535
ajoutez-y la ligne suivante
exécutez ceci pour actualiser avec une nouvelle configuration
éditer le fichier suivant
y ajouter les lignes suivantes
éditer le fichier suivant
ajoutez-y cette ligne
déconnectez-vous et connectez-vous et essayez la commande suivante
Option 3 Il suffit d'ajouter ci-dessous la ligne dans
vers /etc/systemd/system.conf et /etc/systemd/user.conf
la source
Avec la cornemuse, tu as juste besoin de changement
=>
La cornemuse vous aide à limiter le parallèle. plus de détails: https://github.com/JacksonTian/bagpipe
la source
J'ai eu le même problème lors de l'exécution de la commande nodemon , j'ai donc réduit le nom des fichiers ouverts dans un texte sublime et l'erreur a disparu.
la source
EMFILE
erreurs et, par essais et erreurs , j'ai remarqué que la fermeture de certaines fenêtres Sublime résolvait le problème. Je ne sais toujours pas pourquoi. J'ai essayé d'ajouterulimit -n 2560
à mon .bash_profile, mais cela n'a pas résolu le problème. Cela indique-t-il la nécessité de passer à Atom à la place?En s'appuyant sur la réponse de @ blak3r, voici un raccourci que j'utilise au cas où cela aiderait d'autres diagnostics:
Si vous essayez de déboguer un script Node.js qui manque de descripteurs de fichier, voici une ligne pour vous donner la sortie
lsof
utilisée par le processus de nœud en question:Cela fonctionnera de manière synchrone
lsof
filtrée par le processus Node.js en cours d'exécution et retournera les résultats via un tampon.Utilisez ensuite
console.log(openFiles.toString())
pour convertir le tampon en chaîne et consigner les résultats.la source
cwait est une solution générale pour limiter les exécutions simultanées de toutes les fonctions qui renvoient des promesses.
Dans votre cas, le code pourrait être quelque chose comme:
la source
Pour les utilisateurs de nodemon : utilisez simplement l' indicateur --ignore pour résoudre le problème.
Exemple:
la source
Utilisez le dernier
fs-extra
.J'ai eu ce problème sur
Ubuntu
(16 et 18) avec beaucoup d'espace pour les descripteurs de fichier / socket (compter aveclsof |wc -l
).fs-extra
Version d' occasion8.1.0
. Après la mise à jour de9.0.0
"Erreur: EMFILE, trop de fichiers ouverts" a disparu.J'ai rencontré divers problèmes sur divers systèmes d'exploitation avec des systèmes de fichiers de gestion de nœuds. Les systèmes de fichiers ne sont évidemment pas triviaux.
la source
J'ai eu ce problème, et je l'ai résolu en exécutant
npm update
et cela a fonctionné.Dans certains cas, vous devrez peut-être supprimer node_modules
rm -rf node_modules/
la source
J'ai installé watchman, modifié la limite, etc. et cela n'a pas fonctionné dans Gulp.
Le redémarrage d'iterm2 a cependant aidé.
la source