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

【原创 架构设计】多级缓存的应用、常见问题与解决方式

1. 简介

多级缓存是一种常见的性能优化手段,对于多级缓存一般意义上的理解具体主要实现其实指的就是本地缓存分布式缓存

本地缓存一般采用Caffeine或者Guava Cache来进行实现,而分布式缓存一般采用Redis来进行实现。

2. 业务流程

业务线程先在本地缓存中查询缓存数据,如果获取不到,则从分布式缓存中获取,并将结果存放到本地缓存中,然后返回给客户端。

本地缓存中数据会设置一定的有效期,在数据过期之后,将重复执行此操作,从分布式缓存中获取数据,如下图所示:
在这里插入图片描述

3. 优缺点与解决方案

本地缓存和分布式缓存本质上的作用都是为了提高程序的性能,减少对后端的数据存储资源的访问次数,转载请注明原文地址。

  • 本地缓存
    优点:速度最快,直接存储在业务进程内,方便使用和管理。
    缺点:多个节点实例之间的数据不一致,无持久化应用重启后就丢失,缓存容量受限于单进程内存限制,一般比较有限。
  • 分布式缓存
    优点:支持多个实例共享缓存数据,缓存容量更大,可扩缩容。
    缺点:速度相对来讲不如本地缓存,需要考虑故障恢复和一致性问题。

本地缓存同时也是分布式缓存中热key的一种有效的解决手段,后面考虑写一篇详细介绍,感兴趣的朋友可以关注下。

3.1. 如何保证本地缓存的一致性

  1. 给缓存数据加一个版本号

当某一个节点的数据发生变更之后,更新这条数据的版本号,并同步到数据库中,然后返回给客户端。客户端下次再来请求时携带这条数据的版本号,若请求到一个未更新本地缓存的节点上,发现参数中携带的版本号比自己的本地缓存中的版本号新,那么他会从共享存储中重新加载这条缓存,图示如下:

在这里插入图片描述

  1. 缓存数据变更通知

这个方法就很直接了,若节点修改了缓存的数据,那么需要通知其他节点去重新加载缓存数据,来保证多个节点之间的缓存数据一致性。常见的方式有:

1、 修改配置中心配置:配置中心的配置文件发生变更时会通知所有节点,节点收到更新配置的消息之后重新加载缓存。
2、通过MQ广播消息:与修改配置中心的配置类似,当节点修改了缓存数据的时候,发送MQ消息,其他节点监听到这条消息之后更新缓存。

  1. 最终一致

上面的两种方式实时性会好一些,若只需要最终一致性那就比较简单了,直接使用本地缓存的自动失效或者自动更新功能。

// 访问后5秒过期---自动失效
Cache<String, String> cache = Caffeine.newBuilder().expireAfterAccess(5, TimeUnit.SECONDS).build();// 写入后5秒过期,重新加载缓存---自动更新
Cache<String, String> cache = Caffeine.newBuilder().refreshAfterWrite(5, TimeUnit.SECONDS).build(new CacheLoader<String, String>() {@Overridepublic @Nullable String load(String s) throws Exception {// 查询数据库或分布式缓存重新获取缓存值return "";}
});

3.2. 本地缓存的适用场景

首先需要提到的一点:程序员做的一切都要以业务为目标,技术只是实现业务的工具。

使用本地缓存前,需要从业务上评估以下两点:

  1. 评估数据变化的频率

频繁变化的数据,是不适合放入本地缓存中去的,只有不会频繁变化的数据,才适合放到本地缓存中去。-----例如秒杀的库存数据,没人用本地缓存吧 ^ - ^。

  1. 评估业务上能否接受数据不一致,以及能接受不一致的时长

如果业务能够接受一定时长的不一致,可以根据其能接受的时长做缓存过期的时间设置,提前于最大不能接受的时长对缓存进行过期刷新处理。

4. 多级缓存扩展

完整的多级缓存不仅仅包含本地缓存与分布式缓存,还有一些其他的手段如:客户端缓存、CDN缓存、Nginx服务器缓存等。

  • 客户端缓存

根据业务需求,可以将一些不会变更的数据直接缓存到客户端,以此来减少请求服务器的次数。如秒杀的开始时间等,在一次请求服务器之后就可以进行本地计算到计时了,无需多次请求。

  • CDN缓存

即内容分发网络,一般的前端js、css、html、图片、音视频等文件可以使用CDN进行加速,客户端发起请求时最近的一个CDN服务器会返回这些内容。这个一般我们程序员不需要太关心,知道有这个事即可,一般的云厂商都有这项服务,开启后即可进行CDN加速。

  • Nginx缓存

存放静态资源缓存,当没有CDN时会通过Nginx缓存读取。此外还可以存储IP黑名单、异常用户名单校验等缓存逻辑。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【无人机设计与控制】基于蜣螂优化算法求解多无人机集群路径规划问题
  • 【波束管理】
  • leetcode第80题:删除有序数组的重复项(||)
  • MatrixOne助力一道创新打造高性能智能制造AIOT系统
  • java进程与线程
  • 基于单片机无线智能报警系统的设计
  • 华为昇腾智算中心-智算中心测试方案与标准
  • Java Integer 缓存机制:小镇的居民与大城市的拥堵
  • python内置模块pathlib.Path类操作目录和文件
  • Redis数据结构之list列表
  • 【编程底层原理】mysql的redo log undo log bin log日志的作用,以及何时生成,涉及到哪些参数变量
  • Oracle 单机和集群环境部署教程
  • JUC高并发编程1:JUC概述
  • 【学习笔记】IOC容器
  • 用工厂模式演示springboot三种注入方式 | @Autowired
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • 【EOS】Cleos基础
  • 0x05 Python数据分析,Anaconda八斩刀
  • go语言学习初探(一)
  • JS专题之继承
  • Lucene解析 - 基本概念
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 软件开发学习的5大技巧,你知道吗?
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • ​ArcGIS Pro 如何批量删除字段
  • ​Benvista PhotoZoom Pro 9.0.4新功能介绍
  • #70结构体案例1(导师,学生,成绩)
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (4)事件处理——(7)简单事件(Simple events)
  • (ibm)Java 语言的 XPath API
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (黑马C++)L06 重载与继承
  • (接口自动化)Python3操作MySQL数据库
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • .net 调用海康SDK以及常见的坑解释
  • .Net 垃圾回收机制原理(二)
  • .net 生成二级域名
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)
  • .net生成的类,跨工程调用显示注释
  • /usr/bin/perl:bad interpreter:No such file or directory 的解决办法
  • @private @protected @public
  • @RequestBody与@RequestParam
  • [ vulhub漏洞复现篇 ] Hadoop-yarn-RPC 未授权访问漏洞复现
  • [AIGC] CompletableFuture的重要方法有哪些?
  • [BJDCTF2020]The mystery of ip1
  • [BZOJ] 2427: [HAOI2010]软件安装
  • [C#学习笔记]Newtonsoft.Json
  • [C++随笔录] 红黑树
  • [dfs搜索寻找矩阵中最长递减序列]魔法森林的秘密路径