系统设计:Feed流系统

设计支持亿级用户的Feed流系统,详解推模式与拉模式的权衡、Timline排序算法、冷热数据分离、以及社交图的分片存储策略。

系统设计:Feed 流系统

Feed 流(信息流)是社交应用的核心功能,包括微信朋友圈、微博、抖音推荐流等。核心挑战是如何在亿级用户下高效分发内容。

1. 需求分析

场景对比

产品关系内容类型分发策略
微信朋友圈双向关注UGC推模式(写扩散)
微博单向关注UGC/PGC推拉结合
抖音单向关注短视频推荐引擎
Twitter单向关注短文本推模式为主

核心指标

  • 发布延迟:< 1 秒
  • 刷新延迟:< 200ms
  • 一致性:最终一致

2. 推模式 vs 拉模式

推模式(Write Fan-out)

用户A发布内容时,推送到所有粉丝的收件箱。

发布者 → 写入自己发件箱 + 推送到所有粉丝收件箱
               ↓
          N 个粉丝收件箱

优点:读取快,直接读收件箱
缺点:大V发布时写入量巨大(1000 万粉丝 = 1000 万次写入)

拉模式(Read Fan-out)

用户刷新时,拉取所有关注者的最新内容,合并排序。

用户请求 → 获取关注列表
    ↓
读取每个关注者的发件箱
    ↓
合并排序返回

优点:发布零成本
缺点:读取慢,关注人数多时延迟高

混合模式

用户类型策略
普通用户(粉丝 < 1 万)推模式
大V(粉丝 ≥ 1 万)拉模式,或只推在线用户

3. 系统架构

发布内容 → 内容服务 → 存储系统
               ↓
         消息队列(Kafka)
               ↓
    ┌─────────┴─────────┐
    ↓                   ↓
 粉丝 < 1万            粉丝 ≥ 1万
    ↓                   ↓
 推送到收件箱          标记为拉取
(Redis List)

4. 核心设计

4.1 收件箱存储

Redis 有序集合(Sorted Set),按时间戳排序:

ZADD inbox:user_100 1695680000 "tweet:12345"
ZADD inbox:user_100 1695680100 "tweet:12346"
ZRANGE inbox:user_100 0 20 WITHSCORES  # 取最新 20 条

4.2 冷数据归档

  • 收件箱只保留最近 N 天(如 7 天)
  • 冷数据归档到 HBase / S3
  • 用户浏览历史数据时,异步加载

4.3 Timeline 排序

时间序:纯按发布时间排序(微信朋友圈)

智能排序(Edge Rank):

Score = 亲密度 × 内容质量 × 时间衰减

亲密度:互动频率
内容质量:点赞/评论/转发率
时间衰减:越新分数越高

4.4 社交图存储

关注关系用图数据库或分布式存储:

用户A 关注 [用户B, 用户C, ...]
用户B 粉丝 [用户A, 用户D, ...]

分片策略:按粉丝 ID 范围分片,或按关注者 ID 哈希分片。

5. 性能优化

预加载

用户刷新前,预加载下一页内容到缓存。

本地缓存

移动端缓存最近 N 条,减少请求。

CDN

媒体资源(图片、视频)走 CDN 加速。

6. 面试常见问题

Q: 为什么 Twitter 早期用拉模式后来改推模式?
拉模式在关注人数少时简单,但用户关注数百人后读取延迟太高。推模式用空间换时间,适合读多写少的场景。

Q: 大V的「拉模式」怎么实现高效读取?

  • 限制拉取数量(如最近 1000 条)
  • 为大V单独建缓存发件箱
  • 异步预计算大V的内容索引

Q: 如何处理删除内容?

  • 软删除(标记删除,延迟清理)
  • 发布删除指令到消息队列,异步清理各粉丝收件箱

相关文章:

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页