Pourquoi mon Node.js se bloque quand j'exécute de grands scripts ?

Je développe une API en Node.js avec Express et quand je teste avec de gros fichiers CSV (genre 500MB) le processus entier se bloque et je dois redémarrer. J'ai déjà essayé d'augmenter le heap mais ça continue à se bloquer. Quelqu'un sait si c'est vraiment un problème de mémoire ou si j'ai un truc qui cloche dans mon code ?

2 réponses

★ Meilleure réponse

J'ai des problèmes comme ça avec des bases de données énormes et c'est presque toujours la même raison : tu charges le fichier entier en mémoire avant de le traiter ! Un CSV de 500MB devient absolument monstrueux une fois parsé en arrays, et augmenter la heap c'est juste mettre un pansement sur une blessure. La vraie solution c'est d'utiliser les streams - tu traites ligne par ligne pendant que tu écris les données dans une base de données ou un fichier, et Node.js n'aura besoin de stocker que quelques KB à la fois ! Essaie avec la library `csv-parser` avec des streams ou même écrire un parser custom avec `fs.createReadStream()` et les événements, ça change complètement ton jeu.

J'ai vécu quelque chose de similaire quand j'ai essayé de traiter de gros fichiers d'un coup et j'ai réalisé que le problème n'était pas juste la mémoire - c'était le fait que je chargeais tout d'un coup en RAM. Avec un CSV de 500MB, si tu essaies de lire le fichier entier et ensuite le traiter, tu vas manquer de mémoire très vite. La solution c'est d'utiliser des streams au lieu de charger tout en mémoire. Dans Node.js tu as le module `fs.createReadStream()` qui te permet de lire le fichier petit à petit. Si tu utilises des bibliothèques comme `csv-parser`, tu peux enchaîner les streams pour traiter ligne par ligne sans surcharger la RAM.

Un truc qui a aussi changé pour moi c'est de réaliser que même avec les streams, si ta logique de traitement est lente (genre des opérations synchrones dans la boucle, des requêtes à la BD sans batch), tu vas créer un goulot d'étranglement. Quand le stream fournit les données plus vite que tu ne peux les traiter, la mémoire s'accumule quand même. Utilise `pause()` et `resume()` pour contrôler le flux, ou implémente correctement la contre-pression. Si tu fais des requêtes à la base de données pour chaque ligne, mets-les en batch - genre, groupe 1000 lignes et fais une seule opération au lieu de 1000 séparées.

C'est quoi plus ou moins l'opération que tu fais avec les données du CSV? Et tu sauvegardes les résultats quelque part (fichier, base de données) ou tu traites juste et tu renvoies par l'API? La réponse aide parce que le problème pourrait aussi venir de la façon dont tu envoies la réponse au client.

gabriel_oliveira asker Je traite les données et je les sauvegarde directement en base, sans batch. Je vais tester avec des streams et grouper les requêtes par lots de 1000, merci !

Votre réponse

Se connecterpour répondre.