Feed流系统设计实践(一)

关系内容Feed流

关系内容Feed流简单介绍

在当前任何具备社交场景的app应用中,用户之间会由于不少行为产生关系,例如微信好友的关系,当前各类陌生人社交软件喜欢的关系,微博粉丝与博 主的关系,当前各类直播软件中粉丝与主播的关系。当前产生关系以后,一个用户全部关注的用户产生的内容就造成Feed流,这个时候须要设计一个合理的Feed流系统。mysql

如今大多数关系产生Feed流系统能够分为两种实践场景,一种是朋友圈类型,我在这里叫作wx类型,一种是微博关注博主类型,我在这里叫作wb类型。redis

wx类型场景,一个用户被关注的其余用户的数量上限不会太大,例如微信一个用户的好友多一点可能就几千人,这里能够设计为写扩散模式。sql

wb类型场景,一个用户被关注的其余用户的数量多是一个很大的值,例如微博一个大V博主的粉丝可能达到几十万、几百万、几千万这种,这里须要设计为读扩散模式。数据库

什么是写扩散模式,什么是读扩散模式?顾名思义,写扩撒,就是将一个内容写多份,例如一个用户发一条朋友圈内容,除了写入本身的朋友圈列表外,须要将这条朋友圈内容写入全部关注他的其余用户的朋友圈内容列表,这样就是一条朋友圈内容就的发布就要写入多个列表,这个就叫作写扩散;读扩撒,就是一个内容被多读,例如一个拥有千万粉丝的微博大V发布了一条微博,不可能将这条内容逐一写入到全部粉丝关注内容列表里,这样的一个内容写入时间会很长,这样会致使一次瞬间写入量会很大,若是一个时间段有不少大V同时发布微博,写扩散的模式对系统的性能会有很大的损耗,这样就只能先只写一分内容,等到用户下次来刷新查看的时候再来直接获取这个大V用户发布的内容,这样就是读扩散的模式。缓存

可是,读扩撒的设计也会有一个问题,那就是若是一个用户关注了几万,几十万个大V博 主怎么办呢?难到是一次将全部关注的大V博发布的内容所有拿出来?显然这样确定是不合理的,下面两种模式下的Feed流系统设计中会有解答。微信

关系内容Feed流系统设计

1. wx类型关系类容Feed流系统

Feed系统架构图

图片描述

Feed写入和查询时序图

图片描述

Feed写入流程图

图片描述

Feed查询流程图

图片描述

mysql数据库设计

feed_info表结构设计架构

字段 类型 说明
id bigint 主键id, incr id
uid bigint feed内容所属用户id
create_uid bigint feed内容建立用户id
feed_id bigint feed内容id
type int feed内容类型
content varbinanry(4096) feed内容信息
status tinyint feed内容状态, 默认status=1, status=1正常, status=2删除
score_id bigint feed内容排序id
create_time datetime feed内容建立时间
update_time datetime feed内容更新时间

索引设计app

uid、score_id普通索引
create_uid、feed_id惟一索引

分库分表策略数据库设计

根据uid来分表

feed内容设计

feed的内容使用pb压缩字符串, 定义feed类型字段用于标记不一样类型的feed, 方便拓展

feed_id与score_id生成规则

feed_id生成规则根据建立者用户id生成, 非全局惟一,可是对于每个建立feed用户惟一
score_id按照建立时间按照时间序生成,为16位的int,用于作feed的排序

redis缓存设计

Feed list缓存设计性能

使用zset结构
key=uid val=create_uid:feed_id score=score_id
list 列表只维护固定长度,淘汰老数据

Feed info缓存设计

使用hash结构
key=uid field=create_uid:feed_id val={"content": content, "type": type, "create_time": create_time, ...}

2. wb类型关系类容Feed流系统

wb类型采用读扩散模式,用户关注的博主或主播在关注Feed列表内当用户刷新时只是展现用户最新的一条Feed内容,不展现全量Feed内容。此外会将已经展现给用户的Feed内写入用户历史Feed列表中,这就是读扩散的模式。

Feed系统架构图

图片描述

Feed写入和查询时序图

图片描述

Feed写入流程图

图片描述

Feed查询流程图

图片描述

mysql数据库设计

feed_info表结构设计与写扩散模式一致

redis缓存设计

feed list缓存与feed info缓存与写扩散模式一致

读取关注用户列表offset缓存

使用kv结构
key=uid val=offset

用户最新的Feed缓存

使用kv结构
key=uid val={"content": content, "type": type, "create_time": create_time, "score_id": score_id, "feed_id": feed_id, ...}

其余

feed的状态更新,例如删除操做,经过消费kafka队列来进行同步数据,更新缓存与数据库。
关于每条Feed的评论、点赞、转发不在本文所讨论范围,这些只是feed的某一属性,不属于feed内容自己。

结尾

这个是两种模式下关注Feed的设计,有更好的设计欢迎提出建议,做者必定会积极采纳。

相关文章
相关标签/搜索