使用 mongoose 向数据库插入几十万条数据时 Nodejs cpu 直接 100%运行
使用 mongoose 向数据库插入几十万条数据时 Nodejs cpu 直接 100%运行
null
-----代码如下-------
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 使用率飙升。这通常是由于同步执行大量插入操作造成的。为了优化这个过程,你可以考虑以下几种方法:
- 批量插入:使用
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!'));
-
异步处理:使用
async/await
或 Promise.all 控制并发量,避免阻塞事件循环。 -
增加数据库连接池大小:Mongoose 默认连接池大小可能不足以处理大量并发请求,可以通过配置
mongoose.connect
的选项来增加连接池大小。 -
优化服务器硬件和 MongoDB 配置:确保硬件资源充足,并调整 MongoDB 的配置以优化性能。
通过这些方法,你可以显著提高数据插入的效率,降低 CPU 使用率。