Redis数据淘汰策略

Redis数据淘汰策略

Redis数据淘汰策略_第1张图片

1. Redis数据淘汰策略

当Redis中的内存不够用时,此时向Redis添加新的key,那么Redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存的淘汰策略

Redis支持8种不同策略来选择要删除的key:

策略 描述
noeviction(默认) 不淘汰任何key,当内存满时不允许写入新数据,会直接报错
volatile-ttl 对设置了ttl的key,比较剩余ttl值,ttl越小越优先淘汰
allkeys-random 对全体key,随机进行淘汰
volatile-random 对设置了ttl的key,随机进行淘汰
allkeys-lru 对全体key,基于LRU算法进行淘汰
volatile-lru 对设置了ttl的key,基于LRU算法进行淘汰
allkeys-lfu 对全体key,基于LFU算法进行淘汰
volatile-lfu 对设置了ttl的key,基于LRU算法进行淘汰
# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
# is reached. You can select among five behaviors:
# 
# volatile-lru -> remove the key with an expire set using an LRU algorithm
# allkeys-lru -> remove any key according to the LRU algorithm
# volatile-random -> remove a random key with an expire set
# allkeys-random -> remove a random key, any key
# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
# noeviction -> don't expire at all, just return an error on write operations
# 
# Note: with any of the above policies, Redis will return an error on write
#       operations, when there are no suitable keys for eviction.
#
#       At the date of writing these commands are: set setnx setex append
#       incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
#       sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
#       zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
#       getset mset msetnx exec sort
#
# The default is:
#
# maxmemory-policy noeviction

2. LRU和LFU

  • LRU(Least Recently Used)最近最少使用。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高
  • LFU(Least Frequently Used)最少频率使用。会统计每个key的访问频率,值越小淘汰优先级越高

2.1 使用LinkedHashMap实现LRU

public class LRUCache<K,V> extends LinkedHashMap<K, V> {

    private int capacity;

    public LRUCache(int capacity) {
        super(capacity, 0.75f, true);
        this.capacity = capacity;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return super.size()>capacity;
    }

    public static void main(String[] args) {
        LRUCache<Integer, String> lruCache = new LRUCache<>(3);
        lruCache.put(1, "a");
        lruCache.put(2, "b");
        lruCache.put(3, "c");
        System.out.println(lruCache.keySet());

        lruCache.put(4, "d");
        System.out.println(lruCache.keySet());

        lruCache.put(3, "c");
        System.out.println(lruCache.keySet());

        lruCache.put(3, "c");
        System.out.println(lruCache.keySet());

        lruCache.put(5, "e");
        System.out.println(lruCache.keySet());
    }
}

输出结果:

[1, 2, 3]
[2, 3, 4]
[2, 4, 3]
[2, 4, 3]
[4, 3, 5]

3. 使用场景

  1. 数据库中有100万数据,Redis只缓存20w数据,如何保证Redis中的数据都是热点数据?
    使用allkeys-lru淘汰策略,挑选最近最少使用的数据淘汰,留下来的都是经常访问的热点数据。
  2. allkeys-random策略:业务中数据访问频率差别不大,没有明显冷热数据区分,建议使用这个。
  3. volatile-lru策略:如果业务中有置顶的需求,同时置顶数据不设置过期时间,这些数据就一致不被删除,会淘汰其他设置过期时间的数据。
  4. 如果业务中有高频访问的数据,可以使用allkeys-lfuvolatile-lfu策略。

你可能感兴趣的:(Redis,redis,bootstrap,数据库)