【发布时间】:2022-01-20 03:21:55
【问题描述】:
我在 Firebase Functions 中使用 Firebase Admin SDK 来列出 Cloud Storage 上目录的内容。但是,我的功能通常需要超过 5 秒以上的时间来回答。起初我认为这都是由于函数本身的冷启动,我尝试了很多方法来防止函数的冷启动,例如:
- 将
minInstances设置为 1 或更多 - 使用 cronjob 每分钟调用一次函数(无需身份验证,因此它实际上不使用 admin sdk 但仍保持函数温暖)
- 将函数拆分为单独的文件以减少冷启动时间 (https://stackoverflow.com/a/47985480/13370504)
- 尝试将功能移近云存储(
us-central1到europe-west3)
但是,上述方法均无效,并且在第一次调用该函数时,我的响应时间仍然很慢。在函数中添加一些日志记录后,事实证明,Admin SDK 需要一秒钟多的时间才能从实时数据库中获取单个值,并且在 Cloud Storage 上运行 getFiles 命令通常需要 5 秒钟以上(目录通常只包含一个文件)。
例如,对于下面的代码,我得到以下控制台输出:
listVideos: coldstart true
listVideos: duration 1: 0ms
listVideos: duration 2: 1302ms (realtime database)
listVideos: duration 3: 6505ms (getFiles on cloud storage)
listVideos: coldstart false
listVideos: duration 1: 0ms
listVideos: duration 2: 96ms (realtime database)
listVideos: duration 3: 199ms (getFiles on cloud storage)
我的函数如下所示:
import * as admin from "firebase-admin";
admin.initializeApp();
let coldStart = true;
exports.listVideos = functions.region("europe-west1").runWith({
memory: "128MB",
minInstances: 1,
}).https.onCall(async (data, context) => {
console.log("coldstart", coldStart);
coldStart = false;
const t1 = new Date().getTime();
if (context.auth) {
const authUid = context.auth.uid;
console.log(`duration 1: ${new Date().getTime() - t1}ms`);
const level = (await admin.database().ref(`users/${authUid}/`).once("value")).val();
console.log(`duration 2: ${new Date().getTime() - t1}ms (realtime database)`);
const [files] = await admin.storage().bucket()
.getFiles({
prefix: `${authUid}/video`,
});
console.log(`duration 3: ${new Date().getTime() - t1}ms (getFiles on cloud storage)`);
return {status: "success", files: files};
} else {
return {status: "error - not authenticated"};
}
});
我知道我不能期待 0 毫秒的延迟,但是对于一个简单的 getFiles 调用,我希望在 1 秒内完成一些事情,就像 sdk “温暖”时一样(考虑到我的整个存储桶的文件少于 1000 个)并且我列出的目录中只有 1 个文件)
【问题讨论】:
-
您没有描述GCS存储桶中的数据。所以 GCS 文件大小会影响时间。另外,请记住这是一个下载,而不是一个列表,所以它都与对象的大小有关。然后,您抱怨的另一个延迟是调用 RTDB 查找的 1 秒时间。这又取决于地区。如果可能的话,我希望您在与 RTDB 相同区域的 VM 上在 CF 之外测试这些(请记住,对于 RTDB,这是由 firebase 项目创建设置的,无法更改)并测量响应时间?
-
如果结果相同,则更多地与您部署的位置和您正在拨打的电话类型有关。然后以同样的方式对 Firestore get() 重复测试。您应该记录对象的开始和结束时间,加上大小并添加 bps 计算以显示吞吐量。如果您只列出对象,一个侧面测试是看看它是否仍然很慢。
-
@PriyashreeBhadra 我的文件大小在 10-400mb 之间。根据我从文档ref 得到的信息,这些文件没有被下载(只有元数据),所以文件大小无关紧要。我在本地使用 firebase 函数模拟器运行应用程序并获得以下冷启动时间:@987654332@。有趣的是,我在 GitHub 上发现了这个问题,我认为这是我的问题的根本原因:github.com/googleapis/nodejs-storage/issues/951
-
@PriyashreeBhadra 澄清一下:我使用 firebase 模拟器在本地运行这些功能,但连接到比利时数据中心 (europe-west1) 中的实时数据库和云存储。
标签: firebase firebase-realtime-database google-cloud-functions google-cloud-storage firebase-admin