使用 mongoose 向数据库插入几十万条数据时 Nodejs cpu 直接 100%运行

发布于 1周前 作者 zlyuanteng 来自 nodejs/Nestjs

使用 mongoose 向数据库插入几十万条数据时 Nodejs cpu 直接 100%运行
null

3 回复

-----代码如下-------
function readByfile(value,mongodb){
let readPath=path.resolve(__dirname,‘json/json/’+value);
let data = fs.readFileSync(readPath,‘utf-8’);
mongodb.insertMany(JSON.parse(data),function(err){
console.log(err);
});
}
function readDir(dirpath){
let files = fs.readdirSync(dirpath);
_.each(files , function(value){
if(value.startsWith(‘authors.song’)){
readByfile(value,song_author)
}else if(value.startsWith(‘authors.tang’)){
readByfile(value,tang_author)
}else if(value.startsWith(‘poet.tang’)){
readByfile(value,tang_poet)
}else if(value.startsWith(‘poet.song’)){
readByfile(value,song_poet)
}
});
}


改成流处理

在处理大量数据插入时,Node.js 和 Mongoose 可能会遇到性能瓶颈,导致 CPU 使用率飙升。这通常是由于同步执行大量插入操作造成的。为了优化这个过程,你可以考虑以下几种方法:

  1. 批量插入:使用 bulkWrite 方法来批量插入数据,而不是逐条插入。
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const dataSchema = new Schema({ name: String });
const Data = mongoose.model('Data', dataSchema);

async function bulkInsert(dataArray) {
    const batchSize = 5000;  // 每次批量插入的数据量
    for (let i = 0; i < dataArray.length; i += batchSize) {
        const batch = dataArray.slice(i, i + batchSize);
        await Data.bulkWrite(batch.map(data => ({ insertOne: { document: data } })));
    }
}

// 使用示例
const data = Array.from({ length: 100000 }, (_, i) => ({ name: `Item ${i}` }));
bulkInsert(data).then(() => console.log('Done!'));
  1. 异步处理:使用 async/await 或 Promise.all 控制并发量,避免阻塞事件循环。

  2. 增加数据库连接池大小:Mongoose 默认连接池大小可能不足以处理大量并发请求,可以通过配置 mongoose.connect 的选项来增加连接池大小。

  3. 优化服务器硬件和 MongoDB 配置:确保硬件资源充足,并调整 MongoDB 的配置以优化性能。

通过这些方法,你可以显著提高数据插入的效率,降低 CPU 使用率。

回到顶部