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

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Redis 版,经济版 1GB 1个月
简介: 快速学习缓存有效期和淘汰策略

开发者学堂课程【高校精品课-厦门大学 -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 的内存淘汰机制。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3天前
|
存储 设计模式 缓存
Java中的缓存设计与优化策略
Java中的缓存设计与优化策略
|
4天前
|
缓存 Java 数据库连接
一篇文章讲明白hiberbnate缓存策略概述
一篇文章讲明白hiberbnate缓存策略概述
10 1
|
11天前
|
缓存 索引
cpu缓存一致性问题---cache写策略
cpu缓存一致性问题---cache写策略
9 1
|
11天前
|
存储 缓存 NoSQL
Redis 缓存失效策略及其应用场景
Redis 缓存失效策略及其应用场景
19 1
|
1月前
|
存储 缓存 监控
中间件Read-Through Cache(直读缓存)策略实现方式
【5月更文挑战第11天】中间件Read-Through Cache(直读缓存)策略实现方式
37 4
中间件Read-Through Cache(直读缓存)策略实现方式
|
21小时前
|
存储 缓存 安全
实现写入缓存策略的最佳方法探讨
实现写入缓存策略的最佳方法探讨
|
5天前
|
缓存 监控 NoSQL
淘客返利系统的缓存策略与实现
淘客返利系统的缓存策略与实现
|
1月前
|
存储 缓存 NoSQL
Redis 缓存失效策略及其应用场景
Redis 缓存失效策略及其应用场景
51 1
|
1月前
|
缓存 算法 NoSQL
中间件Cache-Aside策略命中缓存
【5月更文挑战第10天】中间件Cache-Aside策略命中缓存
35 8
|
1月前
|
存储 缓存 监控
中间件Cache-Aside策略缓存未命中
【5月更文挑战第10天】
39 7