背景
众所周知,redis是纯内存的操作。所以速度极快。然而内存的大小是有限的。
如:mysql中有2000w的数据,redis中只存20w的数据,那么如何保证redis中的数据都是热点数据呢?
答案:redis内存数据集达到一定大小的时候,就会实行数据淘汰策略,内存的淘汰机制的初衷是为了更好地使用内存
写在淘汰策略之前:reids 过期策略
我们在设置一个key的时候,一般会给这个key设置一个过期时间(expire time),如:key的过期时间1小时,那么一小时到了,这个key是如何被删除的呢?
答案就是:定期删除+惰性删除
定期删除
指的是redis默认是每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意,这里可不是每隔100ms就遍历所有的设置过期时间的key,那样就是一场性能上的灾难。实际上redis是每隔100ms随机抽取一些key来检查和删除的。定期删除可能会导致很多过期key到了时间并没有被删除掉,这时候就需要惰性删除了。
惰性删除
在获取某个key的时候,redis会检查一下 ,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除,不会给你返回任何东西。
两种结合使用,就能够保证:一个key如果过期了,肯定会被删除了
但是,如果定期删除漏掉了很多过期key,然后也没及时去做查询,也就没走惰性删除,此时就可能会有大量过期key堆积在内存里,导致redis内存块耗尽
怎么办?
答案是:走内存淘汰机制。
redis的淘汰策略:
- noeviction:内存满了之后,会返回异常。
- allkeys-lru:尝试回收,最近未使用或者使用比较少的键。(范围是:所有的键)
- volatile-lru:尝试回收,最近未使用或者使用比较少的键。(范围是:设置了过期时间的键)
- allkeys-random:随机移除某个key。(范围是:所有的键)
- volatile-random:随机移除某个key。(范围是:设置了过期时间的键)
- volatile-ttl:回收过期时间较短的key。(范围是:设置了过期时间的键)
本文参考了中华石杉