Redis缓存淘汰策略
noeviction:内存达到了上限,不淘汰内存数据,遇到大部分写命令返回Out Of Memory错误。
allkeys-lru:在所有的key的哈希表中随机选择多个key,在选择到的key中使用lru算法淘汰最近最少使用的缓存。
volatile-lru:在设置了过期时间的哈希表里面随机选择多个key,在选择到的key中使用lru算法淘汰最近最少使用的缓存。
allkeys-random:在所有的key的哈希表中随机选择一个key淘汰掉。
volatile-random:在设置了过期时间的哈希表里面随机选择一个key淘汰掉。
volatile-ttl:在设置了过期时间的哈希表里面随机选择多个key,在挑选到的key中选择过期时间最小的一个淘汰掉。
LRU算法
lru算法原理,根据数据的访问时间,选择淘汰最长时间未被使用的数据。可以使用链表来实现,新增数据(访问数据),把这数据插入(移动)到链表头部,淘汰数据就选择链表末尾的数据淘汰掉。
Redis采样淘汰
Redis实现的lru淘汰算法,选择被淘汰的key不一定是所有key中最近最少使用的,只是选取的样本中访问时间距离当前时间最远的。Redis有个maxmemory-samples配置项,当Redis内存使用达到上限后,从对应哈希表中挑选设置样本数量的key,插入或者替换到样本集中,最后对样本集使用lru算法,淘汰最长时间未被使用的数据。
Redis在随机采样集中应用lru淘汰数据,而不是类似memcached那样严格地挑选所有key中最近最少访问的数据。第一是考虑到Redis内部db的实现方式,Redis是使用hash表结构实现key的存储,要实现严格的lru,那么Redis就要额外的实现一个访问时间链表,增加内存开销(Redis对内存使用还是很抠门的,很多地方都牺牲时间来换取更少的空间开销),这说法是来自官网的,并且每次读写操作都需要维护更新访问时间链表;第二考虑操作的时间开销,实现严格的lru算法,那样淘汰数据的时候都需要扫描整个哈希表(前提是基于当前的数据结构来说),扫描所有key,这样付出的时间开销不言而喻。
Redis缓存淘汰源码分析
|
|