缓存有效期和淘汰策略|学习笔记

简介: 快速学习缓存有效期和淘汰策略

开发者学堂课程【高校精品课-厦门大学 -JavaEE 平台技术缓存有效期和淘汰策略学习笔记,与课程紧密联系,让用户快速学习知识

课程地址:https://developer.aliyun.com/learning/course/80/detail/15927


缓存有效期和淘汰策略


内容介绍

一、缓存的有效期

二、淘汰策略

三、缓存的清理方法

四、Redis 的策略

五、缓存淘汰机制

六、lru 和 lfu 的差别


一、缓存的有效期

Redis 的缓存是非常有限的,实际上是无法把所有的数据都放到缓存中的。当把数据放到缓存中的时候,一般是要给数据设定一个有效期的,就是指定这个数据会在缓存中放多久的时间。当数据到期以后,就要从缓存中把数据清除掉,腾出空间把

新的数据放到缓存中。这个就是缓存的有效期。


二、淘汰策略

淘汰策略指的就是缓存中间的数据全部满时,需要使用什么方法把缓存中的数据取

出。


三、缓存的清理方法

对于缓存有效期和淘汰策略,通常有以下几种方法清理缓存中的数据。

1、定时过期

这也是一般会想到的方法。当把一个数据放到缓存中的时候,因为大部分的数据其实都是有有效期的,可以为每一个数据设定一个定时器,等时间到了以后就把这个数据从缓存中清除掉。这个内存的清理是非常干净的,因为数据到期就会被清理掉。但是这种做法其实是不现实的,因为在缓存中间会有非常多的数据。每个数据放置缓存的时间不同,过期的时间也就不同。所以每一个数据都需要一个定时器把它清理掉。这样会大量占用 CPU 的资源,从而使得用来处理缓存的计算资源受到影响。一般而言都不会使用定时过期的方式来清理缓存中的数据。

2、惰性过期

惰性过期只有访问到这个数据的时候,才会判断这个数据是否已经到有效期。如果到达有效期就把这个数据清除,如果未到有效期就访问这个数据。这样的一种方式其实是完全不需要定时器的,所以它并不会占用 CPU 的资源。但是这个方法对于内存而言是非常不利的,除非访问到这个数据,它才会被清理。如果未访问到这个数据,它就会一直在缓存中。极端的情况下有些数据已经过期了,但是它从未被访问过,就会一直在缓存中不被清除,这样就造成了大量的缓存被占用。

3、定期过期

定期过期的方式其实是设定一个间隔,每隔一段时间扫描缓存中的数据,把过期的数据清除,这样的方式相对于惰性过期而言也是一种主动清理的过程,但是和定时过期相比它可以设定一个时间间隔,所以时间间隔设定的长短也就决定了对于 CPU 的占用资源会用多少。同时也可以设定每次扫描的时候只扫描多少数据,所以间隔和扫描的数据这两个值可以用来平衡 CPU 资源的占用情况,以及对内存清理的程度。定期过期的方式其实并不是及时清理的,所以有一些数据过期仍会在缓存中,等待扫描的时候被扫描到了才会被清理出去。


四、Redis 的策略

Redis 采用的其实是惰性过期和定期过期相结合的方式。Redis 在默认情况下每隔100毫秒就会扫描一下缓存,如果发现有过期的值就把它清理掉。当然在100毫秒中间是不会扫描所有的数据,因为缓存中的数据有多有少,而且缓存本身可大可小,所以全部扫描缓存中的数据会占用较多的时间。所以 Redis 采用了随机抽取的方式,抽取值也是可以设定的。随机抽取一些值,把这些抽取值中过期的数据清理掉。这样的方式还是会造成部分数据未被抽取到,就会一直在缓存中。所以 Redis 也采取了惰性过期的方式,当访问到一个值的时候,发现这个值过期了,就会从缓存中清理掉。结合采用了惰性过期和定期过期的方式,Redis 能够用尽量少的 CPU

资源清理在缓存中间的数据。这是 Redis 有效期的管理。


五、缓存淘汰机制

不管怎样管理有效期,Redis 的缓存的有效期都是有限的,缓存中的空间中将会被全部占用,但是有新的数据要放进去。Redis 在遇到这种情况时,就会启动缓存淘汰机制。

方法:

1、noeviction

这种方法就是如果缓存不够了,数据就会报错,这种方法一般不会采用,更多的会采用一种算法,从所有的数据中间清理掉。算法主要有最近最少使用,最近不常使

用以及随机的算法。

针对的数据范围:

针对的数据有两个范围,一个范围是所有有效期的数据,称之为 volatile 有效的数据;另外就是所有的数据,称之为 allkeys。

2、allkeys-lru

所以在设定 Redis 的内存淘汰机制的时候,如果设定的是 allkeys-lru,就是最近最少使用的算法把所有数据中最少使用的数据清除。

