一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情。
今天来分享一下我在某互联网公司任职时,开发一款名为「创作灵感」产品的设计思路。
页面如下:
可点击该链接进行体验:
member.bilibili.com/york/up-ins…
这块产品的定位是为UP主提供一些选题思路,包括今日热点、未来大事件和热门活动。
使用4s的方法进行分析。关于系统设计的方法,可参考:《系统设计面试指北》
Scenario 场景
该产品主要面向C端用户,除了H5页之外,在APP端创作首页也有相应的入口。
我们可以根据监控系统,通过接口访问量,估算出该产品将来需要承载的QPS
APP端的QPS,预计是100。H5端的QPS,预计是10。页面的曝光,会在一定程度上影响QPS。
这个产品的主要是给用户展示选题,是一个读多写少的产品。唯一的写操作是收藏功能。
因此,我们大致可以梳理出,该产品需要实现的几个核心功能:列表展示、详情展示、收藏、后台管理。
Service 服务
我们可以把产品的开发内容分成两个方面,C端接口,和后台接口。
后台就是传统的CRUD操作,包含新建一条记录,列表展示,上下线,和删除操作。这里不再细讲。
C端接口,可以分为列表页、详情页、收藏夹、收藏/取消收藏。
在大公司里,免不了和各个团队中进行协作,可以注意到,页面上有一块需要展示视频,这里需要运用到服务间调用,目前我们公司使用的是GRPC的方式,只要在后台配好一系列的视频id,就能通过稿件服务提供的RPC接口,获取到稿件的详情信息。
此外,这个模块里还有一块内容是推荐模板(图上未画出),同样也需要跟素材服务进行交互。
Storage 存储
灵感选题的配置信息,采用MySQL来存储,需要创建一张配置信息表。
收藏功能,需要评估一下数据量级。以两千万用户算,假设每个用户收藏了10个,总共就是两亿数目。
我在最开始设计的时候,觉得这个数据量太大,会影响性能,因此采用了分表的策略。按照用户id的尾号,分成了100张表进行存储。比如id为100的用户,它的收藏数据会存储到inspiration_user_00表中。
最后上线后,发现用户收藏功能使用的频率很低,根本没必要拆成100张表,完全可用一张表存储,而且因为查询的时候基本都是走的唯一索引,所以性能上不会有劣势,因此后面在做迁移服务时,也把数据存储重新设计了一下,具体的迭代思路,后面有机会再整理。
另外,在存储方面,还引入了redis。这是因为产品有个用户收藏上限的设定,如果用户收藏过快,很可能会超过该上限,因此我在每次收藏的时候,都进行了加锁,使用了redis实现了分布式锁。可参考这篇文章《高并发场景下的解决方案以及分布式锁的实现》
Scale 扩展
一些接口的具体逻辑,在这里就不赘述。
在给用户展示选题列表的时候,可以注意到每个选题旁都会有一个收藏按钮。其实展示的时候,会把配置数据+用户数据,做一个聚合,展示给前端用户。
因为该服务的QPS不算非常高,我在第一版设计的时候,没有做缓存,每次都直接读的db。在后面迭代时发现,对于配置数据,每个用户获取的都是一样,没必要每次重新去查一次数据库。所以我做了一个缓存。
缓存有很多种,我这次选择的是local cache。在内存中维护一份配置数据,然后定时去更新它。
目前,第一版创作灵感的核心设计,已经介绍完毕。整体来说,这还算一个很简单的小模块,也非常适合刚入职的我去承接。在后面的迭代中,它也逐渐变得庞大起来,设计到微服务划分、数据迁移、新老数据兼容、缓存更新策略、定时任务等话题,未来再慢慢整理。