Bootstrap

彻底理解Redis的过期策略

一.由来

因为现在Redis的使用是非常普遍的,Redis是基于内存的数据存储系统,而内存相比于早些年而言,还是便宜了很多,但是相比硬盘而言还是最很多,因此提高Redis里面的内存利用率是非常重要,而Redis的过期策略就是提升内存空间利用率的一把利刃,同时还存在另一个利刃就是内存淘汰策略

二.过期策略

两种策略:

1.定期删除:定时定期的删除某些数据;

默认会隔一段时间来Redis中随机抽取一些我们设定了过期时间的Key出来,然后来足个分析这些Key是否已经过期,那么说如果这些Key已经过期了(TTL=0),那么就就会将这些数据进行删除,不会将这个数据直接返回给用户,如果说我们抽取出来的Key中已经过期的Key的占比大于抽取出来的数据的25%,那么代表需要删除的有很多,此时会立刻进入下一轮的随机抽取,直到有一次这个占比小于25%,这个时候才会结束这个随机抽取动作,然后根据设置的间隔时间,才会进入下一轮。

Redis默认是每个100ms就随机抽取一些设置了过期时间的Key,检查是否过期,过期就删除。

但是这种会出现两个问题:

(1)随机抽取出来的这个Key很多的话,就需要足个比对,这个时候就会占用大量的CPU资源,从而会影响到Redis的性能;

(2)随机抽取数据,也就意味着在Redis里面肯定会存在一些漏网之鱼,比如上面的K1值,每次抽取都没有抽到它,但是它已经过去,也就代表这个Key不会被删除掉,它就会继续浪费Redis里面的内存空间。

2.惰性删除:存在一种懒加载的思想在里面,需要触发某个常见才能删除某些数据。 

只有当用户访问到某一个Key的时候,才会进行检查Key是否过期,过期就删除,不返回任何东西,没有访问到的Key就会一直存在Redis中,这也没能解决到定期删除的漏网之鱼问题,也就是这个Key既没有被访问到,也没有被随机抽选到,这个Key还是会继续遗忘在Redis里面,浪费内存空间。

为了解决这个问题,就需要使用到内存淘汰机制,

三.内存淘汰策略

常见八种策略:

它主要涉及到Lru的算法(根据使用时间)Lfu的算法(根据使用频率)

1.noevication(3.0版本后的默认策略):当内存使用超过配置的大小时,直接报错;

2.allkeys-lru:在所有Key里面来实行lru算法,根据算法来删除最久没有使用的键;

3.volatile-lru:在设置了过期时间的Key里面来实行lru算法,根据算法来删除最久没有使用的键;

4.allkeys-random:在所有Key里面,随机挑去一部分Key进行删除;

5.volatile-random:在设置了过期时间的Key里面,随机挑去一部分Key进行删除;

6.volatile-ttl:在设置了过期时间的Key里面根据TTL时间进行筛选数据,其实就是选择剩余时间最短的Key进行删除,比如现在有两个Key,一个Key还有10s过期,一个Key还有20s过期,它会有限删除10s的Key;

7.volatile-lfu:在设置了过期时间的Key里面来实行lru算法,根据算法来删除使用频率最少的键;

8.allkys-lfu:在所有Key里面来实行lfu算法,根据算法来删除使用频率最少的键;

四.问题

1.如果数据库有1000万条数据,而Redis只能缓存20万条数据,如何保证Redis中都是热点数据?

答:可以使用allkeys-lru(挑选最近最少使用的数据淘汰)淘汰策略,这样留下来的都是经常访问的热点数据。

2.当Redis的内存用完了会发生什么?

答:主要取决于数据淘汰策略。如果是默认的配置(noeviction),Redis会直接报错,因为无法删除任何数据以腾出内存空间。

;