当前位置: 首页 > article >正文

多级缓存建设方案

项目背景

   xx系统中对容量和耗时有较高要求,以支付优惠立减为例,每个用户咨询可用立减时,都会过一遍全量生效活动。目前日常活动数3000+,目标2w+;日常秒级咨询量1w+,大促22w+。所以如何支撑日常和大促的业务非常具有挑战性。

   对此我们做了很多优化,其中缓存是整个优化的基石。我们对优惠模型、优惠活动预算和优惠周期预算等数据都做了缓存,但在日常开发中存在以下问题:

  1. 没有标准的缓存设计方案,需要翻其他系统的代码去理解怎么做;
  2. 开发成本高,搭建一套缓存要创建多个类,其中较多代码可复用;
  3. 容易踩坑,比如数据一致性问题、缓存击穿、热点key问题等。

   本次缓存设计参考自yy系统,其代码经过了长时间的验证,所以我们希望输出一套缓存标准化方法,尽量满足当前已有业务场景,经过验证后能推广至其他系统,帮助大家夯实缓存系统,为业务发展保驾护航。

多级缓存整体设计

为什么需要多级缓存?

   通过建设 可选的分级缓存结构、各层级缓存数据的不同scope、各层级不同的更新策略 的多级缓存,减少网络IO,极大的提高各个应用节点获取数据的速度。

适用场景

  1. 针对数据变更较少。如大促期间的优惠配置、商户支付规则配置等。
  2. 访问量非常大的。这个概念需要case by case去看,一般是某个接口会对某批数据高频查询使用的场景,数据QPS > 10w or 接口TPS > 10w
  3. 接受较短时间的数据同步延迟的场景。
  4. 不接受 既要 非常满足CAP能力,又要 保证数据吞吐量,还要 多级缓存结构的业务通用性,这是非常不合理的述求,异常情况兼容处理的 ROI 太低,建议由提出这个想法的人来做。分布式多级缓存的 Consistency 和 Availability,只能是尽量满足,如果业务能接受一些技术层面的规则,我们的架构就能在 Consistency 和 Availability 上做的更好。

分级缓存结构

参照已有的系统,有较为常用的三级缓存结构:

  1. 常驻缓存:存放静态数据或热点数据,一般没有超时时间也不会被剔除。为解决变更数据的一致性问题,需要数据推送更新一定成功,定时任务只校验数据一致性问题;
  2. LRU缓存:存放懒加载的热点数据,使用LRU淘汰机制打散的过期时间维护缓存数据;
  3. 远端缓存:存放近期的全量数据,会设置较长的过期时间,尽量不被击穿,保护数据源;
  4. 数据源:存放全量数据,通常是数据库或者外部查询接口。

各级缓存形成一个数据正金字塔,流量访问倒金字塔,越上层存放着越经常访问的数据,承担着更多的流量。

在这里插入图片描述
说明:

  1. 为什么要常驻缓存和LRU缓存?
    a. 如果只有一个LRU缓存,那么在预热时存在预读失效的问题,导致真正需要缓存的数据不在LRU中。
    b. 如果只有一个常驻缓存,那么其数据容量是有限的,需要选择性的缓存数据,会导致该模块业务通用性不够强。
    c. 常驻缓存和LRU缓存设计参考的是InnoDB中的LRU实现思路。
  2. 常驻缓存、LRU缓存的数据有什么差异?
    a. 长期来看,常驻缓存和LRU缓存中的数据会呈现互补的关系。

缓存更新机制(Consistency保障)

