【发布时间】:2019-05-29 05:19:31
【问题描述】:
我使用 bluebirds Promise.map() 方法运行 100,000 个 firebase 查询,如下所示,该函数运行大约需要 10 秒。如果我将并发设置为高于 1000,那么我会收到错误
超过最大调用堆栈大小
关于如何解决此问题以及如何加快此问题的任何想法。在我看来,也许 Promise.map() 可能不是正确使用的函数,或者我可能以某种方式对内存管理不善。任何想法谢谢。
exports.postMadeByFriend = functions.https.onCall(async (data, context) => {
const mainUserID = "hJwyTHpoxuMmcJvyR6ULbiVkqzH3";
const follwerID = "Rr3ePJc41CTytOB18puGl4LRN1R2"
const otherUserID = "q2f7RFwZFoMRjsvxx8k5ryNY3Pk2"
var refs = [];
for (var x = 0; x < 100000; x += 1) {
if (x === 999) {
const ref = admin.database().ref(`Followers`).child(mainUserID).child(follwerID)
refs.push(ref);
continue;
}
const ref = admin.database().ref(`Followers`).child(mainUserID).child(otherUserID);
refs.push(ref);
}
await Promise.map(refs, (ref) => {
return ref.once('value')
}, {
concurrency: 10000
}).then((val) => {
console.log("Something happened: " + JSON.stringify(val));
return val;
}).catch((error) => {
console.log("an error occured: " + error);
return error;
})
编辑
const runtimeOpts = {
timeoutSeconds: 300,
memory: '2GB'
}
exports.postMadeByFriend = functions.runWith(runtimeOpts).https.onCall(async (data, context) => {
const mainUserID = "hJwyTHpoxuMmcJvyR6ULbiVkqzH3";
const follwerID = "Rr3ePJc41CTytOB18puGl4LRN1R2"
const otherUserID = "q2f7RFwZFoMRjsvxx8k5ryNY3Pk2"
var refs = [];
for (var x = 0; x < 100000; x += 1) {
if (x === 999) {
const ref = admin.database().ref(`Followers`).child(mainUserID).child(follwerID)
refs.push(ref);
continue;
}
const ref = admin.database().ref(`Followers`).child(mainUserID).child(otherUserID);
refs.push(ref);
}
await Promise.map(refs, (ref) => {
return ref.once('value')
}, {
concurrency: 10000
}).then((val) => {
console.log("Something happened: " + JSON.stringify(val));
return val;
}).catch((error) => {
console.log("an error occured: " + error);
return error;
})
【问题讨论】:
-
你真的需要做这 100.000 次查询吗?您似乎希望向用户展示朋友发布的帖子。您也许可以使用无限滚动系统来加载 100 个帖子,然后当用户到达页面末尾时,它会自动加载下一个 100 个
-
您正在检索 100.000 次相同的
mainUserID-follwerID组合。这毫无意义.. -
与例如
1000相比,您是否获得了更好的性能?500。更高的concurrency并不意味着更好的性能,尤其是瓶颈肯定是网络连接(或一般的 API 连接)。 -
回答:不要。您正在对第三方 API 进行并发调用,16-50 范围内的并发限制是绝对最大值。您只是要求限制速率。我会调查(a)您是否需要这些查询,(b)如果您需要它们,请在速度不那么重要的后台工作人员中进行。
-
@Weedoze 不幸的是,这是我基于此 asnwer stackoverflow.com/questions/53952903/… 能想出的唯一解决方案,本质上用户选择了一个标签,我想从一个标签中显示他们的关注者帖子高于另一个与标签有关的帖子。我能想到的最好方法是根据发布到特定标签的用户列表检查每个朋友
标签: javascript node.js promise es6-promise bluebird