浅试netcore缓存

1.介绍

我的理解缓存好比记忆细胞,浏览器请求就好比病毒。当我们经历过一次新冠感染后,身体便会产生对应记忆细胞,下次同种新冠再次入侵,我们体内便会快速调度记忆细胞进行识别攻击。并且记忆细胞将随时间流逝越来越少,缓存大体也是这样,唯一不同的是,记忆细胞是杀死病毒,而缓存是响应请求的

2.三大要素

# 缓存命中
# 缓存命中率
# 缓存数据不一致

3.多级缓存

就拿记忆细胞来讲,新冠病毒好比浏览器,而肺比作数据库服务器,在病毒到达肺部的途中会经过多处人体器官,这些地方都会存在记忆细胞。缓存也是一样,在浏览器像数据库发送请求时中途会经过网关、web服务器等,都可能存在缓存。

4.缓存类型

我所了解到缓存有两种类型:客户端缓存、内存缓存。

客户端缓存的优点是速度非常快,因为直接从本机获取数据;缺点是不合适多用户,因为它只是降低了同一个用户的频繁请求,但对于多用户同时请求依然是没办法的。而内存缓存的

客户端缓存

首先我们看客户端缓存,意思就是将数据暂时存在用户电脑的浏览器中。

设置了缓存的响应标头中会出现cache-control:max-age=x,表示服务器告诉浏览器端可以缓存这个响应内容x秒。

只需在接口标记ResponseCache特性,Duration为缓存时间,Asp.Net Core会自动给响应体添加cache-control。

我们频繁请求后发现在缓存时间内请求直接从本机浏览器中取,等时间过了才会向服务器重新发送请求。即使每次请求参数发生改变也不要紧,缓存会把参数一起记录,好比是记录每次请求的整体一样。

并且我们可以从报文头中看到设置的缓存过期时间

内存缓存

与客户端缓存截然相反,内存缓存将数据以键值对的形式存在web服务器对应项目的内存中;

内存缓存的数据保存在当前运行的网站程序的内存中,是和进程相关的。因为在web服务器中往往存在多个网站,而它们运行在不同的进程中,因此不同网站的内存缓存是不会相互干扰的。

但注意当web服务器重启或网站重启后,内存缓存中所有数据会被清空。

1.流程图

浏览器的请求走向web服务器,会先在目标项目的内存中查看是否有匹配数据,没有才会进入接口向DB数据库再次发送请求

2.启用内存

三步走:注入服务、构造函数获取、接口中调用


连续执行两次,可以看到第一次从模拟的数据库中查,查到了便存入缓存;第二次则在缓存中就查到了。

3.过期时间

在上面的例子中我们没有设置过期时间,默认永远不会过期,除非项目重启。

但是我们需要思考一个问题,如果数据在数据库已经发生了改变那缓存中的数据就不一致应该作废。如何作废呢?我们有两种方法:在数据发生改变的时候处调用Remove或Set来删除或修改缓存,这种方法优点是比较及时,缺点是改动地方很多且需要对整个业务非常熟悉。因此我们推荐设置过期时间来解决,将过期时间设置短一些,缓存数据不一致的情况也不会持续很长时间

过期时间有两种:绝对过期、滑动过期。

而能设置时间的调用者就是GetOrCreateAsync()的回调方法中ICacheEntry类型参数

绝对过期时间

可以看到的确是每过3秒后就会去模拟数据库中找一次

滑动过期时间

滑动过期时间的特点就是如果你设置了x秒,那只要在x秒内来了一次请求则过期时间又重新刷为x秒 。

我频繁请求则会一直保存缓存。

混用结论

现在我们已经学会两种过期时间策略,但仔细一想单纯使用绝对过期时间意味着在过期的时候服务器将面临突增的并发问题,单纯使用滑动过期时间呢又怕缓存一直被复活,导致数据可能一直是过期的。

所以现在只能折中,采用混用。并且把绝对过期时间设定比滑动过期时间长,这样缓存项的内容会在绝对过期时间内随着访问被滑动续期,但是一旦超过了绝对过期时间,缓存项就被删除。

可以看到当一直请求的时候,在5秒内滑动过期一直被延期,到了5秒再强制清除缓存

如何选择

无论使用哪种过期时间策略,都会存在缓存数据不一致的情况。部分系统如博客无所谓,但金融相关项目则不能容忍。
可以通过其他机制获取数据源改变的消息,再通过代码调用IMemoryCache的Set方法更新缓存。
posted @ 2023-01-27 14:46  long-livece  阅读(157)  评论(0编辑  收藏  举报