淘汰常用于缓存或者内存性软件,比如 MySQL 的缓存池、redis、memcache 等。主要目的是在内存一定的情况下,让内存尽可能保留符合需求的数据(最新或者常用等),淘汰不常用或者旧数据。下面主要介绍几个最基本的淘汰算法和淘汰策略。

淘汰算法

1.LRU

最近最少使用算法,这个缓存算法将最近使用的条目存放到靠近缓存顶部的位置。当一个新条目被访问时,LRU 将它放置到缓存的顶部。当缓存达到极限时,较早之前访问的条目将从缓存底部开始被移除。

核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高。

2.LFU

最不经常使用算法,通过记录条目的访问次数,淘汰时,先淘汰访问次数最低的。

核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”。

这个算法缺点是,它无法对一个拥有最初高访问率之后长时间没有被访问的条目缓存负责。

3.FIFO

先进先出算法,按照“先进先出(First In,First Out)”的原理淘汰数据,符合队列的特性,数据结构上使用队列Queue来实现。

淘汰策略

1.定期淘汰。每个隔一段时间执行一次淘汰程序。定期策略的重点是多长时间执行一次,每次检查多少键值。

  •     间隔的时间太长,则失去了淘汰的及时性,同时可能导致内存都达到上限了,但仍然没有执行淘汰程序。
  •     间隔的时间太短,则会导致频繁执行淘汰程序,影响软件性能。
  •     检查的键值太多,则会导致执行一次淘汰程序时间过长,影响软件性能。
  •     检查的键值太少,则起不到淘汰的作用,无法及时淘汰无用数据。

2.懒惰淘汰。访问键值时,首先判断是否过期,如果过期直接删除键值。

3.定时删除。每一个键值都设定定时器,但这样在键值足够多的情况下,系统将忙于处理定时器。

以上策略可以根据场景的需求选择一个或者组合使用。比如 redis 使用的方式就是“惰性淘汰+定期淘汰”。

MySQL LRU 优化改进