一、Redis采用的过期策略
惰性删除+定期删除
惰性删除流程
在进行get或setnx等操作时,先检查key是否过期,
若过期,删除key,然后执行相应操作;
若没过期,直接执行相应操作
定期删除流程
遍历每个数据库(就是redis.conf中配置的"database"数量,默认为16)
检查当前库中的指定个数个key(默认是每个库检查20个key,注意相当于该循环执行20次,循环体是下边的描述)
如果当前库中没有一个key设置了过期时间,直接执行下一个库的遍历
随机获取一个设置了过期时间的key,检查该key是否过期,如果过期,删除key
判断定期删除操作是否已经达到指定时长,若已经达到,直接退出定期删除。
二、淘汰策略
Redis在已使用内存达到设定的上限时,提供了6种数据淘汰策略(也就是maxmemory-policy可能的值):
在已经设置了过期时间的数据中:
1、淘汰最近未使用的一些数据,也就是volatile-lru策略
2、随机淘汰一些数据,也就是volatile-random策略
3、淘汰距离过期时间最近的一些数据,也就是volatile-ttl策略
在全部数据中
4、淘汰最近未使用的一些数据,也就是allkeys-lru策略
5、随机淘汰一些数据,也就是allkeys-random策略
不淘汰数据
6、内存使用达到设定的内存上限时,用户试图存储新数据时会直接返回错误,也就是noeviction策略。
注:
lru是less recently used的缩写,译为最近最少使用;ttl是time to live的缩写,译为生存时间。
需要注意以下几点:
1、maxmemory-policy同样可以在运行时设置,用户可以根据内存的使用情况动态的修改淘汰策略。
2、当redis中的数据有一部分访问频率比较高,另外一部分访问频率较低时,设置allkeys-lru比较合适。或者无法预测数据的使用频率时,allkeys-lru也是不错的选择。
3、如果你需要循环或者扫描连续数据时,换种说法就是数据的访问概率大致相等时,allkeys-random是不错的选择。
4、当你想通过设置不同的ttl来控制数据过期的先后顺序时,你可以设置为volatile-ttl。
5、当你希望一些数据常驻内存,另外一些数据可以被替换掉时,就请用volatile-lru或volatile-random吧。
6、另外,数据的过期时间是存储在另外一个哈希表中的,因此要耗费更多的内存空间,而allkeys-lru并不需要数据设置过期时间,因此对内存的利用率更高。
7、volatile-lru, volatile-random 和 volatile-ttl 在没有数据满足被淘汰的条件时,会和noeviction一样返回错误。
何时触发淘汰数据的动作
1、一个客户端执行指令,导致数据的增加时。
2、Redis检测到内存的使用已经达到上限。
3、Redis自身执行指令时,等等。