在社交网络上设计feed / twitter系统时,我们都知道push(写出时的扇出)与pull(读取时的扇出)。
在推送模式下,每当作者生成新帖子时,我们都会写入作者朋友(或帖子)的更新列表(帖子,推文等),这样他们的关注者就不需要查询所有帖子了他们的追随者每次喂食。
在拉动模式下,我们让追随者每次需要查看他朋友的所有饲料时都会查询所有流动的朋友的饲料。
但在这两种情况下,通常使用什么机制来让人们在网站上实时查看更新的Feed? (我认为FB或Twitter不需要你手动刷新页面来查看朋友的新帖子)。
让我们说约翰写了一篇帖子,并且在推送模式下,它推送(写入SQL或redis缓存)这篇帖子指向他所有朋友的提要,他的一个朋友的浏览器怎么会知道现在有更新来自约翰?
答案 0 :(得分:2)
我假设您有一个动态(SPA)前端。
在拉动模式下,您有两个选择:
定期重新获取提要数据,每次发送最后一次查询时间时,仅过滤新的提要项。在开始新项目时,这种方法效果很好,但伸缩性不佳。
有一个消息代理,在其中创建新帖子后,您需要将事件发布到可能更新了提要的所有在线客户端,稍后在客户端接收此类事件后重新加载提要。您还可以在事件有效负载本身中包含新内容。
在推送模式下:
定期重新获取Feed数据(由于您的Feed查询并不复杂,因此性能开销要小得多。)
当您要推送时,请检查客户端是否具有活动连接并同时发布事件。
通常人们使用混合方法:
对于拥有大量活跃消费者(上个月至少登录一次)的生产者,请使用pull方法。
对于活动消费者数量较少的生产者,请使用push方法。
在推入方法中,具有用户提要中项目数量的容量非常重要。如果用户请求更多提要项目,则可以退后至仅提款。同样,由于有容量,您不需要推送给不活动的用户(可能会在新的供稿项登录之前将其替换为新的供稿项)。
答案 1 :(得分:0)
这是系统设计面试中的一个常见问题。通常要求申请 FAANG 或类似公司的后端软件工程师。
我从 Facebook 的论文中了解到为什么他们更喜欢在他们的 TAO Graph 数据库中使用推送模型,该数据库用于发布帖子、喜欢等的时间线。
<块引用>一个 Facebook 页面可以聚合和过滤数百个项目 从社交图。 我们为每个用户提供量身定制的内容 他们,我们通过隐私检查过滤每个项目 帐户当前查看者。
这种极端的定制使它 当内容无法执行大多数聚合和过滤时 被建造;相反,我们解决数据依赖性并检查隐私 每次查看内容时。我们尽可能地拉 社交图谱,而不是推动它。
这种实现策略对图数据存储提出了极高的读取需求; 它必须高效、高度可用,并且可以扩展到高查询率。
– 2013 年的论文,TAO:Facebook 的社交图谱分布式数据存储
Twitter 中还使用了另一种方法——推送方法。 我还没有调查过 Twitter 为何使用它来预先填充推文的个人时间线的任何来源。