我正在将数据从MySQL迁移到MongoDB。
MySQL根本没有优化(没有索引)所以我的操作,1个普通的sql查询和1个sql sequelize查询每个需要大约30秒,每个返回~300k文件。
我并不担心MySQL部分,但关于node / mongo部分。
将它们插入MongoDB时,我尝试了几件事:
嗯,上面的第三个案例对我来说最有意思,因为它正在工作,给我我想要的东西,它只是表现得不太可理解。
为什么"真实"工作只在我调用更新后很久才完成?
我还消除了写入关注/回调以加快这个过程,而且它似乎有所帮助。
典型的upsert看起来像这样:
connectionb.update({ isbn13: book.isbn13 },
{ $addToSet: { ratedByUsers: insertuserrating } },
{ w: 0 });
和
connectionu.update(insertuser,
{ $addToSet: { ratedBooks: insertbookrating } },
{ upsert: true, w: 0 });
另外,我不认为我有内存泄漏,因为整体而言,后来我发现内存再次回落到几个100MB。 (不是这里 - 我把它归咎于GC是懒惰的。我确实重复运行了操作,并且看到内存再次大幅下降。)
我尝试更好地说明行为:你可以看到MySQL CPU消耗中的2个峰值,这是我预期的,因为我进行了2次查询。
MongoD不稳定地达到峰值。
MongoD和MySQL一直使用非常少的内存。
节点一直在运行全1-CPU,内存先快速增加然后慢慢减少。
我希望node.js可以减少工作量并且mongod会一直忙于尝试插入数据。此外,我对时间感到惊讶:节点表示它在大约2分钟后完成所有操作(我的所有代码都已经完成) - 但是那时候mongodb中几乎没有任何数据。
我做错了吗?
如何减少节点的内存和CPU消耗,加快数据最终到达mongodb的时间?
添加了真实代码
(删除了很多,比如我认为无关的模型和查询)。 connectionu和connectionb是与用户和书籍集合的mongodb连接。
首先,导入所有书籍,然后导入所有用户 - 由于mysql DB结构,我使用评级来确定我感兴趣的用户,并再次使用评级更新书籍集。
sequelize.query(qstring).success(function (result) {
var len = result.length;
result.forEach(function ProcessRatingResult(oneresult) {
var insertobject = {
isbn13: oneresult.isbn13,
title: oneresult.title,
};
cntwrite++;
connectionb.update({ isbn13: oneresult.isbn13 }, insertobject, { upsert: true, w: 0 });
// only start 2nd part if first part is completely finished - 135s runtime
if (cntwrite == (len - 1)) {
// start with slight delay - give mongo/node time to catch up
setTimeout(ImportRating, 10000); //2500);
}
});
});
function ImportRating() {
SQLRating.findAll({ where: {}, include: [SQLUser, SQLBook] }).success(function (sqlresult) {
async.each(sqlresult, function ProcessRatingResult(oneresult) {
var book = oneresult.book;
var user = oneresult.user;
var rating = oneresult.rating;
(function (book, user, rating) {
var insertuser = {
joined: user.created,
external_id: user.external_id
};
var insertbookrating = {
book: book.isbn13,
rating: rating
}
connectionu.update(insertuser,
{ $addToSet: { ratedBooks: insertbookrating } },
{ upsert: true, w: 0 });
var insertuserrating = {
user: user.external_id,
rating: rating
}
connectionb.update({ isbn13: book.isbn13 },
{ $addToSet: { ratedByUsers: insertuserrating } },
{ w: 0 });
})(book, user, rating);
}
,
function (err) {
throw err;
}
);
});
}