Импорт очень большого набора записей в MongoDB с помощью nodejs - PullRequest
8 голосов
/ 08 ноября 2011

Прежде чем углубиться в свой вопрос, я хотел бы отметить, что я делаю это частично, чтобы ознакомиться с узлом и монго.Я понимаю, что, возможно, есть лучшие способы для достижения моей конечной цели, но я хочу извлечь из этого общую методологию, которая может применяться в других ситуациях.

Цель:

У меня есть CSV-файл, содержащий более 6 миллионов записей о гео-ip.Каждая запись содержит всего 4 поля, а размер файла составляет примерно 180 МБ.

Я хочу обработать этот файл и вставить каждую запись в коллекцию MongoDB, которая называется «Блоки».Каждый «Блок» будет иметь 4 поля из CSV-файла.

Мой текущий подход

Я использую mongoose для создания модели «Блок» и ReadStream для обработки файла строка за строкой.Код, который я использую для обработки файла и извлечения записей, работает, и я могу заставить его печатать каждую запись на консоли, если я хочу.

Для каждой записи в файле она вызывает функцию, которая создаетновый объект Blocks (используя mongoose), заполняет поля и сохраняет его.

Это код внутри функции, который вызывается каждый раз, когда строка читается и анализируется.Переменная «rec» содержит объект, представляющий одну запись из файла.

block = new Block();

block.ipFrom    = rec.startipnum;
block.ipTo      = rec.endipnum;
block.location  = rec.locid;

connections++;

block.save(function(err){

    if(err) throw err;
    //console.log('.');
    records_inserted++;

    if( --connections == 0 ){
        mongoose.disconnect();
        console.log( records_inserted + ' records inserted' );
    }

});

Проблема

Поскольку файл читается асинхронно,одновременно обрабатывается более одной строки, и чтение файла происходит намного быстрее, чем может записать MongoDB, поэтому весь процесс останавливается на 282000 записей и достигает 5k + одновременных соединений Mongo.Он не падает, он просто сидит, ничего не делая и, кажется, не восстанавливается, и при этом количество предметов в коллекции монго не увеличивается.

То, что я ищу, это общееподход к решению этой проблемы.Как бы я ограничил число одновременных соединений Mongo?Я хотел бы воспользоваться возможностью вставлять несколько записей одновременно, но мне не хватает способа регулирования потока.

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 22 февраля 2012

Не является ответом на конкретную ситуацию импорта из файла .csv, но вместо этого выполняется массовая вставка (и)

-> Прежде всего, нет специальных операций «массовых» вставок, в конце концов все forEach.

-> если вы попытаетесь прочитать большой файл асинхронно, который будет намного быстрее, чем процесс записи, тогда вам следует подумать об изменении вашего подхода, прежде всего выяснить, как много может обработать ваша установка (или просто хит-н-испытание).

---> После этого, измените способ чтения из файла, вам не нужно читать каждую строку из файла, асинхронно, учиться ждать, использовать forEach, forEachSeries из Async.js, чтобы снизить скорость чтения на mongodb напиши уровень, и все готово.

1 голос
/ 18 ноября 2011

Я бы попробовал параметр импорта CSV из командной строки из Mongodb - он должен делать то, что вам нужно, без необходимости писать код

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...