【发布时间】:2020-12-10 01:20:51
【问题描述】:
在某些情况下,我的应用可能有大量的写入、读取和更新(甚至可以超过 10000 次)。
在本地开发应用程序时,这些操作通常最多需要几秒钟(太棒了!)但是,在谷歌云上运行应用程序时很容易需要几分钟,以至于 Firebase 函数超时。
我在一个单独的项目中开发了一个受控测试,其唯一目的是编写、获取和删除数千个项目以进行基准测试。这些是结果(从几次测试中得出的平均值):
Local Emulator:
5000 items, 4.2s write, 2.2s delete
5000 items, batch mode ON, 0.75s write, 0.11s delete
Cloud Firestore:
100 items, 15.8s write, 14.5s delete
1000 items, batch mode ON, 4.8s write, 3.0s delete
5000 items, async mode ON, 10.2s write, 8.0s delete
5000 items, batch & async ON, 4.5s write, 3.9s delete
注意:每当我尝试异步执行数据库操作时,我的本地模拟器就会崩溃(这又是一个问题),但这就是为什么我无法在本地异步测试写入/删除速度的原因。此外,写入和读取值通常在运行之间变化 +-25%。
但是,如您所见,与云中最快的测试相比,我的本地模拟器在其最慢模式下的速度更快,这一事实肯定会引发一些问题。
可能是我有某种配置问题吗?还是仅仅是这些数字是 Firestore 的标准?如果您想尝试,这里是(总结的)打字稿代码:
functions.runWith({ timeoutSeconds: 540, memory: "2GB" }).https.onRequest(async (req, res) => {
//getting the settings from the request
var data = req.body;
var numWrites: number = data.numWrites;
var syncMode: boolean = !data.asyncMode;
var batchMode: boolean = data.batchMode;
var batchLimit: number = data.batchLimit;
//pre-run setup
var dbObj = {
number: 123,
string: "abc",
boolean: true,
object: { var1: "var1", num1: 1 },
array: [1, 2, 3, 4]
};
var collection = db.collection("testCollection");
var startTime = moment();
//insert requested number of items, using requested settings
var allInserts: Promise<any>[] = [];
if (!batchMode) { //sequential writes
for (var i = 0; i < numWrites; i++) {
var set = collection.doc().set(dbObj);
allInserts.push(set);
if (syncMode) await set;
}
} else { //batch writes
var batch = db.batch();
for (var i = 1; i <= numWrites; i++) {
batch.set(collection.doc(), dbObj);
if (i % batchLimit === 0) {
var commit = batch.commit();
allInserts.push(commit);
batch = db.batch();
if (syncMode) await commit;
}
}
}
//some logging information. Getting items to delete
var numInserts = allInserts.length;
await Promise.all(allInserts);
var insertTime = moment();
var alldocs = (await collection.get()).docs;
var numDocs = alldocs.length;
var getTime = moment();
//deletes all of the items in the collection
var allDeletes: Promise<any>[] = [];
if (!batchMode) { //sequential deletes
for (var doc of alldocs) {
var del = doc.ref.delete();
allDeletes.push(del);
if (syncMode) await del;
}
} else { //batch deletes
var batch = db.batch();
for (var i = 1; i <= numDocs; i++) {
var doc = alldocs[i - 1];
batch.delete(doc.ref);
if (i % batchLimit === 0) {
var commit = batch.commit();
allDeletes.push(commit);
batch = db.batch();
if (syncMode) await commit;
}
}
}
var numDeletes = allDeletes.length;
await Promise.all(allDeletes);
var deleteTime = moment();
res.status(200).send(/* a whole bunch of metrics for analysis */);
});
编辑:澄清一下,UI 不执行这些写入操作,因此最终用户机器和云服务器之间的延迟(理论上)应该不会导致任何重大延迟问题。与数据库的通信完全由Firebase Functions
编辑 2:我在两个部署中运行了这个测试,一个在欧洲,另一个在美国。两者的运行时间差不多,尽管我对这两个服务器的 ping 有很大不同
【问题讨论】:
标签: node.js typescript firebase google-cloud-firestore google-cloud-functions