gpt4 book ai didi

node.js - Node 中 mongo 的内存问题

转载 作者:太空宇宙 更新时间:2023-11-04 01:52:49 27 4
gpt4 key购买 nike

我的 Node 应用程序面临内存问题。进行了一些堆转储,发现内存中保存了大量 mongo 对象,这导致 Node 应用程序内存不足。

我的应用程序有以下设置。

MongoDB 3.4.13

Mongoose 4.11.10(也尝试过 4.13.11 和 5.0.7)

Node 8.9.4

config.js

const clientUID = require('./env').clientUID;

module.exports = {
// Secret key for JWT signing and encryption
secret: 'mysecret',
// Database connection information
database: `mongodb://localhost:27017/app_${clientUID}`,
// Setting port for server
port: process.env.PORT || 3000,
}

我的应用程序中有多个模型。每个模型都按以下方式定义(此处仅列出其中一个模型):

模型/card.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const CardSchema = new Schema({
name: {
type: String,
unique: true,
required: true
},
macId: {
type: String,
unique: true,
required: true
},
cardTypeId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'CardType',
required: true
},
},
{
timestamps: true
});

module.exports = mongoose.model('Card', CardSchema);

在应用程序中,我需要模型并执行一些操作,如下所示:

const Card = require('./models/card');
...require other models

const config = require('./config');
mongoose.connect(config.database);

function fetchCardByMacId(macId) {
return Card.findOne({ macId }).lean().exec();
}

function updateTrackerByMacId(macId, x, y, nodeId) {
const data = {x, y, lastNodeId: nodeId};
fetchCardByMacId(macId)
.then(card => {
Tracker.findOneAndUpdate({ cardId: card._id }, data, { upsert: true, new: true }).exec((error, tracker) => {
if (error) {
return console.log('update tracker error', error);
}
TrackerHistory.findOne({ trackerId: tracker._id }).exec((err, trackerHistory) => {
if (err) {
return console.log('fetch trackerHistory error', err);
}
if (trackerHistory) {
trackerHistory.trackers.push({ x, y, timestamp: moment().format(), nodeId });
TrackerHistory.findOneAndUpdate({_id: trackerHistory._id},trackerHistory,(er, trackerHis) => {
if (er) {
return console.log('trackerHistory change update error', er);
}
})
} else {
const trackerHistoryNew = new TrackerHistory({
trackerId: tracker._id,
trackers: [{ x, y, timestamp: moment().format(), nodeId }]
});
trackerHistoryNew.save((er, trackerHis) => {
if (er) {
return console.log('trackerHistory create error', er);
}
});
}
});
});
}).catch(error => {
console.log('updateTrackerByMacId error', error);
});
}

像这样,还有许多其他读取和更新数据的函数。

每 5 秒我都会收到需要插入数据库的新数据(不超过 100kbs),并且一些旧的数据库数据也会根据这些新数据进行更新(看起来相当简单的数据库操作...读取、操作并更新回来)。

从 index.js 中,我生成了 2 个子进程,它们负责处理新数据并根据业务逻辑更新数据库。当使用事件监听器在 index.js 中接收到新数据时,我将其发送到子进程 1 以插入/更新数据库。子进程 2 在 10 秒计时器上运行以读取更新的数据,然后对数据库进行一些进一步的更新。

在我的本地 macbook pro 上运行它没有问题(记录正在使用的堆内存永远不会超过 40-50mb)。当我将其加载到 DO Ubuntu 16.04 服务器(4GB/2 个 CPU)上时,我面临内存问题。子进程在达到进程的内存阈值(~1.5gb)后退出,这对我来说似乎很奇怪。我也尝试使用 docker 容器执行此操作并看到相同的结果。在 Mac 上它运行没有问题,但在服务器上它正在消耗内存。生成堆转储显示堆中存在大量 mongo 对象。

我需要一些帮助来理解我在这里做错了什么,以及 mongo 占用服务器上这么多内存的问题是什么。

最佳答案

因此,TrackerHistory 集合的建模方式存在一个大问题。 TrackerHistory 有一个数组,每次必须将新对象添加到数组时,整个 TrackerHistory 对象就会加载到内存中,并且以给定的更新实时数据的频率,内存膨胀的速度比GC 的速度更快。

通过删除新集合中的跟踪器数组并添加对 TrackerHistory 的外键引用来修复此问题。

帮助我识别此问题的引用文章。

https://www.mongodb.com/blog/post/6-rules-of-thumb-for-mongodb-schema-design-part-1

关于node.js - Node 中 mongo 的内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49036821/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com