为什么需要缓存
因为计算机读取文件(数据库)的速度相对于读取内存的数据来说,会比较慢,所以,我们常常使用缓存来加快我们的访问效率。
为什么需要淘汰数据
相对于动则几T几T的硬盘来说,内存就要小得多,而且贵得多,现在大部分的服务器仍是32G/64G内存的,并且类似JAVA这类会有GC问题的语言来说,使用大内存可能引来FullGC问题,可能会造成系统暂停服务一小段时间,得不偿失,所以,我们不能把所有的数据都从数据库放到内存去缓存,只能够缓存更加有价值的数据。如果查询一个数据,这个数据刚好在缓存里,我们称之为命中缓存,显而易见,命中率,是衡量一个缓存的重要指标。
淘汰算法
因为需要淘汰掉数据,所以需要设计淘汰算法,总不能跟机器说,帮我淘汰掉没价值的,那样估计程序员们就要失业了,常用的淘汰算法有哪些呢?
FIFO(First in First out)
先进先出算法,这个最简单了,就是谁先进来,我们就把谁淘汰掉。我们用一个图来解释下这个过程。
我们假设缓存的大小设置位5,
1.首先插入ABC,那么内存里面是ABC
2.再次插入DE,内存队列里面位ABCDE
3.再次插入F,则最先进入的A被淘汰
4.再次插入G,则淘汰第二次进入队列的B
这个算法有什么问题呢?那就众生平等,无论王侯将相,进来的,早晚得出去,而且是ONE BY ONE 排队出去。
LRU(Least Recently Used)
淘汰最近最久未使用算法,顾名思义,就是哪个是最近不用的,就把他淘汰掉。这是目前阶段最常用的缓存淘汰算法了。我们用一个图来解释下这个算法。
假设我们缓存里面存放5个元素
1.依次插入ABC,那么会把ABC放到对应的位置上
2.再次插入DE,这个时候元素的个数还没到元素的总个数,所以不用淘汰
3.插入F,发现元素个数大于缓存的上限,所以把最近没有使用的A淘汰掉。
4.插入B,B已经在缓存里面了,所以把B的位置提到最新的位置
5.插入G,这个时候最旧的数据已经不是B,而是C,所以把C淘汰掉。
这种算法有什么问题呢?不凡假设有这么一种情况,可能有某个数据出现的频率很高,每隔一段时间就会出现,也避免不了被淘汰的命运,所以又有人提出了另外的淘汰算法。
LFU(least frequently used)
淘汰最近最少使用算法,顾名思义,就是淘汰缓存里面用的最少的了,我们也通过一个图,来解释下这个算法的运行过程。
我们同样假设缓存里面存放的元素是5个,我们对每一个元素都维护一个计数器,记录用了多少次。
1.依次插入ABC,每个的计数器上都是1.
2.依次插入DE,ABCDE的计数器上也都是1
3.插入ABCE,除了D之外,其他的计数器都是2
4.再次插入F,发现D的计数器最小,于是淘汰掉D。
那么这种淘汰算法又有什么问题呢?我们不难想到,如果某个数据只一开始出现了100万次,后面再也没出现过,但是这个数据仍然可能被我们缓存着!
总结
为了提高缓存的命中率,有着非常多的算法,每种算法都要各自的优点跟缺点,需要我们根据业务进行选择,希望大家关注我,下一期,我们会简单的介绍下这几种算法代码上是如何实现的。
领取专属 10元无门槛券
私享最新 技术干货