Почему мой Node.js зависает при выполнении больших скриптов?

Разрабатываю API на Node.js с Express и когда тестирую с большими CSV-файлами (типа 500MB) весь процесс зависает и приходится перезагружать. Уже пробовал увеличить heap, но всё равно зависает. Кто-нибудь знает, это проблема памяти или в коде что-то не так?

2 ответа

★ Лучший ответ

Я сталкиваюсь с такой проблемой при работе с огромными базами данных, и причина почти всегда одна и та же: ты загружаешь весь файл в память перед обработкой! CSV размером 500MB становится просто монструозным при парсинге в массивы, а увеличение heap - это просто заклеить рану пластырем. Реальное решение - использовать streams: обрабатываешь строку за строкой, одновременно записывая данные в базу или файл, и Node.js даже не потребуется хранить больше чем несколько КБ за раз! Попробуй библиотеку `csv-parser` со streams или даже напиши собственный парсер с помощью `fs.createReadStream()` и событий - это полностью изменит твой подход.

Я сталкивалась с чем-то похожим, когда пыталась обработать большие файлы сразу, и поняла, что проблема была не только в памяти - это был факт того, что я загружала всё сразу в RAM. С CSV размером 500MB, если ты попытаешься прочитать весь файл и потом обработать, память кончится очень быстро. Решение - использовать streams вместо загрузки всего в память. В Node.js есть модуль `fs.createReadStream()`, который позволяет читать файл по кусочкам. Если ты работаешь с библиотеками вроде `csv-parser`, ты можешь связать streams в цепь, чтобы обрабатывать строку за строкой без перегрузки RAM.

Ещё что мне помогло - понять, что даже со streams, если твоя логика обработки медленная (вроде синхронных операций в цикле, запросы в БД без batch-обработки), ты создашь узкое место. Когда stream поставляет данные быстрее, чем ты их обрабатываешь, память накапливается и так же. Используй `pause()` и `resume()`, чтобы управлять потоком, или правильно реализуй back-pressure. Если ты делаешь запросы в БД для каждой строки, группируй их в batch - типа, собери 1000 строк и сделай одну операцию вместо 1000 отдельных.

Какая примерно операция у тебя с данными CSV? И ты сохраняешь результаты куда-нибудь (файл, база данных) или просто обрабатываешь и возвращаешь через API? Ответ важен, потому что проблема может быть и в том, как ты отправляешь ответ клиенту.

gabriel_oliveira автор вопроса Обрабатываю данные и сохраняю сразу в БД без батча. Попробую работать со streams и группировать запросы порциями по 1000, спасибо!

Ваш ответ

Войдите, чтобы ответить.