产品中心
详细信息
BM30-62
BM30-62介绍完定时器的背景知识,接下来看下我们系统的实现。我们先看一下需求背景。在我们组的实际业务中,有延迟任务的需求。一种典型的应用场景是:商户发起扣费请求后,立刻为用户下发扣费前通知,24小时后完成扣费;或者发券给用户,3天后通知用户券过期。基于这种需求背景,我们引出了定时器的开发需求。
我们首先调研了公司内外的定时器实现,避免重复造轮子。调研了诸如例如公司外部的Quartz、有赞的延时队列等,以及公司内部的PCG tikker、TDMQ等,以及微信支付内部包括营销、代扣、支付分等团队的一些实现方案。后从可用性、可靠性、易用性、时效性以及代码风格、运维代价等角度考虑,我们决定参考前人的一些的技术方案,并根据我们团队的技术积累和组件情况,设计和实现一套定时器方案。
首先要确定定时器的存储数据结构。这里借鉴了时间轮的思想,基于微信团队常用的存储组件tablekv进行任务的持久化存储。使用到tablekv的原因是它天然支持按uin分表,分表数可以做到别以上;其次其单表支持的记录数非常高,读写效率也很高,还可以如mysql一样按指定的条件筛选任务。
我们的目标是实现秒级时间戳精度,任务到期只需要单次通知业务方。故我们方案主要的思路是基于tablekv 按任务执行时间分表 ,也就是使用使用方指定的start_time(时间戳)作为分表的uin,也即是时间轮bucket。为什么不使用多轮时间轮?主要是因为首先kv支持单表上亿数据, 其二kv分表数可以非常多,例如我们使用1000万个分表需要约115天的间隔才会被哈希分配到同一分表内。故暂时不需要使用到多轮时间轮。
BM30-62