提问人:Md.Reyad Hossain 提问时间:11/15/2023 最后编辑:Md.Reyad Hossain 更新时间:11/16/2023 访问量:53
MongoDB 多租户设计面临意外的插入时间慢
MongoDB multi-tenant design faces unexpected slow insertion time
问:
我们一直在为我们的业务开发多租户模型,并使用MongoDB为我们的客户处理数据,我们的客户基本上是一些组织,他们的用户使用该系统。
现在,我们有一个单一的应用层(单一应用部署),用于控制或连接到单个集群中的多个数据库。数据库连接的变化发生在应用程序(使用 Node.js 和 Mongoose 构建)层。每个数据库都包含相同的集合,例如 db-00 和 db-01 将具有相同数量的集合,例如用户、business_units、预订、doucment_management、库存......等。
对于进入服务器的每个请求,将执行以下代码以将用户请求连接到相应的数据中心:
const MONGO_URI = < only the cluster url with user and password no /db attached here >
let databaseCluster = {};
const connect = (db) => {
mongoose.plugin(forceRunValidators);
return mongoose.createConnection(
process.env.MONGO_URI + `/${db}?retryWrites=true&w=majority`,
{
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true,
autoIndex: true,
}
);
};
// this function si called once the server starts in the server js file
exports.connectToCluster = () =>
new Promise(async (resolve, reject) => {
try {
let adminConnection = await connect(process.env.ADMIN_DB);
let tenants = await Tetants(adminConnection).find({});
databaseCluster = adminConnection;
console.log("MongoDB admin Connected");
tenantsMap = tenants;
resolve("Tenants cached successfully.");
console.log("Tenants cached successfully");
} catch (err) {
console.error(err);
reject(err);
// Exit process with failure
process.exit(1);
}
});
exports.getConnectionByTenant = (tenantName) => {
let connection = null;
connection = databaseCluster.useDb(tenantName, { useCache: true });
return connection;
};
每当编译模型时,示例代码如下所示:
const connection = getConnectionByTenant("my_tenant");
const ModelBuilder = (connection) => connection.model("collection_name",modelSchema);
const Model = ModelBuilder(connection);
最后,在数据访问层中,它被用作普通代码,如下所示:
// insert operation
const DataObject = new Model({
property_1:"some_value",
...
})
await dataObject.save();
// find operation
const data = await Model.findOne({});
该系统在本地和 Atlas 集群中也能正常工作。它按预期连接到不同的数据库。但是我们遇到了一个有线问题。
问题陈述
当只插入单个数据库时,数据库变得非常慢,例如,假设我们有db_1、db_2 db_3插入操作在db_3中变得非常慢,即使几乎没有数据并且插入一个项目大约需要 40 秒。当我们重新启动服务器时,问题会转移到不同的数据库(如db_2,db_3变得正常。我们已经确认,这个问题只发生在一个数据库上,无论我们拥有多少数据库。除了特定的数据库外,所有其他数据库都运行良好。
调查
我也尝试使用以下命令监视mongodb shell中的插入操作,但结果不是很有用。
db.currentOp({
"op": "insert"
}, true);
它始终以空数组的形式返回。inprog
{ inprog: [],
ok: 1,
'$clusterTime':
{ clusterTime: Timestamp(1, 1700042646),
signature:
{ hash: BinData(0, "z5Pv/28gd21JtFpYB0bpQBk+NTc="),
keyId: NumberLong("7244587175163985926") } },
operationTime: Timestamp(1, 1700042646) }
谁能在这个问题上提供帮助。
雷亚德
答:
我认为问题来自.useDb 将使用相同的连接池切换到不同的数据库。当您不配置连接池时,问题就在这里,默认情况下是,您的请求需要从许多数据库中保存到许多集合中,这会导致切换速度缓慢和超过 5 个连接。useDb
5
最好创建与另一个数据库的不同连接。
function makeNewConnection(uri) {
const db = mongoose.createConnection(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
serverSelectionTimeoutMS: 300000
});
db.on('error', function (error) {
console.log(`MongoDB :: connection ${this.name} ${JSON.stringify(error)}`);
db.close().catch(() => console.log(`MongoDB :: failed to close connection ${this.name}`));
});
db.on('connected', function () {
mongoose.set('debug', function (col, method, query, doc) {
console.log(`MongoDB :: ${this.conn.name} ${col}.${method}(${JSON.stringify(query)},${JSON.stringify(doc)})`);
});
console.log(`MongoDB :: connected ${this.name}`);
});
db.on('disconnected', function () {
console.log(`MongoDB :: disconnected ${this.name}`);
});
return db;
}
const connection1 = makeNewConnection(mongoConfig.uriConnection1);
const connection2 = makeNewConnection(mongoConfig.uriConnection2);
评论
dbconnections.dbconn_1
database connection singleton
上一个:admin js 中的嵌套过滤器
评论