缓存是什么
缓存工作的基本原理是空间换时间,即牺牲部分存储空间来换取数据访问时间;
将一些频繁查询,变动较小的数据预先放入可以快速查询的存储空间中(缓存);
查询数据的时候,会先检查缓存中是否有请求要获取的数据,有就返回缓存的数据,没有就要去其他数据源检索数据
影响查询速度的因素:
- 设备速度:高速缓存cache > 内存 > 磁盘
- 网络IO:如果获取数据需要经历多次网络IO,那一定很慢
- 数据生成耗时:如果获取数据的过程中,需要经过耗时的数据生成逻辑,也一定是慢的
缓存技术分类
-
本地缓存
本地缓存指的是一台JVM自己缓存的数据,适用于数据量小,对实时性要求高的场景;
数据存储本地无法与多个应用程序共享,当应用程序或者服务器重启,缓存数据就会丢失
-
分布式缓存
分布式缓存指的是多台JVM一起缓存的数据,适用于数据量大,需要在多个应用程序或服务器间共享数据的场景
缺点是访问速度比本地缓存慢,且需要额外的硬件和网络资源来支持
场景 - 缓存在会话缓存中的应用
实现方式:本地缓存 or 分布式缓存
用户会话缓存,自然就是在会话期内创建和使用,而在会话结束之后就失效的缓存
如果你的项目中,存在会话期内频繁访问的数据,并且数据量不大的话,可以使用会话级别的缓存来优化
下面这个图结合举的例子一起理解
以在线外卖点餐的购物车的业务场景进行举例子
假设我们在做一个在线点外卖网站的后端服务,该网站允许用户浏览外卖商品、将商品添加到购物车、查看购物车中的商品进行结算
场景描述:
- 用户进入APP:用户在手机进入外卖平台APP
- 浏览商品:用户浏览平台上的外卖商品
- 添加商品到购物车:选择要吃的外卖
- 查看购物车:用户可以随时查看购物车中点的外卖商品列表及总价
- 修改购物车:用户可以增加或减少购物车中商品的数量
- 结算:用户最终购买的外卖订单,进行结算
会话级别缓存的应用:
- 当用户进入APP时,服务器为该用户创建一个唯一的会话ID,将会话数据和这个ID进行关联
- 当用户将商品添加到购物车时,服务器更新会话数据中的购物车列表,而不是每次都去数据库中查询或者更新
- 当用户查看、修改或结算购物车时,服务器可以快速访问会话中的购物车信息,提供快速响应
- 如果一个用户在一段时间内没有进行操作(例如30分钟),服务器可以自动终止会话并清除会话数据
场景 - 缓存在客户端缓存的应用
实现方式:本地缓存 or 分布式缓存
在微服务架构中,有些时候对性能要求非常苛刻,又或者你对一致性要求不高的时候
可以在调用别人微服务的结果扽时候,就把结果缓存下来,等到下一次有类似请求进来时,就可以直接用缓存了
我们以一个在线新闻平台的例子进行举例,配合上图来理解客户端缓存的方式
假设我们有一个在线新闻平台,该平台由多个微服务组成,包括入口Web服务、内容微服务、推荐微服务等
场景描述:
- 用户浏览:用户可以通过前端页面访问新闻平台,浏览不同的新闻类别和文章
- 内容检索:用户可以使用搜索功能,通过关键词检索相关的新闻内容
- 服务调用:将用户的搜索请求发送给Web服务器,Web服务器调用搜索微服务获取搜索结果,再调用内容微服务获取具体的新闻内容
客户端缓存的应用
- 首次检索:当用户首次进行某个关键词的搜索的时候,Web应用将搜索结果存储在本地缓存
- 缓存查询:对于之后的相同的关键词的搜索请求,Web应用先查本地缓存,如果本地没有采取调用搜索微服务
- 缓存更新:应用可以设置一个合适的缓存过期时间,定期更新本地缓存中的搜索结果,确保内容的准确性和实时性
场景 - 缓存的多级缓存方案
前面介绍的方案,多数是单独使用本地缓存或者分布式缓存实现的。
从性能上来说,本地缓存的查询肯定是优于分布式缓存的,因为少了网络开销。
但是本地缓存相对于分布式缓存来说有明显的缺点,缓存空间小,可以缓存的内容少。
所以实际场景中,更常见的事一种多级的缓存结构,将本地缓存和分布式缓存一起的一种实现方案。
数据查询优先走的本地缓存,如果不命中再走分布式缓存,如果还不命中,就去查源数据库。
按照上图举个业务场景的例子,我有一个接口,性能要求十分苛刻,最开始的时候只用了Redis缓存,性能其实也还说得过去,
但是后面想要进一步提升性能的时候,就开始考虑引入本地缓存,而为了避免本地缓存命中率不高及内存浪费的问题,
我就进一步在客户端利用一致性哈希负载均衡算法,确保同一个业务的请求总是落到同一个节点上,提高本地缓存的命中率。
所以,多级缓存的方案主要针对的是,性能要求很苛刻的场景(查redis都觉得慢的情况),可以用多级缓存的方案优化