多级缓存更新设计时,应考虑的问题

   先抛出业务问题,再看解决的方案。

  1. DB 数据变更后,如何尽快的让业务使用到最新的数据?
    • 需要主动更新的方式,尽快变更缓存中的数据
  2. 在1更新数据时,由于一些未知因素导致缓存数据更新失败,该如何处理?
    • 为避免部分数据更新成功,部分数据更新失败,需要保证更新操作的原子性,既有更新的操作,有更新失败的回滚操作即可。(不建议对小概率的异常场景,进行过多的设计)
  3. 如何及时发现各级缓存的数据不一致问题和使用情况
    • 主动增量变更数据时,保证操作的原子性
    • 定时任务定时扫描
  4. 为什么不要延时双删?怎么解决在更新数据的同时,把历史数据加载到了缓存中,导致脏数据长时间在Cache中。延时双删方案
    • 本业务方案中,不使用删除的方式,在完成DB的数据变更后,使用更新DB的数据更新到各级缓存,可以解决延时双删方案中,读取并使用老的数据更新缓存的问题。
    • 同步更新DB和Cache 或 延时双删的策略,需按业务场景自行决策。
  5. 如何解决热点key的大批量请求影响系统的运行问题?
    • 热点key一般都会被放在一级常驻缓存中,正常来讲,不影响单台node的运行
    • 若疏忽上面的步骤,且一级LRU缓存中,没有对应的数据,那么将请求到远端缓存中,此时应当可以得到数据,也可以解决热点key问题对应用的影响
    • 若上面两级缓存中都不存在,我们在远端缓存查询DB时,使用分布式排他锁,避免大量请求到DB端,也可以解决绝大部分场景下的热点key问题对应用的影响。

   Consistency 由推拉结合的方式来保障,但不同层级的缓存操作流程不一样,整体架构图如下:
在这里插入图片描述

通过业务平台被动的数据变更流程

在这里插入图片描述
备注:

  1. 蓝色为业务管理系统,绿色为应用服务

多级缓存主动增量更新机制

请添加图片描述

备注:

  1. 缓存穿透问题的解决:
    • 查询前校验key的合法性
    • 设置守护值,设置一个较短的过期时间
    • 在查询DB的前一级缓存中添加锁(分布式或单机锁),控制缓存击穿。只解决DB层的缓存击穿,其他缓存层级间不处理该问题
  2. 缓存雪崩问题的解决:
    • 设置过期时间时,添加了随机值

定时器缓存核对任务

  1. 通过指定的策略(loop:30min),扫描缓存中的所有Key,并和DB的数据源进行对比;若数据有差异,则抛出告警,不更新缓存;
  2. 记录各个缓存层级基础信息,如命中率、内存使用情况、key情况等

缓存预热加载机制

… …


http://www.kler.cn/a/16619.html

相关文章:

  • sql server 查看io资源使用
  • UVC 输出视频格式修改和windows下数据分析
  • 【云计算解决方案面试整理】1-2云计算基础概念及云计算技术原理
  • MacOS 本地生成SSH key并关联Github
  • MySQL Workbench导入数据比mysql命令行慢
  • 深度学习——权重初始化、评估指标、梯度消失和梯度爆炸
  • PHP图片上传代码怎么写和代码的用发
  • vue3表单输入绑定
  • DDD系列:三、Repository模式
  • C++项目中打破循环依赖的锁链:实用方法大全
  • 【Java校招面试】基础知识(二)——Spring Framework AOP
  • java stream 实践篇
  • day1_内存区域
  • 枚举法计算24点游戏
  • C++Primer第五版【阅读笔记】
  • LeetCode 560. 和为 K 的子数组
  • kettle不同数据源的字段不一致的合并后插入数据库
  • 如何使用快速排序算法对整数数组进行就地排序?
  • 从4k到42k,软件测试工程师的涨薪史,给我看哭了
  • 我的医学预测模型评价步骤(仅供参考)
  • SmartEngine流程引擎之Custom模式
  • ApplicationContextAware接口
  • ETL工具 - Kettle 输入输出算子介绍
  • MyBatisPlus代码生成器使用
  • Linux Ansible角色介绍
  • Python使用AI animegan2-pytorch制作属于你的漫画头像/风景图片