引言
LRU (Least-Recently-Used) Cache 是经常使用的一种内存缓存,可以将一些热点数据存放在其中,进而提高接口的响应速度。在实际应用中,cache miss 后,实际可能会回源到 Redis 集群获取缓存数据,如果 Redis 集群也没有,才会回源数据库。也就是引入 LRU Cache 后相当于给应用层添加了一级高速缓存。当然,更为实际一点的是,我们需要使用的是带有过期时间的 LRU Cache,否则后台更新了课程数据,由于内存缓存的原因而得不到及时更新。
本节主要是学习下 LRU Cache 实现原理,只探讨最核心的实现思想,不考虑复杂的情况(如 goroutine 安全,缓存带过期时间等)。
实现原理
LRU Cache 提供的功能有两个:
- 顾名思义,缓存能力
- 当缓存空间满了后,会将最少访问的节点删除掉,从而为新的 key/value 提供缓存空间
具体实现的思路如下:
- 需要使用一个 map 维护 key -> entry node 的映射关系,从而能够基于此快速找到相关的节点;
- 需要使用一个双向链表来维护 entry node;
cache.set
时,需要首先检查缓存是否超出界限了,如果是的话,需要将链表尾巴(即最少访问的节点)移除;然后将新的节点插入在链表的头部,并在 map 中刷新 key 对应的 entry node 指针;cache.get
时,如果 hit 到缓存了,则将对应的 entry node 调整在链表头部,保证最频繁的节点始终往前靠。
动手实现
1 | // Package lrucache implements a cache with limited capacity, which evicts |