使用nodejs脚本将GB的数据从MongoDB迁移到Cassandra的最佳方法

时间:2017-03-14 16:08:23

标签: node.js mongodb cassandra

我在MongoDB中有一个很大的集合。想要通过在该数据上运行一些业务逻辑nodejs脚本来迁移所有数据到cassandra。做这个的最好方式是什么 ?

我制作了一个脚本,我在mongo的单个请求中获取5000个文档并处理数据并将文档插入cassandra。 40-50次迭代后需要很长时间。 CPU使用率显示为100%。这是因为发生了很多回调吗?我是节点js的新手,因此无法得出任何结论.var cassandra = require('../ models / tracking_cassandra');     var TrackingEvents = require('../ models / tracking_mongo_events');

var counter = 0;
var incr = 5000;
var final_counter = 0;

var start_point = function (callback){
    TrackingEvents.count(function(err, data){
        final_counter = data;
        TrackingEvents.getEventsByCounter(counter, function(counter, obj) {
            var prevId = obj[0].toObject()._id;
            getMessagesFromMongo(prevId, callback);
        });
    });
};

function getMessagesFromMongo(prevId, callback){
    counter = counter + incr;
    TrackingEvents.getEventsByCounter(counter, function(counter, obj) {
        var nextId = obj[0].toObject()._id;
        var start_time = new Date();
        TrackingEvents.getEventsBtwIds(prevId, nextId, function ( err, userEvents ) {
            if(userEvents.length !== 0){
                insert_into_cassandra( userEvents, callback );
            }else{
                console.log('empty data set');
            }
        });
        if(counter >= final_counter){
            callback();
        }else{
            getMessagesFromMongo(nextId, callback);
        }
    });
};

var insert_into_cassandra = function( events, callback ){
    var inserts = 0;
    total_documents = total_documents + events.length;
    for(var i = 0 ; i< events.length ; i++){
        var userEventData = events[i].toObject();
        if(typeof userEventData.uid == 'undefined'){
            total_nuid ++;
        }else{
            create_cassandra_query( userEventData );
        }
    }
};

var create_cassandra_query = function ( eventData ) {
    delete eventData._id;
    delete eventData[0];
    delete eventData.appid;
    delete eventData.appversion;
    var query = "INSERT INTO userwise_events ";
    var keys = "(";
    var values = "(";
    for(var key in eventData){
        if(eventData[key] == null || typeof eventData[key] == 'undefined'){
            delete eventData[key];
        }
        if (eventData.hasOwnProperty(key)) {
            keys = keys + key + ', ';
            values = values + ':' + key + ', ';
        }
        if(key != 'uid' && key!= 'date_time' && key != 'etypeId'){
            eventData[key] = String(eventData[key]);
        }
    }
    keys = keys.slice(0, -2);
    values = values.slice(0, -2);
    keys = keys + ")";
    values = values + ")";
    query = query + keys + " VALUES " + values;
    cassandra.trackingCassandraClient.execute(query, eventData, { prepare: true }, function (err, data) {
        if(err){
            console.log(err);
        }
    });
};

var start_time = new Date();
start_point(function(res, err){
    var end_time = new Date();
    var diff = end_time.getTime() - start_time.getTime();
    var seconds_diff = diff / 1000;
    var totalSec = Math.abs(seconds_diff);
    console.log('Total Execution Time : ' + totalSec);
});

process.on('uncaughtException', function (err) {
    console.log('Caught exception: ' + err);
});`

1 个答案:

答案 0 :(得分:2)

  

这是因为发生了很多回调吗?

对于我所知道的所有内容,可能根本没有回调 - 无法告诉您代码中的问题是什么,即使只包含一行代码。

对于这样一个模糊的问题,我只能给你一个一般的建议:确保你没有长时间运行forwhile循环。并且除了事件循环的第一个刻度之外,不要在其他任何地方使用阻塞系统调用。如果您不知道事件循环的第一个标记是什么,那么根本不使用阻止调用。只要你可以,就可以使用数据流来获取数据 - 特别是如果你有很多数据。

100%的CPU利用率是一个不好的迹象,对于I / O繁重的操作(例如您尝试执行的操作)不应该发生。您应该能够轻松处理大量数据,尤其是在使用流时。让您的进程最大化CPU以进行固有的I / O绑定操作,例如通过网络移动大量数据,这肯定表明您在代码中做错了。究竟是什么?这仍然是一个谜,因为你甚至没有向我们展示你的代码。