一. 背景
微博,微信朋友圈,抖音等都是典型的feed流产品,也就是我们的浏览内容都是由他人发的feed组成。
二. 如何设计一个微博feed流
在数据存储上主要分三个部分
是用户发布的内容存储,这部分内容需要永久存储,用户在查看个人主页的时候不论多久的都要可以看到
数据结构简化如下,根据userId进行水平分表
create table `t_feed`(
`feedId` bigint not null PRIMARY KEY,
`userId` bigint not null COMMENT '创建人ID'
`content` text,
`recordStatus` tinyint not null default 0 comment '记录状态'
)ENGINE=InnoDB;
2)关注关系存储是用户之间关系的一个存储,也是控制用户能够看到feed范围的依赖,同样需要永久存储。数据结构简化如下(待优化)根据userId进行水平分表:
CREATE TABLE `t_like`(
`id` int(11) NOT NULL PRIMARY KEY,
`userId` int(11) NOT NULL,
`likerId` int(11) NOT NULL,
KEY `userId` (`userId`),
KEY `userId` (`likerId`),
)ENGINE=InnoDB;
用于feed流展示,可以理解为是一个收件箱,关注的人发布了feed,就要向其中投递。
可以根据业务场景保存一段时间内的内容,冷的数据可以进行归档也可以直接删除。
数据结构简化如下,根据userId进行水平分表:
create table `t_inbox`(
`id` bigint not null PRIMARY KEY,
`userId` bigint not null comment '收件人ID',
`feedId` bigint not null comment '内容ID',
`createTime` datetime not null
)ENGINE=InnoDB;
读写比例差距巨大,典型的读多写少场景。
需要根据timeline或者feed的打分值来进行排序处理展示。
/** 插入一条feed数据 **/
insert into t_feed (`feedId`,`userId`,`content`,`createTime`) values (10001,4,'内容','2021-10-31 17:00:00');
/** 查询所有粉丝 **/
select userId from t_like where liker = 4;
/** 将feed插入粉丝的收件箱中 **/
insert into t_inbox (`userId`,`feedId`,`createTime`) values (1,10001,'2021-10-31 17:00:00');
insert into t_inbox (`userId`,`feedId`,`createTime`) values (2,10001,'2021-10-31 17:00:00');
insert into t_inbox (`userId`,`feedId`,`createTime`) values (3,10001,'2021-10-31 17:00:00');
select feedId from t_inbox where userId = 1 ;
3、对数据进行聚合排序处理
当大V被很多很多用户关注的时候,遍历进行粉丝进行插入数据非常耗时,用户不能及时收到内容
可尝试的解决方法:
1. 可将任务推入消息队列中,消费端多线程并行消费。
2. 使用插入性能高、数据压缩率高的数据库
每个粉丝都要存储一份关注人的微博数据,大V粉丝量很高的时候,插入数据量成指数级上升。
并且微博可以将关注的博主进行分组,所以数据不仅要在全部收件箱中插入,也要在分组的收件箱中插入。
可尝试的解决方法:
数据冷热分离,热库仅保存短时间内的数据,冷库多保留一段时间的数据,冷热库均定时清理数据。
用户量不断上涨,使用这种设计方案,终究还是会遇到瓶颈
当被关注用户删除微博或取关某博主时,需要将所有粉丝的收件箱中的内容都删除,依然存在一个写扩散的即时性问题
可尝试的解决方案:
在拉取数据的时候对微博的状态进行判断,过滤已删除/已取关的微博过滤
以上解决方案可以在一定程度上提升效率,但是不能根源上解决问题。
select liker from t_like where userId = 1;
2.根据博主ID进行内容拉取。
select * from t_feed where userId in (4,5,6) and recordStatus = 0;
缓存节点一主多从,通过水平扩容,来分散读压力和带宽瓶颈
三. 总结
分析完推模式和拉模式的优缺点,我们很容易发现推模式适合于粉丝量不大的场景。例如朋友圈,一对一聊天。
所以在场景设计时,可以将推模式和拉模式结合使用。逻辑如下
如喜欢本文,请点击右上角,把文章分享到朋友圈
如有想了解学习的技术点,请留言给若飞安排分享
因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享
·END·
相关阅读:
架构师作者:盖茨狗
来源:https://juejin.cn/post/7025208419875291166
版权申明:内容来源网络,仅供分享学习,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!
我们都是架构师!
关注架构师(JiaGouX),添加“星标”
获取每天技术干货,一起成为牛逼架构师
技术群请加若飞:1321113940 进架构师群
投稿、合作、版权等邮箱:admin@137x.com