LRU 是优先缓存最近使用过的资源, 淘汰最近没有使用过的资源。根据最近使用原则, 这些临时资源会直接排在缓存队列的最前面, 然后才能被被慢慢淘汰掉
在LRU算法中,使用了一种有趣的数据结构,这种数据结构叫作哈希链表。
什么是哈希表
哈希表(又叫散列表)是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
什么是链表
N个节点离散存储
彼此通过指针相连
每个节点只有一个前驱节点,每个节点只有一个后续节点,首节点没有前驱节点,尾节点没有后续节点
明白了定义我们再来理解一下
在哈希链表中,这些Key-Value是被一个链条串了起来。每一个Key-Value都具有它的前驱Key-Value、后继Key-Value,就像双向链表中的节点一样
1.假设使用哈希链表来缓存图片信息,目前缓存了4个图片,这4个图片是按照被访问的时间顺序依次从链表右端插入的
2.如果这时访问了图片5,由于哈希链表中没有图片5的数据,需要从服务器下载,在插入到缓存中。此时,链表最右端是最新被访问的图片5,最左端是最近最少被访问的图片1。
3.接下来,如果用户访问图片2,哈希链表中已经存在图片2的数据,这时我们把图片2从它的前驱节点和后继节点之间移除,重新插入链表的最右端。此时,链表的最右端变成了最新被访问的图片2,最左端仍然是最近最少被访问的图片1。
4.接下来,如果用户请求修改图片4的信息。同样的道理,我们会把图片4从原来的位置移动到链表的最右侧,并把图片信息的值更新。这时,链表的最右端是最新被访问的图片4,最左端仍然是最近最少被访问的图片1。
5.后来用户又访问图片6,图片6在缓存里没有,需要插入哈希链表中。假设这时缓存容量已经达到上限,必须先删除最近最少被访问的数据,那么位于哈希链表最左端的图片1就会被删除,然后再把图片6插入最右端的位置。
这就是整个LRU的淘汰策略
LRU 在应对批量临时资源时候性能会很差, 比如进入页面, 大量请求图片然后直接退出根据最近使用原则, 这些临时资源会直接排在缓存队列的最前面, 然后才能被被慢慢淘汰掉.
LFU 是优先缓存使用最多的资源, 每个资源需要记录使用次数, 相对于 LRU 的实现会更为复杂一些.
在后续的缓存改进中, 我们可以使用 LRU-K 算法, 以解决 LRU 算法“缓存污染”的问题, 提升缓存的命中率以及缓存逻辑的性能.