微博feed流系统设计(如何设计一个微博feed流)

生活常识 2023-04-16 17:34生活常识www.baidianfengw.cn

微博如何查看通关粉丝【手机版】如何设计一个微博feed流。

翻译自作者| JiaGouX

一. 背景

微博、微信朋友圈、Tik Tok等。都是典型的feed流产品,也就是我们的浏览内容是由别人发来的feed组成的。

本文试图分析微博feed流的设计。有问题请指正。

二. 如何设计一个微博feed流

1. 存储设计

在数据存储方面主要分为三个部分。

1)feed存储

它是用户发布内容的存储,需要永久存储,用户无论看个人主页多久都应该能看到。

数据结构简化如下,表格按照userId水平划分。

创建表 t _ feed (feed Bigint not null主键,Userid` Bigint not null注释 创建者ID “内容”文本,“记录状态”Tinyint not null默认0注释 )ENGINE=InnoDB2)关注关系存储

是用户之间关系的存储,也是控制用户可以看到的feed范围的依赖。它还需要永久存储。

数据结构简化如下(待优化):表格按照userId水平划分

CREATE TABLE ` t _ like `(` id ` int(11)NOT NULL主键,` userId` int(11) NOT NULL,` likerId` int(11) NOT NULL,KEY `userId` (`userId `),KEY `userId` (`likerId `))),ENGINE=InnoDB3)feed同步存储

用于feed stream展示,可以理解为收件箱,关注它的人会向它发帖。

内容可以根据业务场景保存一段时间,冷数据可以直接存档或删除。

数据结构简化如下,表格按照userId水平划分

创建表` t _ inbox` (`id` bigint not null主键,` userid` bigint not null注释 收件人ID 美联储bigint not null注释 内容ID ` create time ` datetime not null)engine=innodb;

2. 场景特点

1) 读多写少

读写差距巨大,典型的读多写少的场景。

2) 有序展示

需要按照时间轴或者feed的评分来排序显示。

3. 使用推模式实现

推送模式又称写扩散模式,是在关注者发布内容后,主动将内容推送给关注者并写入他们的收件箱。

1)方案

1.在一个相关人员发布了一个内容之后,获取所有关注该人员的用户,然后遍历数据并将内容插入到他们的收件箱中。例子如下

/ 插入一段提要数据 /Insert into t _ feed(` feed ;` userid `内容 创建时间 )值(10001,4 ;内容 17:00:00 / 查询所有粉丝 /Select userid from t _ like where likelier=4;/ 将馈电插入风扇 s收件箱 /插入t收件箱( 用户 美联储 创造时间 )值(1,10001 ;31,17:00:00 )插入t_inbox (`userId `,` feedId `,` createTime `)值(2,10001, 17:00:00 )插入t_inbox (`userId `,` feedId `,` createTime `)值(3,10001, 17:00:00 )2.当用户ID为1的用户查看提要流时,将会找到inbox表中的所有数据。示例如下

从t_inbox中选择feedId,其中userId=1;3.对数据进行汇总和分类。

2)存在的问题

1、即时性差

当大V被很多很多用户关注的时候。

,遍历进行粉丝进行插入数据非常耗时,用户不能及时收到内容

可尝试的解决

1. 可将任务推入消息队列中,消费端多线程并行消费。 2. 使用插入性能高、数据压缩率高的数据库

2、存储成本很高

每个粉丝都要存储一份关注人的微博数据,大V粉丝量很高的时候,插入数据量成指数级上升。

并且微博可以将关注的博主进行分组,所以数据不仅要在全部收件箱中插入,也要在分组的收件箱中插入。

可尝试的解决

数据冷热分离,热库仅保存短时间内的数据,冷库多保留一段时间的数据,冷热库均定时清理数据。

用户量不断上涨,使用这种设计方案,终究还是会遇到瓶颈

3、数据状态同步

当被关注用户删除微博或取关某博主时,需要将所有粉丝的收件箱中的内容都删除,依然存在一个写扩散的即时性问题

可尝试的解决方案

在拉取数据的时候对微博的状态进行判断,过滤已删除/已取关的微博过滤

以上解决方案可以在一定程度上提升效率,不能根源上解决问题。

3)小结

推模式仅适用于粉丝量不会太多的情况,例如微信朋友圈,这样能够比较好的控制好即时触达性、以及数据存储的成本。

对于微博大V这种粉丝量很大的场景并不适合。

4. 使用拉模式

拉模式也称读扩散模式,当我们使用拉数据的方式后,用户获取数据流程如下

1、获取所有关注的博主ID。

select liker from t_like where userId = 1

2、根据博主ID进行内容拉取。

select from t_feed where userId in (4,5,6) and recordStatus = 0

3、获取所有内容后根据timeline进行排序。

这样的方案解决了在推模式下存在的三个问题,却也引发了的性能问题。

假如,用户关注的博主非常多,要拉取所有内容并进行排序聚合,这样的操作必定会耗时很多,请求时延很高。

那么如何做到低耗时,完成快速响应呢?

单纯依靠数据库是无法达到要求的,所以我们要在中间引入缓存层(分片),通过缓存来降低磁盘IO。

1)流程为

1、关注列表缓存

将用户关注的所有博主ID存入缓存中。以用户ID为key,value为关注博主id

2、微博内容缓存

以博主ID为key,value为微博内容 。博主发布微博后,将微博内容存入 中

3、获取feed流时

根据关注的博主id ,在所有缓存分片节点上拉取所有内容并进行排序聚合。

假如缓存分片集群为三主三从,也就是一共需要三次请求即可拉取到所有内容,然后进行时间倒排,响应给用户

2)存在的问题

1、系统的读压力很大

假如用户关注了1000个博主,那么需要拉取这1000个博主的所有发布内容,进行排序聚合,对于缓存服务,以及带宽压力都很大。

可尝试的解决方案:

缓存节点一主多从,通过水平扩容,来分散读压力和带宽瓶颈

3)小结

对于大V用户,拉模式能够很好解决写扩散存在的问题,也会带来上述存在的问题。

三.

分析完推模式和拉模式的优缺点,我们很容易发现

推模式适合于粉丝量不大的场景。例如朋友圈,一对一聊天。拉模式适合粉丝量巨大的大V用户。例如微博大V。

所以在场景设计时,可以将推模式和拉模式结合使用。逻辑如下

设定一个大V粉丝量阈值,达到阈值后触发打用户标签事件。对于未达到阈值的用户依然使用写扩散方式,这样冗余的数据量不会太大,也不存在即时性问题。当达到阈值的用户发微博的时候,将微博内容存入缓存(热数据),不进行写扩散,而是粉丝拉取数据与收件箱中的数据进行排序聚合。

PS这里还可以通过用户行为去维护一个活跃粉丝列表,对于该列表中的粉丝,同样进行一个写扩散的行为,保证即时触达。

微博feed流 微博feed流算法

Copyright@2015-2025 白癜风网版板所有