Seit einigen Tagen habe ich nach einer funktionierenden Lösung für einen Fehler gesucht
Error: EMFILE, too many open files
Es scheint, dass viele Menschen das gleiche Problem haben. Die übliche Antwort besteht darin, die Anzahl der Dateideskriptoren zu erhöhen. Also habe ich das versucht:
sysctl -w kern.maxfiles=20480
,
Der Standardwert ist 10240. Dies ist in meinen Augen etwas seltsam, da die Anzahl der Dateien, die ich im Verzeichnis verarbeite, unter 10240 liegt. Noch seltsamer ist, dass ich immer noch den gleichen Fehler erhalte, nachdem ich die Anzahl der Dateideskriptoren erhöht habe .
Zweite Frage:
Nach einer Reihe von Suchen habe ich eine Lösung für das Problem "zu viele offene Dateien" gefunden:
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);
Leider erhalte ich immer noch den gleichen Fehler. Was ist los mit diesem Code?
Eine letzte Frage (ich bin neu in Javascript und Node): Ich bin dabei, eine Webanwendung mit vielen Anfragen für etwa 5000 Benutzer pro Tag zu entwickeln. Ich habe langjährige Erfahrung in der Programmierung mit anderen Sprachen wie Python und Java. Ursprünglich dachte ich, diese Anwendung mit Django oder Play Framework zu entwickeln. Dann habe ich Node entdeckt und ich muss sagen, dass die Idee eines nicht blockierenden E / A-Modells wirklich nett, verführerisch und vor allem sehr schnell ist!
Aber welche Probleme sollte ich mit Node erwarten? Ist es ein produktionserprobter Webserver? Was sind deine Erfahrungen?
quelle
lsof -i -n -P | grep "12843" | wc -l
== 4085 aberulimit -a | grep "open files"
== (-n) 1024 Gibt es einen Hinweis darauf, wie ich mehr geöffnete Dateien als maximal haben könnte?Die Verwendung des
graceful-fs
Moduls von Isaac Schlueter (node.js Betreuer) ist wahrscheinlich die am besten geeignete Lösung. Es wird ein inkrementelles Backoff durchgeführt, wenn EMFILE auftritt. Es kann als Ersatz für das eingebautefs
Modul verwendet werden.quelle
Ich bin mir nicht sicher, ob dies irgendjemandem helfen wird. Ich begann an einem großen Projekt mit vielen Abhängigkeiten zu arbeiten, das mir den gleichen Fehler verursachte. Mein Kollege schlug mir vor,
watchman
mit Brew zu installieren , und das hat dieses Problem für mich behoben.Bearbeiten am 26. Juni 2019: Github Link zum Wächter
quelle
Ich bin heute auf dieses Problem gestoßen, und da ich keine guten Lösungen dafür gefunden habe, habe ich ein Modul erstellt, um es anzugehen. Ich war von @ fbarthos Snippet inspiriert, wollte aber vermeiden, das fs-Modul zu überschreiben.
Das Modul, das ich geschrieben habe, ist Filequeue , und Sie verwenden es genau wie fs:
quelle
Sie lesen zu viele Dateien. Der Knoten liest Dateien asynchron, er liest alle Dateien gleichzeitig. Sie lesen also wahrscheinlich das 10240-Limit.
Überprüfen Sie, ob dies funktioniert:
quelle
Wie wir alle sind Sie ein weiteres Opfer asynchroner E / A. Wenn Sie bei asynchronen Aufrufen viele Dateien durchlaufen, öffnet Node.js für jede zu lesende Datei einen Dateideskriptor und wartet dann auf eine Aktion, bis Sie sie schließen.
Der Dateideskriptor bleibt geöffnet, bis auf Ihrem Server eine Ressource zum Lesen verfügbar ist. Selbst wenn Ihre Dateien klein sind und das Lesen oder Aktualisieren schnell ist, dauert es einige Zeit, aber gleichzeitig hört Ihre Schleife nicht auf, den Deskriptor für neue Dateien zu öffnen. Wenn Sie also zu viele Dateien haben, ist das Limit bald erreicht und Sie erhalten eine schöne EMFILE .
Es gibt eine Lösung: Erstellen einer Warteschlange, um diesen Effekt zu vermeiden.
Dank der Leute, die Async geschrieben haben , gibt es dafür eine sehr nützliche Funktion. Es gibt eine Methode namens Async.queue . Sie erstellen eine neue Warteschlange mit einem Limit und fügen der Warteschlange dann Dateinamen hinzu.
Hinweis: Wenn Sie viele Dateien öffnen müssen, ist es eine gute Idee, zu speichern, welche Dateien gerade geöffnet sind, und sie nicht unendlich erneut zu öffnen.
Sie können sehen, dass jede Datei zur Warteschlange hinzugefügt wird (Dateiname console.log), jedoch nur, wenn die aktuelle Warteschlange unter dem zuvor festgelegten Grenzwert liegt.
async.queue Informationen über die Verfügbarkeit der Warteschlange über einen Rückruf abrufen. Dieser Rückruf wird nur aufgerufen, wenn die Datendatei gelesen wird und alle erforderlichen Aktionen ausgeführt werden. (siehe fileRead-Methode)
Sie können also nicht vom Dateideskriptor überwältigt werden.
quelle
Ich habe gerade ein kleines Stück Code geschrieben, um dieses Problem selbst zu lösen. Alle anderen Lösungen scheinen viel zu schwer zu sein und erfordern, dass Sie Ihre Programmstruktur ändern.
Diese Lösung blockiert nur alle fs.readFile- oder fs.writeFile-Aufrufe, sodass zu einem bestimmten Zeitpunkt nicht mehr als eine festgelegte Nummer im Flug ist.
quelle
Ich habe alle oben genannten Dinge für das gleiche Problem getan, aber nichts hat funktioniert. Ich habe unten versucht, es hat 100% funktioniert. Einfache Konfigurationsänderungen.
Option 1 festgelegtes Limit (funktioniert meistens nicht)
Überprüfen Sie das verfügbare Limit
Option 2 Um das verfügbare Limit auf 65535 zu erhöhen
Fügen Sie die folgende Zeile hinzu
Führen Sie dies aus, um mit der neuen Konfiguration zu aktualisieren
Bearbeiten Sie die folgende Datei
Fügen Sie die folgenden Zeilen hinzu
Bearbeiten Sie die folgende Datei
füge diese Zeile hinzu
Melden Sie sich ab und melden Sie sich an und versuchen Sie den folgenden Befehl
Option 3 Fügen Sie einfach die folgende Zeile hinzu
zu /etc/systemd/system.conf und /etc/systemd/user.conf
quelle
Mit Dudelsack brauchen Sie nur Wechselgeld
=>
Der Dudelsack hilft Ihnen, die Parallele zu begrenzen. Weitere Details: https://github.com/JacksonTian/bagpipe
quelle
Hatte das gleiche Problem beim Ausführen des Befehls nodemon, so dass ich den Namen der in erhabenem Text geöffneten Dateien reduzierte und der Fehler verschwand.
quelle
EMFILE
Fehler und durch Versuch und Irrtum bemerkte ich, dass das Schließen einiger Sublime- Fenster das Problem löste. Ich weiß immer noch nicht warum. Ich habe versuchtulimit -n 2560
, mein .bash_profile zu erweitern, aber das hat das Problem nicht gelöst. Zeigt dies an, dass stattdessen zu Atom gewechselt werden muss?Aufbauend auf der Antwort von @ blak3r, hier eine kurze Abkürzung, die ich für den Fall verwende, dass sie anderen Diagnosen hilft:
Wenn Sie versuchen, ein Node.js-Skript zu debuggen, dem die Dateideskriptoren ausgehen, finden Sie in der folgenden Zeile die Ausgabe des
lsof
vom betreffenden Knotenprozess verwendeten:Dies wird synchron
lsof
gefiltert nach dem aktuell ausgeführten Node.js-Prozess ausgeführt und gibt die Ergebnisse über den Puffer zurück.Verwenden Sie dann
console.log(openFiles.toString())
, um den Puffer in eine Zeichenfolge zu konvertieren und die Ergebnisse zu protokollieren.quelle
cwait ist eine allgemeine Lösung zur Begrenzung der gleichzeitigen Ausführung von Funktionen, die Versprechen zurückgeben.
In Ihrem Fall könnte der Code ungefähr so aussehen:
quelle
Für Nodemon- Benutzer: Verwenden Sie einfach das Flag --ignore , um das Problem zu lösen.
Beispiel:
quelle
Verwenden Sie die neueste
fs-extra
.Ich hatte dieses Problem auf
Ubuntu
(16 und 18) mit viel Speicherplatz für Datei- / Socket-Deskriptoren (zählen mitlsof |wc -l
). Gebrauchtefs-extra
Version8.1.0
. Nach dem Update auf9.0.0
"Fehler: EMFILE, zu viele geöffnete Dateien" verschwanden.Ich habe auf verschiedenen Betriebssystemen verschiedene Probleme mit Knotenhandhabungsdateisystemen gehabt. Dateisysteme sind offensichtlich nicht trivial.
quelle
Ich hatte dieses Problem und habe es durch Laufen gelöst
npm update
und es hat funktioniert.In einigen Fällen müssen Sie möglicherweise node_modules entfernen
rm -rf node_modules/
quelle