高并发系统-缓存(三)-设计一个缓存组件

436 阅读3分钟

文本紧接上文高并发系统-缓存(二)-如何使用缓存 设计一个通用的缓存组件

1. 原始需求

最近在做优惠券系统,其对并发要求比较高,大促期间领券峰值达到上万TPS,用券峰值也要到大几千TPS,其中峰值最高的是各种活动页、商详页中券信息漏出,可能会几万或者数十万QPS。

单单依靠数据库操作很难达到上述性能指标,其中相关数据分析如下:

  1. 优惠券批次信息属于配置信息,在领券、用券、查询券信息接口都会用到,调用量极高
  2. 优惠券领券数量、用券数量在领券/用券操作中就会变更,并发度较高
  3. 用户领取优惠券信息、优惠券状态等信息在优惠券中心、订单确认页选择优惠券时才会用到,并发度一般

2. 缓存设计思路

为了满足上述需求,设计本地缓存-REDIS缓存-数据库三级缓存。

  • 本地缓存:为了缓存极度热度数据,并设置较低过期时间
  • REDIS缓存:缓存配置数据、以及像优惠券领券数量之类频繁更新的不适合在数据操作数据
  • 数据库:数据存储最终保证,上述本地缓存和REDIS缓存的数据源

image.png

通过CacheSDK实现上述缓存管理,一二三级缓存功能。

  • 本地缓存采用Caffine来实现
  • REDIS采用集群模式,采用REDISSION来与REDIS交互
  • 三级缓存数据库(MYSQL)或者算法/接口执行结果

3. 关键设计点

3.1 如何保证数据一致性

采用Cache Aside(旁路缓存)的方式,参考前期文章高并发系统-缓存(二)-如何使用缓存

读策略(三级缓存)

  1. 从本地缓存中读取数据
  2. 如果本地缓存命中,则直接返回数据
  3. 如果本地缓存不命中,则从REDIS查询数据
  4. 如果REDIS缓存命中,会写本地缓存后返回
  5. 如果REDIS缓存未命中,则回调方法查询结果
  6. 会写REDIS和本地缓存并返回

写策略

  1. 更新数据库中的记录
  2. 删除REDIS缓存记录,同时使用REDIS PUB/SUB模式,删除本地缓存

3.2 单个key获取流程

单个KEY 查询和新增如下: image.png

3.3 批量key获取流程

批量KEY比较麻烦,主要涉及三级缓存汇聚过程,极端情况本地查询一部分,REDIS查询到一部分,MYSQL查询到一部分,最终要回写REDIS和本地缓存,最终返回。

具体实现见下篇。

参考
03 设计缓存架构时需要考量哪些因素?
经验分享 | 业务缓存之体系化设计与开发
系统设计常见组件 - Cache 篇
实现多级缓存架构设计方案