3、allkeys-random

如果是 allkeys-random 的话,就是从所有数据中随机抽取一个数据进行清除。

4、valatile-lru

valatile-lru 就是用 lru 的算法在有有效期的数据中选取一个数据清理。

5、valatile-random

valatile-random 就是用随机的方法在有效期的数据中间淘汰一个。

6、volatile-ttl

对于有有效期的数据而言还有一种自己的算法为 volatile-ttl,这种算法是取有效期过期时间最早的数据清理掉。这样可以保证如果有过期数据的话它的过期时间一定是最早的。如果没有过期数据的话就会清理最近过期的数据。

在 Redis4.0 以后提供了第三种算法为 lfu。Lru 是最近最少使用的,lfu 清理是最近不经常使用的数据。对于所有的数据是 allkeys-lfu,对于有效期的数据是 valatile。

 

六、lru 和 lfu 的差别

1、基本介绍

lru 是最近最少使用的,lfu 就是最近使用频率最少的。lru 是把近访问的数据插到对头使它最晚被淘汰,lfu 是按照使用的频率排序,所以把使用频率最小的数据清理掉。

2、案例分析

现在使用一个例子看一下这两种算法运行的状况。假如有五个数据已经在队列中,

分别是A、B、C、D、E。

(1)LRU 算法

首先使用 lru 的算法。假设第一个数据被访问到的是D, 按照 lru 的算法D就会被移到对头,A移到了第二位。随后访问到数据B,则B就会移到对头,D移到了第二位,A就到了第三位。第三个数据F,它在最中间是不存在的,意味着要在最中间淘汰一个数据。所以按照 lru 的算法在队尾的E数据在最近一段时间未被使用过,就被

移除了队列。这样队列就剩下了 F、B、D、A、C,其中F、B、D是最近访问的三个数据。

LRU 算法其实存在了一份问题,其实是只表现了这个数据最近访问的次序,没有办法表现出数据访问的频率。其实更应关心的是最近访问的数据在未来如果再次被访问的话,它应该留在队列中而不被淘汰掉。所以如果在短期内有新的数据进入,它

就可能会把之前使用较为频繁的数据挤出队列中,所以就会有 LFU 的算法。

图片16.png

(2)LFU 算法

LFU 算法和 lru 不同,并不是使用访问的先后来进行排序,而是把所有的数据记录了访问次数。比如还是有 A、B、C、D、E 这五个数据,他们的访问次数分别为32、30、26、26、25,在队列中间按照这个顺序进行排序。

当D数据首先访问的时候,D数据的访问次数就会加一,就变成了27,。D数据就会在整个队列中向前提一位,排在了C的前面。第二个数据B被访问的时候,它的数据也有增加但没有超过A,所以它依然会在第二位。当F进入的时候,因为F在队列中间是不存在的,所以它的次数是一。它不会像 lru 排在队头,而是按照顺序排在了队尾,把E淘汰了。所以这样的算法可以看到按照访问频度排序的话就会排除频度访

问较小的数据。

当然这有一些问题,第一个问题是F进入后就排在了队尾,如果下次进来新的数据就

会很快地淘汰F。

图片17.png

所以 lfu 的算法对于新数据而言是不利的,通常的话会对新数据做一个初始值,比如做一个五火六的初始值,不至于刚进入就被淘汰,对于老数据是有利的,比如A。虽然在这段时间都没有访问,但是依然在对头。

这是因为之前访问的次数比较多,所以它一直是排在对头的。LFU 还需要做一个定期淘汰、定期衰减的做法,每隔一段时间把所有数据的次数都减少一个值,这样使得老数据也会在队列中间慢慢地被淘汰。

在 Redis 中间如果简单的采用 lru 和 lfu 的话都需要维持一个排序队列,或者是记录访问的先后或者是按照访问的频度进行排序。这时需要占用较大的内存空间和

CPU 资源的,而且每次数据的访问都会造成队列的改动。

Redis 采用了一种近似的方式,不是维护这样的队列,而是从所有的值中间随机选取N个,按照最近访问的次数或最近的频度进行排序。这样就使得不需要将每一次对于数据的访问都进行排序,而是在内存空间不足发生淘汰的时候,才需要从所有的数据中提取N 个并对其进行排序。按照 lru 和 lfu 的算法把队尾的数据清理。新

的数据也不需要记录它在队列中的位置,直接放进去就行。

这样的算法比理论上的 lru 和lfu 的计算量要小很多,但它也可以达到近似 lru 和 lfu 的效果,而且资源的控制量其实是由N值控制的,就是随机选取多少值来进行排序直接决定了需要多少资源运行 lru 和 lfu。N越大,它的效果越接近理论上的 lru 和 lfu;N越小,它的效果距离理论值越远,对于计算资源的消耗就越小。这就是

redis 的内存淘汰机制。

