如何从头打造一个Feed流

如何从头打造一个Feed流(逆序显示最新列表)

Feed流是微博、微信朋友圈等热门App的核心功能,Up主在刚接到这个需求时完全没有意识到社交性质的功能有如此大的难度,在这里简单记录一下。

起因:UP主在今年接到这么一个需求,一个类似于微信朋友圈的社交广场,这个模块致力于提供一个小型的社交广场。

那么,从头开始吧。

一、逆序时间流

最开始,UP主的思路就是把这个广场的所有数据放进一张表里,分页查就好了,但是转念一想,不对啊,假设你进入这个App,看到了当前最新的数据,在加载第二页前,涌入了一大批数据,这时你的第二页就不是第二页了。
你在某个时间节点获取的第一页在彼时已经不再是第一页了,所以你翻页时一定会下方看到你曾经看过的朋友圈,传统的分页在这里完全乱套了。

1. 第一次尝试

时间节点

如果我们在获取朋友圈时加一个时间戳标记呢?
在获取数据时,传入一个时间戳,对这个时间节点以后的数据分页,获取到的就是正确的页了。就像这样。

这时一条时间线,以某个时间节点开始,向后分页
时间线

好了,问题看起来解决了。

接下来是缓存,常规的方式就是对页缓存呗。时间节点+页码扔进Redis就好了,我们在这里试图用缓存来加速,But it’s exactly worked?

No, it’s absolutely not. 要知道每时每刻都会有用户进来,时间戳一致的可能性太小了,这就会导致每个人的每页都不一样。缓存必要性的最重要指标是命中率,这样的缓存策略命中率远低于百分之一,传统的分页缓存完全失效了。

这时,Up主的思路已经不够用了,就求助了公司的架构师,架构师说了这么一句话: 分时段缓存

分时段缓存

如果我们把时间戳粗化一下,比如0-10分作为一个时间段,一个小时分为6个时间段,在这个时间段里的分页是一致的,命中率就很高了,结果惨遭BA拒绝,这样的分页方式会导致朋友圈发送的内容在10分钟后才会显示,用户接受不了。

那咋办嘛?

操作系统级别的分页

这时Up主想起了不久前学过的操作系统,如果这样ID全部走数据库,内容走缓存呢?

又一张糟糕的配图

内容的Id就直接去数据库查,反正信息足够少。然后内容以一个小胶囊为单位,把内容缓存起来呢?比如说1-5、6-10这样的小页面缓存起来,不够一个胶囊就不缓存。

至此,其实内容的缓存已经搞定了,接下来的难题在于最关键的ID列表,这时传来一个噩耗,预估活跃用户有100k+,内容缓存是没问题,但是仅仅去DB查Id,足够把数据库拖垮了。架构也没有提出什么简单高效的方案,Up主一筹莫展。

写扩散

如果我们想办法把ID放到一个高性能的列表里呢?
常见的搜索引擎ES、Solr之类能不能满足需求呢?很遗憾,并不能,ES之流不适合存储这种频繁变动的数据,因为ES插入数据要刷新索引,而这个刷新的速度连Mysql都比不过。

最终,我们选用了Redis的Sord Set,以ID为key,时间戳为Score放到这个列表里,就能够满足高频的查找需求了。

解决方案:

这里要注意一下,Redis的Zset,也就是Sord Set在数据量大的情况下,性能会下降,所以要定期去修剪这个列表,保留几百条至几千条就足够了,如果真的有用户刷到了大页码,直接走数据库就好了。

发表朋友圈的同时,利用MQ异步的推送ID至Zset,并利用上文提到的内容胶囊缓存,最终将响应时间降低至50ms。

至此,一个简单的瀑布流(这个还不能称之为瀑布流)的关键问题就解决了,接下来Up主会不定期更新和完善,最终形成一个简易版的Feed流架构。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值