产品开发经验分享3——pull和push

241 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情

做产品设计,经常在做trade off,之前有遇到一个需求,简单来讲,给用户下发勋章,可以给全部用户发,或者给指定人群发,然后用户可以在个人中心看到这些勋章。

我们依然使用4s的方法进行分析。关于系统设计的方法,可参考:《系统设计面试指北》

Scenario 场景

首先要明确,我们大概要给多大规模的用户去发放勋章。经过我的调研,勋章可分为两类,一类是全部用户,大概3kw的量级,一类是给特定用户发送,大概是几百人的规模。

发送勋章时,还需要附带一个特殊条件:发送私信,也就是对于3kw的用户而言,需要发3kw条私信消息。

一般这种发私信消息,都会有qps的限制,假设qps是1k,我们可以计算出,3kw的用户,大概要发送8小时才算完成。

另外3kw的数据,落表的话,也需要insert这么多次,如果每100条插入一次,也需要插入30w次,如果控制db写入速度为10QPS的话,大概需要50min。

另外,这种勋章也会存在撤回的可能,一次性也不能更新那么多行记录,也是需要分批执行的。

所以会发现,如果3kw量级的数据量,采用落表的方式的话,会非常的不方便,我们需要换一个思路,把主动推送给用户push,转换为用户主动读取pull的方式。

如果采用这种方式,我只需要记录一条全局的勋章配置即可,只要能查到这条勋章的用户,都能展示该条勋章。对于发送私信的需求,后来寻找到业务方进行了批量私信的发送。

接下来分析另一类,给特定用户群体发送的情况,我们公司提供了一个叫做人群包的服务,可以圈定指定的一些用户。如果采用pull的方式,我需要判断用户是否在这个人群包里面。

一旦这种指定人群的勋章配置变得很多,就会出现一个问题,每个用户都要查询多个人群包,才知道能看到哪些勋章,这一步操作的成本会非常高,会造成很大的接口耗时。

因此这种场景更合理的做法,是采样push的形式,把数据落表,用户只需要按照自己的用户id去查即可。

这类指定用户的规模,大概是几百人,所以一边进行落表,一边进行私信推送,也是可行的。

Service 服务 & Storage 存储

按照前面的讨论,在设计服务时,需要一张配置表,并且标注是对全量用户发送,还是指定人群发送。

另外,对于指定人群发送,需要另一张表来存储用户的具体发放记录。

Scale 扩展

对于本系统,可以考虑以下扩展点:

  1. 白名单

很多时候,我们在发放勋章的时候,需要提前看下展示是否正确,需要出一个测试发送的功能,可以指定部分用户看到勋章的效果。

  1. 任务机制

因为除了发送之外,还有撤回功能,如果发送了一半,可能还需要考虑紧急撤回等,停掉正在发送的任务。

所以我在实际开发中时,另外设计了一张任务表,记录每个任务的操作,并且能够控制发送的速率,发送期间不断轮询任务是否被中止,另外任务也需要考虑幂等跟加锁。

这里面涉及的内容也比较多,后续再另外写专题来讨论。