相关文章
|
6月前
|
缓存 负载均衡 网络协议
电商API接口性能优化技术揭秘:缓存策略与负载均衡详解
电商API接口性能优化是提升系统稳定性和用户体验的关键。本文聚焦缓存策略与负载均衡两大核心,详解其在电商业务中的实践。缓存策略涵盖本地、分布式及CDN缓存,通过全量或部分缓存设计和一致性维护,减少后端压力;负载均衡则利用反向代理、DNS轮询等技术,结合动态调整与冗余部署,提高吞吐量与可用性。文中引用大型及跨境电商平台案例,展示优化效果,强调持续监控与迭代的重要性,为电商企业提供了切实可行的性能优化路径。
|
缓存 算法 数据挖掘
深入理解缓存更新策略:从LRU到LFU
【10月更文挑战第7天】 在本文中,我们将探讨计算机系统中缓存机制的核心——缓存更新策略。缓存是提高数据检索速度的关键技术之一,无论是在硬件还是软件层面都扮演着重要角色。我们会详细介绍最常用的两种缓存算法:最近最少使用(LRU)和最少使用频率(LFU),并讨论它们的优缺点及适用场景。通过对比分析,旨在帮助读者更好地理解如何选择和实现适合自己需求的缓存策略,从而优化系统性能。
428 3
|
7月前
|
缓存 搜索推荐 CDN
HTTP缓存策略的区别和解决的问题
总的来说,HTTP缓存策略是一种权衡,需要根据具体的应用场景和需求来选择合适的策略。理解和掌握这些策略,可以帮助我们更好地优化网页性能,提高用户的浏览体验。
219 11
|
6月前
|
存储 缓存
.NET 6中Startup.cs文件注入本地缓存策略与服务生命周期管理实践:AddTransient, AddScoped, AddSingleton。
记住,选择正确的服务生命周期并妥善管理它们是至关重要的,因为它们直接影响你的应用程序的性能和行为。就像一个成功的建筑工地,工具箱如果整理得当,工具选择和使用得当,工地的整体效率将会大大提高。
259 0
|
9月前
|
数据采集 缓存 JavaScript
数据抓取的缓存策略:减少重复请求与资源消耗
本教程聚焦于提升爬虫效率与稳定性,通过结合缓存策略、代理IP技术(如爬虫代理)、Cookie和User-Agent设置,优化数据采集流程。以知乎为例,详细讲解如何抓取指定关键词的文章标题和内容。内容涵盖环境准备、代码实现、常见问题及解决方案,并提供延伸练习,帮助读者掌握高效爬虫技巧。适合具备Python基础的初学者,助你规避网站机制,顺利获取目标数据。
264 2
数据抓取的缓存策略:减少重复请求与资源消耗
|
缓存 JavaScript 中间件
优化Express.js应用程序性能:缓存策略、请求压缩和路由匹配
在开发Express.js应用时,采用合理的缓存策略、请求压缩及优化路由匹配可大幅提升性能。本文介绍如何利用`express.static`实现缓存、`compression`中间件压缩响应数据,并通过精确匹配、模块化路由及参数化路由提高路由处理效率,从而打造高效应用。
538 91
|
Web App开发 缓存 UED
如何设置浏览器的缓存策略?
【10月更文挑战第23天】通过合理地设置浏览器的缓存策略,可以在提高网页性能、减少网络流量的同时,确保用户能够获取到最新的内容,从而提升用户体验和网站的性能优化效果。
1126 60
|
缓存 API C#
C# 一分钟浅谈:GraphQL 中的缓存策略
本文介绍了在现代 Web 应用中,随着数据复杂度的增加,GraphQL 作为一种更灵活的数据查询语言的重要性,以及如何通过缓存策略优化其性能。文章详细探讨了客户端缓存、网络层缓存和服务器端缓存的实现方法,并提供了 C# 示例代码,帮助开发者理解和应用这些技术。同时,文中还讨论了缓存设计中的常见问题及解决方案,如缓存键设计、缓存失效策略等,旨在提升应用的响应速度和稳定性。
187 13
|
存储 缓存 安全
在 Service Worker 中配置缓存策略
Service Worker 是一种可编程的网络代理,允许开发者控制网页如何加载资源。通过在 Service Worker 中配置缓存策略,可以优化应用性能,减少加载时间,提升用户体验。此策略涉及缓存的存储、更新和检索机制。
|
存储 缓存 监控
利用 Redis 缓存特性避免缓存穿透的策略与方法
【10月更文挑战第23天】通过以上对利用 Redis 缓存特性避免缓存穿透的详细阐述,我们对这一策略有了更深入的理解。在实际应用中,我们需要根据具体情况灵活运用这些方法,并结合其他技术手段,共同保障系统的稳定和高效运行。同时,要不断关注 Redis 缓存特性的发展和变化,及时调整策略,以应对不断出现的新挑战。
202 10