LRU、LFU 缓存淘汰算法
一、基本概念
LRU(Least Recently Used)和 LFU(Least Frequently Used)是两种常见的缓存淘汰算法,用于在缓存空间有限的情况下选择合适的缓存对象进行淘汰,以提高缓存的利用效率。
- LRU 算法基于 "最近最少使用" 的原则进行淘汰。它维护一个缓存的访问顺序链表,当有新的数据被访问时,如果数据已经在缓存中,则将其移到链表头部;如果数据不在缓存中,则将其添加到链表头部。当需要淘汰数据时,选择链表尾部的数据进行淘汰,因为维护的数据是最近最少被访问的数据。
- LFU 算法基于 "最不经常使用" 的原则进行淘汰。它维护一个缓存对象的访问频次,对于每个访问到的对象,增加其访问频次。当需要淘汰数据时,选择访问频次最低的数据进行淘汰。
二、适用场景
LRU 和 LFU 算法都有各自的优势和适用场景
- LRU 算法适用于访问具有时间局部性的数据,即最近被访问的数据可能在将来一段时间内仍然会被访问。LRU 算法相对较简单,容易实现,适用于大多数场景。但是,当存在 "热点数据"(被频繁访问的数据)时,LRU 算法可能无法有效的保证缓存的命中率。
- LFU 算法适用于访问具有访问频次局部性的数据。即访问频次高的数据很可能在将来一段时间内仍然会被频繁访问。LFU 算法需要维护每个对象的访问频次技术,相对于 LRU 算法来说更加复杂。LFU 算法在面对热点税局的场景下表现较好,但在某些场景下可能存在 "频次突变" 的问题,即频次高的数据突然不在被访问,但因为频次计数较高而长时间无法被淘汰。
三、Redis 持久保留方案
Redis 的数据存储在内存中,这也就意味着 Redis 的内存是有限的。为了解决内存不足的问题,Reids 提供了多种数据的淘汰策略,以下是 Redis 的内存淘汰策略的整理。
- noeviction
当内存不足时,禁止淘汰数据,写入操作保存,这是 Redis 默认的内存淘汰策略。
- allkeys-random
当内存不足时,从所有的 key 中,随机选出数据进行淘汰。
- volatile-random
当内存不足时,从设置了过期时间的 key 中,随机选出数据进行淘汰。
- volatile-ttl
当内存不足时,从设置了过期时间的 key 中,选出即将过期的数据(按照过期时间的先后,选出最先过期的数据)进行淘汰。
- allkeys-lru
当内存不足时,从所有 key 中使用 LRU 算法,选出最近使用最少的数据进行淘汰。
- volatile-lfu
当内存不足时,从设置了过期时间的 key 中使用 LFU 算法,选出使用频率最低的数据进行淘汰。
- allkeys-lfu
当内存不足时,从所有 key 中使用 LFU 算法,选出使用频次最低的数据,进行淘汰。
- volatile-lru
当内存不足时,从设置了过期时间的 key 中使用 LRU 算法,选出最近最少使用的数据进行淘汰。