当数据集变大时,如何缓解firebase workers启动时间过长的问题

当数据集变大时,如何缓解firebase workers启动时间过长的问题,firebase,scalability,Firebase,Scalability,Firebase有一个有趣的功能/麻烦,当你监听一个数据引用时,你会得到所有添加到该引用的数据。因此,例如,当你监听“child_added”时,你会得到一个从一开始就添加到该引用的所有子代的重播。我们正在编写一个带有如下数据集的评论系统: /comments /sites /sites/articles /users 网站有很多文章,文章有很多评论,用户有很多评论 我们希望能够跟踪用户所做的所有评论,因此我们认为明智的做法是将评论放在单独的参考文献中,而不是按它们所属的文章进行划分。我们有一

Firebase有一个有趣的功能/麻烦,当你监听一个数据引用时,你会得到所有添加到该引用的数据。因此,例如,当你监听“child_added”时,你会得到一个从一开始就添加到该引用的所有子代的重播。我们正在编写一个带有如下数据集的评论系统:

/comments
/sites
/sites/articles
/users
网站有很多文章,文章有很多评论,用户有很多评论

我们希望能够跟踪用户所做的所有评论,因此我们认为明智的做法是将评论放在单独的参考文献中,而不是按它们所属的文章进行划分。我们有一个后端监听器,需要在新评论到达时对其进行处理,增加其子项计数,调整用户的统计数据等。。我担心的是,过了一段时间,如果这个监听器必须处理所有评论的重播,它将需要很长时间才能启动

我考虑过可能只在文章中存储评论,并在用户表中存储对每个评论的siteId/articleId/commentId的引用,这样我们仍然可以找到给定用户的所有评论,但这会使后端复杂化,因为它可能需要为每个站点甚至每个文章提供一个单独的侦听器,这可能会使管理这么多听众变得困难


想象一下,如果其中一篇文章出现在一个流量非常高的网站上,每篇文章都有上万篇文章和数千条评论。缩放是为了某种程度上跟踪每个站点的流量级别,并以分配给不同工作进程的方式对其进行设置和划分吗?关于启动时间的问题,以及每次我们加载员工时重播所有数据需要多长时间?

如果您只需要处理一次新评论,您可以将它们放在一个单独的列表中,例如新评论与已处理的评论。完成处理后,将它们从新成员移动到评论


或者,您可以像今天一样将所有评论保留在一个列表中,并向其中添加一个最初设置为true的字段,例如isNew。处理完成后,您可以使用orderByChild'isNew'。equalTotrue进行筛选并更新{isNew:false}。

如果您只需要处理一次新注释,您可以将它们放在单独的列表中,例如新注释与已处理的注释。完成处理后,将它们从新成员移动到评论


或者,您可以像今天一样将所有评论保留在一个列表中,并向其中添加一个最初设置为true的字段,例如isNew。然后,您可以使用orderByChild'isNew'。equalTotrue进行筛选,并在处理完成后更新{isNew:false}。

再加上Frank的答案,这里还有一些其他可能性

使用

因为工作人员确实希望处理一次性事件,所以给他们一次性事件,他们可以在完成处理后从队列中提取并删除这些事件。这很好地解决了多个工作者的情况,并确保不会因为服务器脱机而遗漏任何内容

利用时间戳减少积压工作

在Worker重新启动/启动期间避免积压的一个简单策略是向所有事件添加时间戳,然后执行以下操作:

var startTime = Date.now() - 3600 // an hour ago
pathRef.orderByChild('timestamp').startAt( startTime );
跟踪最后处理的id

这只适用于,因为不按键自然排序的格式在将来的某个时候可能会变得无序


在处理记录时,让您的工作人员通过将该值写入Firebase来跟踪它添加的最后一条记录。然后可以使用orderByKey.startAt lastKeyProcessed来避免积压工作。令人恼火的是,我们不得不放弃第一把钥匙。然而,这是一个高效的查询,不需要为索引花费数据存储,而且实现起来很快。

再加上Frank的答案,这里还有一些其他的可能性

使用

因为工作人员确实希望处理一次性事件,所以给他们一次性事件,他们可以在完成处理后从队列中提取并删除这些事件。这很好地解决了多个工作者的情况,并确保不会因为服务器脱机而遗漏任何内容

利用时间戳减少积压工作

在Worker重新启动/启动期间避免积压的一个简单策略是向所有事件添加时间戳,然后执行以下操作:

var startTime = Date.now() - 3600 // an hour ago
pathRef.orderByChild('timestamp').startAt( startTime );
跟踪最后处理的id

这只适用于,因为不按键自然排序的格式在将来的某个时候可能会变得无序

在处理记录时,让您的工作人员通过将该值写入Firebase来跟踪它添加的最后一条记录。然后可以使用orderByKey.startAt lastKeyProcessed来避免积压工作。令人烦恼的是,我们不得不放弃
第一把钥匙。但是,这是一种高效的查询,不需要索引的数据存储,而且实现起来很快。

如果只需要处理一次新注释,可以将它们放在单独的列表中。或者添加一个最初设置为true的字段,例如isNew。然后,您可以使用orderByChild'isNew'。equalTotrue进行筛选,并在处理完成后更新{isNew:false}。谢谢Frank。今天早上醒来时,我也有了同样的想法。你为什么不把这个贴出来作为答案呢?我不确定它是否完全回答了这个问题。我稍后会把它作为一个答案发布……如果你只需要处理一次新评论,你可以把它们放在一个单独的列表中。或者添加一个最初设置为true的字段,例如isNew。然后,您可以使用orderByChild'isNew'。equalTotrue进行筛选,并在处理完成后更新{isNew:false}。谢谢Frank。今天早上醒来时,我也有了同样的想法。你为什么不把这个贴出来作为答案呢?我不确定它是否完全回答了这个问题。我将在稍后发布它作为一个答案。。。