redis里面的内存淘汰策略:是指当内存的使用率达到了maxmemorg的上限的时候,它的一种内存释放的一个行为。
redis里一面提供了很多种内存的淘汰算法,归纳一起就主要有四种。
1.Random算法(随机算法,随机移除某个key)。
2.TTL算法(就是在设置了过期时间的键口里面去找到更早过期时间的key,进行有限移除)。
3.LRU算法(去移除最近很少使用的key,使用场景主要应用在内存管理上,比如Mysql里面的Buffer_Pool。业务场景中解决topIO的一个问题或者在IM类的场景缓存最近的聊天记录等等)。
4.LFU算法(它跟LRU的算法是类似的)。
LRU是一种比较常见的内存淘汰算法,在redis里面它会维护一个大小为16的候选池,而这个候选池里面的数据,会根据时间进行排序,然后每一次随机抽取5个key,放入到这个候选池里面,当候选池满了以后,访问的时间间隔最大的key就会从候选池里面取出来淘汰掉,通过这一个设计就一可以把真实的最少访问的key从内存里面淘汰,但是这样的一种LRU算法还是会存在一个问题,假如一个key很长时间没有访问,但是最近一次偶然被访问到那么LRU就会以为这是一个热点key不会之被淘汰,所以在redis4里面增加一个LFU算法,相比于LRU,LFU去增加了访问频率这样一个维度来统计数据的热点情况。
LFU的主要设计是使用了两个双向链表去形成一个二维的双向链表,一个是用来保存访问频率,另一个是用来保存访问频率相同的所有的元素,当添加元素的时候,访问频次默认为1,于是找到相同频次的节点然后添加到相同的频率节点对应的双向链表的头部,当元素被访问的时候就会增加对应key的访问频率并且把当前访问的节点移动到下一个频次的节点,当然有可能会出现某个数据前期的访问次数很多,然后后续就一直不使用了。如果单纯按照这样的一个访问频次来进行淘汰的话,那么这个key就很难被淘汰掉,所以在LFU的算法里面去通过了使用频率和上次访问时间来标记数据的这样一个热度,如果某个数据有读和写,那么就增加访问的频率,如果一段时间内这个数据没有读写,那么就减少访问频率,所以通过LFU算法改进之后就可以真正达到非热点数据的淘汰,当然LFU也有缺点,相比LRU算法,LFU增加了访问频次的一个维护以及实现的复杂度要比LRU更高。