券码系统设计

1.背景

对于券码系统来说,在一些营销领域是非常常见的,同时也是比较有难度的。
主要的点是:

  1. 导入的券码量大,对系统会有一定的冲击,后续数据多了也容易造成大表影响性能
  2. 发放产生的券码记录很大,也需要考虑
  3. 需要对性能有较高的要求
  4. 发放失败后,需要做好补偿机制

2.架构设计

1.券码导入

image.png

要点:

  1. 对于大文件的券码,例如50w的券码,如果用xlsx格式,即使你使用easyExcel的流式处理,它仍然会一次性将文件加载进内存(内容会有每个单元的字体、颜色等等),这个是由与excel格式决定的。我们这边50w的券码大概会占用500M,所以采用csv,直接一行行读,不存在OOM风险。

2.券码发放

image.png

要点:

  • 1.数据存放:发放券码的时候会触发异步任务从db查询出来,放到redis,一批1000这样的加载
  • 2.加载阈值:发放券码时,会触发db加载到redis,这里有一个阈值,我们这是1w5,当券码数量在redis中小于阈值后,就会自动触发异步从db加载,这样能比较好的防止突发流量把redis的数据全部取走,导致去db加载,击穿db
  • 3.一致性: 由于在调用发券的时候,有可能存在对方系统抖动,导致我们发放失败,但是这个时候券码又被从redis取出了然后因为异常,这个券码被丢弃了。所以,这里做了兜底机制,取出券码同时会有个redis标记,等发放完成后再删除。如果出现异常,那么会有定时任务去检测redis标记,进行补发,补发完成后再删除这个标记

3.兜底机制

image.png

要点:
1、标记会先存在redis中,重试多次不成功后会落到db,db继续重试,重试再不成功后告警,这样如果下游服务长时间不稳定,不会直接把redis打爆。

3.其他细节

1、对券码、券码领取记录根据有效期备份,做个归档,减少表的数据压力
2、当数据库的券码加载到redis用完了后,会设置一个过期时间10min的数据库券码为空标记到redis,这样下次触发加载后,不会再查db,防止击穿。同时如果有券码导入了以后,会移除这个标记
3、第一次初始化的时候走同步加载,加载的线程加分布式锁,只能有一个线程去加载,其他线程CAS的方式去获取券码(sleep50ms获取一次),同时加载券的线程进行小数量(可配置)的加载,加快初次加载的时间。

4.后期优化

1、可以根据参数自动创建新表用于券码导入、发放,这样针对一些大型活动,导入、发放的时候直接走新表,减少对其他业务的影响
2、券码表分库分表,能支持短期的大量券码导入、发放

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容

  • 什么是秒杀 通俗一点讲就是网络商家为促销等目的组织的网上限时抢购活动 比如说京东秒杀,就是一种定时定量秒杀,在规定...
    zwb_jianshu阅读 3,870评论 0 1
  • 什么是秒杀 通俗一点讲就是网络商家为促销等目的组织的网上限时抢购活动 比如说京东秒杀,就是一种定时定量秒杀,在规定...
    码道功臣阅读 11,218评论 2 79
  • 什么是秒杀 通俗一点讲就是网络商家为促销等目的组织的网上限时抢购活动 比如说京东秒杀,就是一种定时定量秒杀,在规定...
    zwb_jianshu阅读 3,579评论 0 0
  • 一、前言 秒杀系统其实是一个比较复杂的设计,文章先介绍设计秒杀系统的思路脉络和设计系统的原则。后面章节再详细介绍使...
    liuliuzo阅读 10,847评论 3 85
  • 数据库系统设计概述 世界上只有两种开发人员,一种使用数据库系统的,一种开发数据库系统的。 数据是系统最重要的信息。...
    MageByte_青叶阅读 4,421评论 0 0