Feed流系统设计(一):从RSS到信息流,理解Feed流的本质
写在前面
做互联网开发这么多年,Feed流这个东西几乎无处不在。朋友圈是Feed流,微博首页是Feed流,抖音刷到的那些视频也是Feed流。甚至很多App里那个叫"动态"或者"发现"的tab,本质上都是Feed流。
但真要让你从零设计一个Feed流系统,可能很多人会犯怵。不是因为技术多难,而是因为Feed流涉及的东西太杂了——存储、缓存、消息队列、分发策略、分页方案,每一块都有坑。所以我想花几篇文章的篇幅,把Feed流系统从头到尾捋一遍。不是那种泛泛而谈的概述,而是真正能落地的设计方案。
这一篇先不急着写代码,我们把Feed流到底是什么、怎么分类、有哪些核心概念搞清楚。磨刀不误砍柴工,后面真正做架构设计的时候会顺畅很多。
1. 什么是Feed流
Feed流说白了就是一个持续更新并展示给用户的信息流。它把用户主动订阅的多个消息源组合在一起,形成一个内容聚合器,帮助用户持续地获取最新的内容。
听起来有点抽象,举个具体的例子。你关注了20个博主,这20个博主每天会发各种内容。如果没有Feed流,你得挨个点进他们的主页去看有没有更新。但有了Feed流,系统会自动把这20个博主最新发布的内容聚合到一起,你只需要在一个页面里不断往下划就能看完。
所以Feed流最核心的能力就是两个字:聚合。
微博通过你的关注列表聚合信息源,然后按时间轴的形式推给你。抖音不需要你手动关注,而是根据你的观看时长、点赞行为生成用户画像,聚合你可能感兴趣的内容。微信朋友圈则是根据你的好友关系,聚合你朋友们发布的动态。
虽然表现形式不同,但本质都是一样的——根据某种规则把信息聚合起来,然后以流的方式呈现给用户。
2. Feed流是怎么来的
在聊怎么设计之前,先花点时间聊聊Feed流的前世今生。了解它的来龙去脉,有助于理解为什么Feed流会演变成现在这个样子。
Feed流的前身是RSS系统。RSS的全称是Really Simple Syndication,翻译过来就是"简易信息聚合"。在Web 2.0时代早期,RSS是非常主流的信息获取方式。用户可以选择订阅多个网站,比如科技博客、新闻站点,然后通过一个RSS阅读器统一查看这些网站的最新内容。
整个过程有点像订杂志——你选好了想看的杂志,杂志一出新一期就自动寄到你家。只不过RSS订阅的是网站,内容是网页上的文章。
RSS的问题在于,它能订阅的只是新闻网站和博客,而且内容形式比较单一,就是文字和图片。真正让Feed流走向大众的,是Facebook。
2006年,Facebook推出了一个叫News Feed的功能。这个功能彻底改变了信息分发的方式——订阅源从"网站"变成了"人",内容从"新闻公告"变成了"好友动态"。你可以看到朋友发了什么状态、传了什么照片、加了什么好友。内容丰富程度直线上升,而且人与人之间的社交距离被大大拉近了。
这个模式很快就被验证了,Twitter、微博、微信朋友圈纷纷跟进。从此RSS逐渐淡出历史舞台,Feed流成为了移动互联网时代最主流的信息获取方式。
3. Feed流的分类
搞清楚了Feed流是什么,接下来要做的就是对它进行分类。为什么要分类?因为不同类型的Feed流,底层的设计思路差别很大。用错方案,轻则性能拉胯,重则架构要推倒重来。
3.1 按信息聚合依据分类
Feed流的信息聚合依据主要有三种:
第一种是无关系依赖的。最典型的就是抖音的推荐页。你不需要关注任何人,系统根据你的行为数据(看了什么视频、看了多久、点了什么赞)生成用户画像,然后从海量内容池里匹配你可能感兴趣的内容推给你。这种方式的核心是算法和推荐引擎,用户关系反而是次要的。
第二种是单向关系依赖的。微博的关注页就是这种。你关注了一个博主,就能看到他发布的内容。这种关系是单向的——你关注他,他不需要关注你。信息聚合的依据就是"我关注了谁"。
第三种是双向关系依赖的。微信朋友圈是典型代表。只有两个人互相加了好友,才能看到对方的朋友圈内容。信息聚合的依据是"谁是我的好友"。
这三种聚合逻辑分别适用于不同的场景:无关系依赖适合信息探测(发现新内容),单向关系适合信息订阅(主动追踪感兴趣的人),双向关系适合熟人社交。
3.2 按内容排序方式分类
除了按聚合依据分,还可以按内容的排序方式来分:
时间顺序排序。这是最常见的形式,先发布的排在前面,后发布的排在后面(或者反过来,最新的在最上面)。微信朋友圈、微博关注页都是这种。产品选择这种排序方式,隐含的假设是:Feed流中的每条内容都很重要,都需要用户看到。
权重排序。这种方式不按时间排,而是按照某个权重因子排序,用户最可能感兴趣的排在最前面。抖音推荐页、今日头条的信息流就是这种。产品选择这种排序方式,隐含的假设是:内容太多了,用户时间有限,需要帮他筛选出最想看的Top N。
把这两个维度组合起来,可以得到一个更清晰的分类:
| 信息源选择依据 | 权重排序 | 时间顺序 |
|---|---|---|
| 无需依赖关系 | 抖音推荐页 | - |
| 单向依赖关系 | - | 微博关注页 |
| 双向依赖关系 | - | 微信朋友圈 |
实际上可以进一步归纳为两大类:一类是依据隐含兴趣推荐信息、按权重排序展示的Feed流(如抖音推荐页);另一类是依据用户关系拉取信息、按时间顺序展示的Feed流(如微博关注页、微信朋友圈)。
这两种Feed流的底层实现原理差别非常大。本系列文章主要聚焦第二种——基于用户关系的Timeline类型Feed流,因为它是更基础、更通用的形式。推荐类型的Feed流涉及大量算法相关的内容,会在最后一篇中简要介绍思路。
4. Feed流的核心特征
在正式进入架构设计之前,有必要先了解一下Feed流系统有哪些典型的特征。这些特征直接决定了我们在做技术选型和架构设计时要关注什么。
多账号内容流。Feed流系统中存在成千上万的账号,账号之间可以关注、取关、加好友、拉黑。系统需要维护这些复杂的关系网络,并且在关系发生变化时及时更新内容分发策略。
非稳定的账号关系。用户可以随时关注、随时取关,关系是在不断变化的。这意味着系统不能只做一次性的数据同步,而是要能持续处理关系的动态变更。
读写比例严重失衡。Feed流是典型的读多写少场景。一条消息发布出去,可能会被成百上千甚至上千万的用户读取。读写比通常在10:1以上,极端情况下能达到100:1甚至更高。这就要求系统在读性能上做足功夫。
消息必达性要求高。用户发了条朋友圈,结果女朋友没看到——这种事情在产品层面是不可接受的。消息发布出去后,必须保证所有关注者都能感知到,至少要满足最终一致性,不能出现消息丢失的情况。
理解了这些特征,后面讨论架构方案的时候就会更有针对性。
5. 几个关键术语
在深入设计之前,先把Feed流领域常用的几个术语统一一下,免得后面沟通时产生歧义。
Feed:Feed流中的每一条状态或消息都叫Feed。朋友圈里的一条状态是一个Feed,微博里的一条微博也是一个Feed。
Feed流:本质上是数据流,核心逻辑是服务端将"多个发布者的信息内容"通过"关注、收藏、屏蔽等关系"推送给"多个接收者"。它有三个特点:少部分人发布,基于订阅行为关联关系,大多数人读取信息。
Timeline:Timeline是一种Feed流的类型,微博和朋友圈都是Timeline类型的Feed流。由于Timeline出现最早、使用最广泛,有时候人们也直接用Timeline来指代Feed流。
关注页Timeline:展示其他人Feed消息的页面,比如朋友圈、微博首页。它还有一个名字叫"收件箱"——每个用户能看到的消息都会被存储到他的收件箱中。
个人页Timeline:展示自己发送过的Feed消息的页面,比如微信的相册、微博的个人主页。它也叫"发件箱"——自己发布的消息都会记录在自己的发件箱中。别人的收件箱里的消息,就是从各个关注人的发件箱同步过来的。
写扩散:也叫推模式。用户发布消息后,消息被记录到发件箱中,然后立刻同步给所有粉丝的收件箱。
读扩散:也叫拉模式。用户发布消息后,消息只记录到发件箱中。粉丝不会立刻收到,而是等到粉丝查看Feed流的时候,主动去所有关注人的发件箱里拉取消息。
这几个术语后面会反复出现,搞清楚它们的含义很重要。
6. 小结
这篇文章主要聊了Feed流的基本概念。从RSS到Facebook News Feed的演变,从三种聚合方式到两种排序策略,这些内容看似偏理论,但实际上直接决定了后续的架构选型。
如果用一句话总结这一篇:Feed流的核心是信息聚合,不同的聚合逻辑和排序方式对应不同的技术方案。搞清楚你要做的是哪种类型的Feed流,才能选对架构。
下一篇我们会进入正题——聊一聊Feed流系统的架构设计,重点分析推模式、拉模式和推拉结合这三种数据分发策略各自的优缺点和适用场景。这也是Feed流系统设计中最核心的决策点之一。
