在互联网领域,尤其现在的移动互联网时代,Feed流产品是非常常见的,比如我们每天都会用到的朋友圈,微博,就是一种非常典型的Feed流产品,还有图片分享网站Pinterest,花瓣网等又是另一种形式的Feed流产品。除此之外,很多App的都会有一个模块,要么叫动态,要么叫消息广场,这些也是Feed流产品,可以说,Feed流产品是遍布在天下所有的App中。
Feed流的特点
多账号内容流:Feed流系统中肯定会存在成千上万的账号,账号之间可以关注,取关,加好友和拉黑等操作。只要满足这一条,那么就可以当做Feed流系统来设计。
非稳定的账号关系:由于存在关注,取关等操作,所以系统中的用户之间的关系就会一直在变化,是一种非稳定的状态。
读写比例100:1:读写严重不平衡,读多写少,一般读写比例在10:1,甚至100:1以上。
消息必达性要求高:比如发送了一条朋友圈后,结果部分朋友看到了,部分朋友没看到,如果偏偏女朋友没看到,那么可能会产生很严重的感情矛盾,后果很严重。
什么是Feed流
“Feed”,在RSS订阅过程中引申为用来接收该信息来源更新的接口。RSS是站点用来和其他站点之间共享内容的一种简易方式(也叫聚合内容),通常被用于新闻和其他按顺序排列的网站,例如Blog。一段项目的介绍可能包含新闻的全部介绍等。或者仅仅是额外的内容或者简短的介绍。这些项目的链接通常都能链接到全部的内容。网络用户可以在客户端借助于支持RSS的新闻聚合工具软件,在不打开网站内容页面的情况下阅读支持RSS 输出的网站内容。
换句话说,feed是将用户主动订阅的若干消息源组合在一起形成内容聚合器,帮助用户持续地获取最新的订阅源内容。严格按照上述定义来说,我们通常说的搜索结果、排序列表都不能算作feed流。feed是一种给用户持续提供内容的数据形式,是由多个内容提供源组成的资源聚合器,由用户主动订阅消息源并且向用户提供内容。
最早web时代,订阅源一般是新闻网站以及博客。典型的应用即是rss订阅器,用户主动订阅信息源,订阅器帮用户及时更新订阅源信息,然后按照时间顺序展示出来。
facebook在2006年推出了“news feed”,同时还有“mini feed”(个人动态):Facebook提供了一种新的思路,将好友或者关注的对象作为信息源,而内容即是好友或关注对象的动态(发布的内容以及其他的社交行为)。当好友足够多或者好友发布动态足够频繁时,用户能源源不断的收到内容。
我们现在习以为常的“好友动态”,在facebook刚推出来的时候,便遭到了大量用户的抗议,用户觉得该功能会侵犯个人隐私,甚至有用户建立了专门抵制“news feed”的网站,要求Facebook移除该模块。
Facebook最终还是没有移除“news feed”模块,并且在后续的发展中,对该模块不断的进行优化迭代,现在feed流已经能够给Facebook每天带来上千万美元的收入。
国内,微博从2016年开始也启用了智能排序的算法,新的feed流一发布就遭到了用户的大面积声讨。目前典型的应用,诸如今日头条、知乎、小红书、,都采用类似的方法。
Feed流展现形式
了解了feed的含义,feed流也就很清楚了—持续更新并呈现给用户内容的信息流。feed流的展现形式有很多种,主要的有timeline以及rank。
timeline:是最典型的feed流展示方式,按照feed流内容更新的时间先后顺序,将内容展示给用户,早期的微博、朋友圈都是典型的timeline。
rank:即按照某些因素计算内容的权重,从而决定内容展示的先后顺序。例如当前的微博主页信息流算法即抛弃了原始的timeline,而采用最新的智能排序。
上面两种是最常见的分类方式,也有其他的一些分类方式,比如Aggregate、Notice方式,其中:
Aggregate方式表示聚合类型,比如几个朋友看了一部电影,这就可以聚合为一条Feed:A,B,C看了电影《你的名字》,这种聚合功能比较适合在客户端做。一般的Aggregate类型是Timeline类型+客户端聚合。
Notice:通知类型,功能类型,一般用于各种APP中的各种通知、私信等场景,也是Timeline和Aggregate类型等。
至于在timeline或rank形式下使用列表、瀑布流还是卡片形式,则是前端设计展示的问题。在产品迭代发展的过程中,feed流的展现形式也在不断的变化。
最常见的是feed流中插入商业变现的广告内容,Facebook在2012的新版feed流中推送广告内容,微博feed流中的广告已经成为了用户吐槽的一个点,朋友圈也在16年开始推送广告,虽然会有部分用户抵触,但是feed流广告带给平台的收入是实实在在的。
feed流不再严格的按照时间顺序排列,在timeline的基础上,使用智能排序。
最早的是Facebook的EdgeRank算法,将内容按照权重因子计算权重,优先曝光高权重内容。
存储和推送
我们先来看存储,Feed流系统中需要存储的内容分为两部分,一个是账号关系(比如关注列表),一种是Feed消息内容。不管是存储哪一种,都有几个问题需要考虑:
如何能支持100TB,甚至PB级数据量?
数据量大了后成本就很关键,成本如何能更便宜?
如何保证账号关系和Feed不丢失?
推送系统需要考虑的功能有两个:一个是发布Feed,另一个是读取Feed。对于推送系统,仍然需要考虑两个问题:
如何能够保证提供千万级的TPS和QPS?
如何保证读写延迟在10ms,甚至2ms以下?
如何保证Feed的必达性?
存储系统选择的注意点
存储系统主要有两类:一类是账号关系(例如关注列表)、一类是Feed消息。
存储账号关系,账号关系的存储,有如下特征:一系列的变长链表,长度可达亿级别;数据量非常大,关系极其简单;性能敏感,直接影响关注,取关的响应速度。
最适合存储账号关系的系统应该是NoSQL数据库,数据量极大,关系简单不需要复杂的join,性能要求高。对内设计实现简单,对外用户体验好。有序性:有序性不要求具有排序功能,而只需要按照主键排序即可,只要按照主键排序,关注列表和粉丝列表的顺序就是固定的,可预见的。
存储Feed消息
Feed消息有一个最大的特点:数据量大,而且在Feed流系统里很多时候都会选择扩散(推模式),这时候数据量会再膨胀几个数量级,所以这里的数据量往往达到100TB,甚至PB级别。此外,还有一些如下特征:数据格式简单;数据不能丢失,可靠性要求高
自增主键功能,保证个人发的Feed的消息ID在个人发件箱中都是严格递增的,则读取时只需要一个范围即可。由于个人发布的Feed并发度很低,这里用时间戳也能基本满足需求,但是当应用层队列堵塞,网络延迟变大或时间回退时,用时间戳还是无法保证严格递增。
开发模型举例:阿里
互联网快速发展的今天,社交类应用、消息类功能大行其道,占据了大量网络流量。大至钉钉、微信、微博、知乎,小至各类App的推送通知,消息类功能几乎成为所有应用的标配。根据场景特点,我们可以将消息类场景归纳成三大类:IM(钉钉、微信)、Feed流(微博、知乎)以及常规消息队列。因此,如何开发一个简便而又高效IM或Feed流功能,成为了很多架构师、开发人员不得不面对的问题。
Timeline 1.0版模型
针对消息类场景,表格存储团队针对JAVA语言打造了一个TableStore-Timeline 1.0版数据模型模型(简称Timeline模型)。基于场景经验与理解,将消息场景封装成一个数据模型,提供了表结构设计,读写方式等解决方案供需求者使用。用户只需依托模型API,直接忽略Timeline到底层存储系统之间的架构方案,直接基于接口实现业务逻辑。它能满足消息数据场景对消息保序、海量消息存储、实时同步等特殊需求。Timeline 1.0是定义在表格存储之上抽象出来的数据模型,具体内容参见《TableStore Timeline:轻松构建千万级IM和Feed流系统》。
全文检索、模糊查询需求
在表格存储的Timeline模型受到广泛使用的过程中,我们也逐渐发现消息类数据的全文检索、模糊查询这一很强需求。而原有模型的在线查询能力存在一定短板。随着表格存储支持了SearchIndex能力,使得Timeline模型支持在线全文检索、模糊查询成为了可能。所以我们基于原有的架构设计,重新打造了Timeline
2.0时代到来
2.0模型,引入了强大的查询能力与数据管理新方案。项目代码目前已经开源在了GitHub上:Timeline@GitHub。此次推出的Timeline模型2.0版,没有直接基于1.X版本直接改造。而是在兼容原有模型架构之上,定义、封装了新的使用接口。重新打造升级新的模型,增加了如下功能:
增加了Timeline Meta的管理能力;
基于多元索引功能,增加了Meta、Timeline的全文检索、多维组合查询能力;
支持SequenceId两种设置方式:自增列、手动设置;
支持多列的Timeline Identifier设置,提供Timeline的分组管理能力;
兼容Timeline 1.X模型,提供的TimelineMessageForV1样例可直接读、写1.X版本消息,用户也可仿照实现。