首页 > 其他分享 >2 新鲜事系统设计(Twitter, 朋友圈)

2 新鲜事系统设计(Twitter, 朋友圈)

时间:2023-02-04 11:13:35浏览次数:44  
标签:Feed Pull Twitter Cache 新鲜事 用户 朋友圈 Push News

新鲜事系统设计

Twitter, 朋友圈

新鲜事系统的核心因素?

关注与被关注, 每个人看到的新鲜事都是不同的.

Pull Model

算法: 在用户查看 New Feed 时, 获取每个好友的前 100 条 Tweets, 合并出前 100 条 News Feed. (K 路归并算法)

复杂度分析: 假如有 N 个关注的对象, 则为 N 次DB Reads 的时间 + K 路归并的时间 (可忽略, 因为访问磁盘速度远远慢于运算速度)

Pull 模型有什么缺陷

Pull 模型每次用户刷新, 都需要现算, 需要一定的时间, 体验不好.

Push Model

算法:

  • 为每一个用户建立一个 List 存储他的 News Feed 信息.

  • 每一个用户发送一个 Tweet 之后, 将该推文推送到每个用户的 News Feed List 中. (Fanout)

  • 用户需要查看 News Feed 时, 只需要从该 News Feed List 中读取最新的 100 条即可.

复杂度分析:

  • News Feed: 1 次 DB read

  • Post a tweet: N 个粉丝, 需要 N 次 DB writes. 但是好处是可以用异步任务在后台执行, 无需用户等待.

可以异步在后台执行, 无序用户等待

News Feed Table
id primary key
owner_id (接收 News 的用户) foreign key
tweet_id foreign key
created_at timestamp
graph LR; A((西毒)) --> B((东邪)) A --> C((郭靖)) B --> D((黄蓉)) B --> C C --> D D --> C;

东邪发了一条帖子: 好想念超风

西毒发了一条帖子: 好想念嫂子

郭靖发了一条帖子: 不知道华筝怎么样了

黄蓉发了一条帖子: 男人都不是好东西

id owner_id tweet_id created_at
1 东邪 好想念超风 No1
2 西毒 好想念超风 No1
3 西毒 好想念嫂子 No2
4 郭靖 不知道华筝怎么样了 No3
5 东邪 不知道华筝怎么样了 No3
6 西毒 不知道华筝怎么样了 No3
7 黄蓉 不知道华筝怎么样了 No3
8 黄蓉 男人都不是好东西 No4
9 郭靖 男人都不是好东西 No4
10 东邪 男人都不是好东西 No4

黄蓉登录后, 可以看到的帖子通过一句 SQL 查询就可以拿到:

select * from news_feed_table where owner_id = 黄蓉 order by created_at desc limit 20;

如上的 SQL 语句怎么建立索引呢?

应该建立一个复合索引, 先按照 owner_id 排序, 再按照 created_at desc 来排序. 不能单独建立 owner_id 的索引或者单独建立 created_at desc 的索引, 因为查询的时候都是复合条件的, 单个索引没有用. 怎么查的决定怎么建立的索引.

Push Model 有什么缺陷

有些大V有很多粉丝, 那么发送一条 Tweet 在数据库中创建的记录就会非常巨大, 开销非常大.

怎么选呢

先看看热门 Social APP 的模型

  • Facebook: Pull

  • Instagram: Pull + Push

  • Twitter: Pull

  • 朋友圈: Push

Facebook, Instagram, Twitter 的 News Feed 都需要进行实时的运算, 而不是单单使用时间来进行排序, 所以需要 Pull 模型来实时进行运算. 而朋友圈只按照时间展示动态, 所以在发布动态的时候就可以仅仅按照时间插入到 News Feed List 中, 可以使用 Push 模型.

误区

  • 不坚定想法, 摇摆不定

  • 不能表现出 Tradeoff 能力

  • 无法解决特定的问题

Scale 扩展

1 解决 Pull 的缺陷

最慢的部分发生在用户读请求时(需要消耗用户等待时间)

  • 在 DB 访问之前加入 Cache

  • Cache 每个用户发过的帖子

    • N 个 DB 请求 --> N 次 Cache 请求 (N是关注的好友个数)

    • Trade off? Cache 用户发布的所有帖子? Cache 用户发布最近 1000 条帖子?

  • Cache 每个用户的 News Feed (可能刷的过于频繁, 关注的人没有在这段时间发布帖子)

    • 没有 Cache News Feed 的用户: 归并 N 个用户最近的 100 条结果, 取出结果的前 100 条.

    • 有 Cache News Feed 的用户: 归并 N 个用户在某个时间戳 (上次 Cache News Feed 的时间) 之后的 Tweets.

2 解决 Push 的缺陷

Push 的机制就是写扩散

  • 浪费更多的存储空间 Disk

    • 与 Pull 模型将 News Feed 存储在内存中相比很便宜

    • Disk is cheap

  • 不活跃用户

    • 粉丝排序
  • 粉丝数目 followers >> 关注数目: 大V粉丝及其多, 他们发布的一条帖子会 fanout 出几千万的记录.

面试时错误的回答方案: 既然 Push 不行, 那我们就切换成 Pull 吧. 这样肯定不可以, 因为前面可能已经构建完毕, 才发现这个问题, 如果草率切换, 以前的工作全部白费.

前期用户少, 可以使用 push 模型, 节省 pull 模型可能的内存开销. 后期用户多了, 可以进行重构, 重构为 pull 模型.

3 Push + Pull 优化方案

  • 普通的用户仍然 Push

  • 将大V标记为明星用户, 不 Push 到用户的 News Feed 中.

  • 当用户需要时, 来明星用户的 Timeline 中获取, 并整合进入 News Feed 中.

4 总结

系统面试不只是期望你答出来最优的解决方法, 而是从你的分析当中判断你对系统的理解和知识的储备.

  • 什么时候用 Push?

    • 资源少 (用 Disk 即可)

    • 实时性要求不高

    • 代码简洁

    • 用户少, 明星用户少

  • 什么时候用 Pull?

    • 资源充足 (Cache 多)

    • 实时性要求较高

    • 用户发帖多

    • 用户多, 有明星用户

标签:Feed,Pull,Twitter,Cache,新鲜事,用户,朋友圈,Push,News
From: https://www.cnblogs.com/geraldkohn/p/17091096.html

相关文章