Добавление больших объемов данных в MySQL из Node.JS
Здравствуйте!
Задача:
Кучку больших текстовых файлов (от 1.5 до 5 Гб), в которых хранится нужная информация, нужно распарсить на Node.JS и залить в базу данных на MySQL. Задачу парсинга я решил c помощью fs.createReadStream() и модуля node-lazy, но вот с задачей добавления распарсенных данных в базу я справиться не могу. Выполняя в цикле по всем строкам файла insert в БД, Node.JS начинает разжираться до невообразимых размеров и в конце концов, будучи в 0.8 Гб оперативки, вываливается с out of memory.
Не могу разобраться в чем заключается проблема и постепенно прихожу ко мнению, что во мне, так как банальный цикл из статических однотипных инсертов не вызывает у Node ожирение.
В качестве коннектора к MySQL использую стандартный node-mysql. Задача решается на Винде. Вот код:
var lazy = require("lazy"),
fs = require("fs"),
mysql = require('mysql');
Спасибо, я знаю о таком операторе, но в условиях данной задачи он не подходит и не будет использоваться по ряду причин. Во-первых перед добавлением в базу, данные необходимо предварительно обработать, а какие-то вообще отсеять. Во-вторых все же хочется разобраться с проблемой загрузки из Node таких объемов, так как в дальнейшем это может много где помочь.
Проверяйте по частям, к примеру, закомментируйте выполнение запроса в MySQL, отработает ли скрипт? Если отработает сделайте вместо выполнения запроса, запись их в файл
Добавляйте по несколько много строк за раз
INSERT INTO `table` (`a`, `b`, `c`) VALUES (1, 1, 1), (2, 2, 2),… (n, n, n);
Отключайте индексы в начале добавления.
Видимо lazy грешит утечкой памяти. Попробуйте написать свой обработчик для stream.on('data',… ), который будет разбивать блоки текста на строки и сразу же их обрабатывать. Пример можно посмотреть здесь: github.com/j03m/node-csv2xml/blob/master/lineByline.js. В итоге получите контроль над использованием памяти.