redis常常作为一个内存数据库,redis在内存空间不足的时候,为了保证命中率,就会选择一定的数据淘汰掉来腾出空间存放新的key-value。
在redis.conf文件中可以配置淘汰策略,默认是no-enviction(不删除)
maxmemory-policy allkeys-lru
LRU
删除最近没有使用的,redis是由一个个的key-value组成的,每一个value是一个redisobject对象
typedef struct redisObject {
//对象的数据类型,占4bits,共5种类型
unsigned type:4;
//对象的编码类型,占4bits,共10种类型
unsigned encoding:4;
//least recently used
//实用LRU算法计算相对server.lruclock的LRU时间
unsigned lru:LRU_BITS; /* lru time (relative to server.lruclock) */
//引用计数
int refcount;
//指向底层数据实现的指针
void *ptr;
} robj;
每一次访问数据的时候,会更新 redisObject.lru。
进行lru淘汰的时候,在数据集中随机挑选几个键值对,取出其中lru最大的键值对淘汰,redis不会遍历全部的key
用当前时间-最近访问的时间越大,说明上次访问的时间越久。
- volatile-lru
从设置了过期时间的数据集中挑选最近没有使用的数据淘汰 - allkeys-lru
从全部数据集中挑选最近没有使用的数据淘汰
lFU
删除最不经常使用
redisObject.lru是一个24位的bit
高16位存储一个分钟数级别的时间戳,低8位存储访问计数器(lfu :最近访问次数)
lru----> 高16位: 最后被访问的时间
lfu----->低8位:最近访问次数
如果过了几分钟这个key没有被访问,那么这个lfu的访问次数会衰减
- volatile-lfu
从设置了过期时间的数据集中挑选最近最少使用次数的数据淘汰 - allkeys-lfu
从全部数据集中挑选最近最少使用次数的数据淘汰
random
随机
volatile-random
从已设置过期时间的数据集中任意选择数据淘汰
allkeys-random
从全部数据集中任意选择数据淘汰
ttl
volatile-ttl
从已设置过期时间的数据集中挑选将要过期的数据淘汰
redis 数据集数据结构中保存了键值对过期时间的表(server.db[i].expires)。
TTL 数据淘汰机制:从过期时间的表中随机挑选几个键值对,取出其中 ttl 最小的键值对淘汰。
no-enviction
禁止驱逐数据,默认