简介
本项目是一个短视频平台,拥有热度排行榜,热门视频,兴趣推送,关注推送,内容审核等功能。
源码下载
网盘
(访问密码: 8418)
登录/注册
首页
创作中心
架构设计
上传视频业务流程
视频推送流程
1.用户订阅分类后取出分类后的默认标签,标签数/100 得到同等概率,存到用户模型库
2.用户在 视频停留时长/点赞/收藏 将对该视频下的所有标签拿到 模型库中进行增长/缩减 ,每次增长后需要同等比缩小概率,防止概率膨胀
3.推送视频时获取用户的模型库,将其组装为数组,下标为labelId,随机数取数组长度,获取videoId,并和浏览记录去重,再根据用户性别标签获取视频,封装数据后返回,这里可能会推送很少的视频,不要紧
4.前端拉取推荐视频根据上一次推送视频集合的阈值拉取,例如集合扩容机制
热门推送
数据结构:
Set ttl: 3天
key: hot:video
value: hotVideo
设计
每隔3个小时 切片快速分页扫描全表 ,每个视频计算热度值后和系统配置表的热度值做比对,小于则放入热门视频
推送:
热门视频属于随机推送且下拉获取新视频,不需要分页,如果出现相似视频则说明是数据量不够大
热度排行榜
根据视频的热度进行排行
设计
热度 = 权重 和时差的计算
权重 = 点赞,浏览,分享,收藏对应的占比例
时差:当前时间 - 视频发布时间的差值
A视频24小时内点赞到了1W,B视频1小时内点赞到了1W,则说明B视频热度更高
这里可以采用半衰期公式计算热度
总结可以理解为 当前时间 - 视频发布时间 差值为x ,x越小y越大,x越大y越小 后 对应的权重 得到热度
数据结构:
Zset ttl: -1
key:hot:rank
value: videoId
socore: 热度
每隔1个小时切片快速分页扫描全表,每个视频计算热度值后放入有界的小根堆,遍历完成再放入Redis -> TopK问题
关注推送
推送关注人发送的视频 -> feed流
设计
用户拥有发件箱和收件箱
发件箱
用户所发布的视频存储在发件箱
数据结构:
Zset ttl:-1
key: out:follow:feed: + 用户id
value: 视频id
Score: 视频发布时间
收件箱
存储用户关注人的视频
数据结构:
Zset ttl:5天
key:in:follow:feed: + 用户id
value: 视频id
score: 视频发布时间
流程
-
用户发布视频后,将视频异步发送到发件箱
-
用户上线后异步获取关注流:
2.1 关注流为空,则拉取关注人7天之内的视频
2.2 不为空,则拉取收件箱最新视频的时间 - 当前时间内关注人的视频并存入收件箱
-
用户删除视频将异步删除发件箱视频,以及粉丝内的收件箱视频
-
用户拉取关注流根据滚动分页获取
推拉模式的选择是需要根据当前项目的数据体量决定的。当前项目体量不大,选择拉模式且设置ttl,过滤不活跃粉丝
收件箱初始化
拉取关注视频
分类推送
根据分类随机推送视频,不需要分页,不需要去重,因数据量少
一切的设计实现都要考虑当前项目的因素落地
审核中台
审核中台可自定义放行比例以及设置是否开启审核
设计
AuditService: 规定审核标准,规定入参返回值 <T,R>
AbstractAuditService: 封装统一逻辑 : 比较得分,获取消息,返回对应审核状态(策略模式)
ImageAuditService: 图片审核
TextAuditService: 内容审核
VideoAuditService: 视频审核
VideoPublishAuditServiceImpl: 发布视频审核设计
后台管理界面
权限模块
使用RBAC实现权限模块,超级管理员可自行分配角色
系统配置
系统配置中配置了审核力度、审核开关、热门视频热度限制、白名单
视频模块
可对视频进行下架审核处理
分类模块
可管理首页的分类
优化记录
架构优化
当前项目为单体架构,后续随着流量的增大会升级为微服务项目,主要服务如下:
- 评论服务 :评论服务抽出来是考虑到后续产品会出 动态 功能,因此将评论服务抽出来
- 点赞收藏浏览分享服务 :该服务考虑到后续可能会有对视频,动态,评论等有操作
- 鉴权服务 :用于对资源的保护
- 网关 :路由请求转发
- 消息队列:在项目中大量使用了线程解耦,实际引入MQ
- 审核服务:在项目中审核的设计为嵌入式服务,应该将其抽出改为单独服务,并且提供更多的信息
- 分享服务:分享未做短链接,实际应该做短链接处理,存储视频信息,用户信息等
视频存储优化
项目中Redis有一个分类库,用于存储所有的视频达到随机推送视频,且ttl为-1,项目中未做分片,会造成大key
分片设计
-
每个分类维护一个分片id,且限制分片id最大存储X条数据。 数据结构String key: 分类id value: 自增id
-
系统启动时将分片id存储本地缓存
-
存储视频时,先判断对应分类中的数量是否达到限制
3.1. 未达到 - 跳到4
3.2. 达到限制 - 将本地缓存自增1,异步修改Redis对应分类id 跳到4 -
获取本地缓存对应分类id
-
取对应id内的随机数,达到分片获取数据。如果想避免数据倾斜(随机数很旧,获取视频不是最新),可指定具体id进行获取数据
Feed流优化
当前项目中是以拉模式实现,用户上线后拉取内容且设置ttl。这里应该做成推拉模式,用户发布一个视频后,推送到活跃用户的收件箱,这里的设计是考虑了项目体量决定
对象存储优化
对象存储在项目中是将和资源相关暴露给了前端,实际该尽可能减少暴露
设计
-
设计文件表,用于管理所有的文件
-
视频表关联文件表, file_id = file_key
-
获取资源时根据file_id从文件表中查询file_key进行重定向
-
鉴权…