作者:用户19910071 | 来源:互联网 | 2023-05-21 11:18
Firebase有一个有趣的功能/滋扰,当您收听数据引用时,您将获得所有已添加到该引用的数据.因此,例如,当您收听'child_added'时,您将获得从一开始就添加到该ref的所有孩子的重播.我们正在编写一个评论系统,其数据集看起来像这样:
/comments
/sites
/sites/articles
/users
网站有很多文章和文章有很多评论,用户有很多评论.
我们希望能够跟踪用户所做的所有评论,因此我们认为将评论放在单独的ref中是明智的,而不是根据它们所属的文章对它们进行分区.我们有一个后端监听器,它需要在新的评论到达时做一些事情(增加他们的子计数,调整用户的统计数据等).我担心的是,经过一段时间后,如果它必须处理所有评论的重播,那么这个听众需要很长时间才能启动.
我想过可能只在文章中存储注释并在每个注释中存储对每个注释的siteId/articleId/commentId的引用,这样我们仍然可以找到给定用户的所有注释,但这会使后端变得复杂,因为它可能需要每个站点甚至每篇文章都有一个单独的监听器,这可能使管理这么多听众变得困难.
想象一下,如果这些文章中的一篇文章位于人流量很大的网站上,每篇文章都有成千上万的文章和数千条评论.缩放答案是否以某种方式跟踪每个站点的流量级别,并以分配给不同工作进程的方式对它们进行设置和分区?那么启动时间的问题以及每次加载工作人员时重播所有数据需要多长时间?
1> Kato..:
除了弗兰克的答案之外,还有其他几种可能性.
使用队列策略
由于工作人员真的希望处理一次性事件,然后给他们一次性事件,他们可以从队列中提取并在完成处理后删除.这样可以优雅地解决多工作方案,并确保在服务器脱机时不会遗漏任何内容
利用时间戳来减少积压
在工作重启/启动期间避免积压的简单策略是为所有事件添加时间戳,然后执行以下操作:
var startTime = Date.now() - 3600 // an hour ago
pathRef.orderByChild('timestamp').startAt( startTime );
跟踪最后处理的ID
这仅适用于push id,因为未按键自然排序的格式可能会在将来的某个时候出现故障.
处理记录时,让您的工作人员通过将该值写入Firebase来跟踪其添加的最后一条记录.然后可以orderByKey().startAt( lastKeyProcessed )
用来避免积压.令人讨厌的是,我们不得不丢弃第一把钥匙.但是,这是一种有效的查询,不会为索引花费数据存储,并且可以快速实现.