缓存(redis)的淘汰机制

Redis提供多种缓存淘汰策略,如allkeys-lru删除最早未使用的键,volatile-lru只淘汰有过期时间的键,allkeys-random和volatile-random随机删除,以及volatile-ttl优先删除最近要过期的键。这些策略帮助管理内存,防止缓存过度占用导致系统性能下降。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redis的缓存淘汰机制是指当缓存容量达到上限时,Redis会根据一定的策略删除缓存中的数据,以释放空间。这个机制是为了避免缓存占用过多的内存,从而提高系统的性能和稳定性。

Redis提供了多种淘汰策略,具体如下:

allkeys-lru

删除最早未使用的键,保持最近最少使用的键。

这个策略会根据键的最近使用时间来决定哪些键需要被删除。当缓存中的键数量超过设定的最大键数时,Redis会从缓存中删除最近最少使用的键,直到缓存中的键数量降低到最大键数以下。

 

public class RedisCache {  
  
    private static final String REDIS_host = "localhost";  
    private static final int REDIS_port = 6379;  
  
    private Jedis jedis;  
  
    public RedisCache() {  
        jedis = new Jedis(REDIS_host, REDIS_port);  
    }  
  
    public String get(String key) {  
        return jedis.get(key);  
    }  
  
    public void put(String key, String value) {  
        jedis.set(key, value);  
    }  
  
    public void delete(String key) {  
        jedis.del(key);  
    }  
  
    public long size() {  
        return jedis.keys("*").size();  
    }  
  
    public void clear() {  
        jedis.flushAll();  
    }  
  
    public void setMaxSize(long size) {  
        // 使用allkeys-lru淘汰策略,最大键数为size  
        jedis.configSet("maxclients", String.valueOf(size));  
        jedis.configSet("maxmemory", "0"); // 不限制内存使用  
        jedis.configSet("maxmemory-policy", "allkeys-lru"); // 设置淘汰策略为allkeys-lru  
    }  
}

这个代码示例中,我们使用了Jedis客户端连接Redis,并实现了基本的缓存操作方法,包括get、put、delete和size等。其中,setMaxSize方法设置了缓存的最大键数和淘汰策略。在setMaxSize方法中,我们使用了以下Redis配置命令: 

jedis.configSet("maxclients", String.valueOf(size)); // 设置最大键数为size  
jedis.configSet("maxmemory", "0"); // 不限制内存使用  
jedis.configSet("maxmemory-policy", "allkeys-lru"); // 设置淘汰策略为allkeys-lru

这样,当缓存中的键数量超过设定的的大小时,Redis会使用allkeys-lru策略删除最早未使用的键,保持最近最少使用的键,从而释放空间。 

 

volatile-lru

删除最早未使用的键,但只删除带有过期时间的键。

这个策略会根据键的过期时间和最近使用时间来决定哪些键需要被删除。当缓存中的键数量超过设定的最大键数时,Redis会从缓存中删除最近最少使用的键,但只会删除带有过期时间的键。这个策略适用于缓存中带有过期时间的键,可以有效地清除过期的键。

public class RedisCache {  
  
    private static final String REDIS_host = "localhost";  
    private static final int REDIS_port = 6379;  
  
    private Jedis jedis;  
  
    public RedisCache() {  
        jedis = new Jedis(REDIS_host, REDIS_port);  
    }  
  
    public String get(String key) {  
        return jedis.get(key);  
    }  
  
    public void put(String key, String value, long expirationTime) {  
        jedis.setex(key, expirationTime, value);  
    }  
  
    public void delete(String key) {  
        jedis.del(key);  
    }  
  
    public long size() {  
        return jedis.keys("*").size();  
    }  
  
    public void clear() {  
        jedis.flushAll();  
    }  
  
    public void setMaxSize(long size) {  
        // 使用volatile-lru淘汰策略,最大键数为size,只淘汰带有过期时间的键  
        jedis.configSet("maxclients", String.valueOf(size));  
        jedis.configSet("maxmemory", "0"); // 不限制内存使用  
        jedis.configSet("maxmemory-policy", "volatile-lru"); // 设置淘汰策略为volatile-lru  
    }  
}

这个代码示例中,我们使用了Jedis客户端连接Redis,并实现了基本的缓存操作方法,包括get、put、delete和size等。其中,put方法还增加了设置过期时间的功能。在setMaxSize方法中,我们使用了以下Redis配置命令: 

jedis.configSet("maxclients", String.valueOf(size)); // 设置最大键数为size  
jedis.configSet("maxmemory", "0"); // 不限制内存使用  
jedis.configSet("maxmemory-policy", "volatile-lru"); // 设置淘汰策略为volatile-lru

 这样,当缓存中的键数量超过设定的最大键数时,Redis会使用volatile-lru策略删除最早未使用的键,但只删除带有过期时间的键,从而释放空间。

allkeys-random

随机删除一个键。

这个策略会随机选择一个键进行删除,无论它是否被使用过。当缓存中的键数量超过设定的最大键数时,Redis会随机选择一个键进行删除,直到缓存中的键数量降低到最大键数以下。

 


  
public class RedisCache {  
  
    private static final String REDIS_host = "localhost";  
    private static final int REDIS_port = 6379;  
  
    private Jedis jedis;  
  
    public RedisCache() {  
        jedis = new Jedis(REDIS_host, REDIS_port);  
    }  
  
    public String get(String key) {  
        return jedis.get(key);  
    }  
  
    public void put(String key, String value) {  
        jedis.set(key, value);  
    }  
  
    public void delete(String key) {  
        jedis.del(key);  
    }  
  
    public long size() {  
        return jedis.keys("*").size();  
    }  
  
    public void clear() {  
        jedis.flushAll();  
    }  
  
    public void setMaxSize(long size) {  
        // 使用allkeys-random淘汰策略,最大键数为size  
        jedis.configSet("maxclients", String.valueOf(size));  
        jedis.configSet("maxmemory", "0"); // 不限制内存使用  
        jedis.configSet("maxmemory-policy", "allkeys-random"); // 设置淘汰策略为allkeys-random  
    }  
}

 这个代码示例中,我们使用了Jedis客户端连接Redis,并实现了基本的缓存操作方法,包括get、put、delete和size等。在setMaxSize方法中,我们使用了以下Redis配置命令:

jedis.configSet("maxclients", String.valueOf(size)); // 设置最大键数为size  
jedis.configSet("maxmemory", "0"); // 不限制内存使用  
jedis.configSet("maxmemory-policy", "allkeys-random"); // 设置淘汰策略为allkeys-random

 

volatile-random

随机删除一个带有过期时间的键。

这个策略会随机选择一个带有过期时间的键进行删除。当缓存中的键数量超过设定的最大键数时,Redis会随机选择一个带有过期时间的键进行删除,直到缓存中的键数量降低到最大键数以下。

  
public class RedisCache {  
  
    private static final String REDIS_host = "localhost";  
    private static final int REDIS_port = 6379;  
  
    private Jedis jedis;  
  
    public RedisCache() {  
        jedis = new Jedis(REDIS_host, REDIS_port);  
    }  
  
    public String get(String key) {  
        return jedis.get(key);  
    }  
  
    public void put(String key, String value, long expirationTime) {  
        jedis.setex(key, expirationTime, value);  
    }  
  
    public void delete(String key) {  
        jedis.del(key);  
    }  
  
    public long size() {  
        return jedis.keys("*").size();  
    }  
  
    public void clear() {  
        jedis.flushAll();  
    }  
  
    public void setMaxSize(long size) {  
        // 使用volatile-random淘汰策略,最大键数为size,只淘汰带有过期时间的键,随机选择一个进行淘汰  
        jedis.configSet("maxclients", String.valueOf(size));  
        jedis.configSet("maxmemory", "0"); // 不限制内存使用  
        jedis.configSet("maxmemory-policy", "volatile-random"); // 设置淘汰策略为volatile-random  
    }  
}

 这个代码示例中,我们使用了Jedis客户端连接Redis,并实现了基本的缓存操作方法,包括get、put、delete和size等。在put方法中,我们增加了设置过期时间的功能,以便在使用volatile-random 策略时仅淘汰带有过期时间的键。在setMaxSize方法中,我们使用了以下Redis配置命令:

jedis.configSet("maxclients", String.valueOf(size)); // 设置最大键数为size  
jedis.configSet("maxmemory", "0"); // 不限制内存使用  
jedis.configSet("maxmemory-policy", "volatile-random"); // 设置淘汰策略为volatile-random

 这样,当缓存中的键数量超过设定的最大键数时,Redis会使用volatile-random策略随机选择一个带有过期时间的键进行淘汰,从而保持缓存的大小不超过设定的大小

volatile-ttl

删除带有过期时间的键,优先删除最近要过期的键。

这个策略会根据键的过期时间和最近使用时间来决定哪些键需要被删除。当缓存中的键数量超过设定的最大键数时,Redis会从缓存中删除最近要过期的的时间最短的键,直到缓存中的键数量降低到最大键数以下。

// RedisVolatileTtlCache类,用于实现Redis的volatile-ttl缓存策略  
public class RedisVolatileTtlCache {  
    // 定义Redis主机和端口  
    private static final String REDIS_HOST = "localhost";  
    private static final int REDIS_port = 6379;  
  
    // 定义默认的最大缓存大小和过期时间  
    private static final int DEFAULT_MAX_SIZE = 1000;  
    private static final int DEFAULT_EXPIRATION_TIME = 60;  
  
    // Redis连接池  
    private JedisPool jedisPool;  
  
    // 构造函数,接受最大缓存大小和过期时间作为参数  
    public RedisVolatileTtlCache(int maxSize, int expirationTime) {  
        // 创建Jedis连接池,并设置最大连接数和主机名、端口号  
        JedisPoolConfig poolConfig = new JedisPoolConfig();  
        poolConfig.setMaxTotal(maxSize);  
        jedisPool = new JedisPool(poolConfig, REDIS_host, REDIS_port);  
        // 设置过期时间  
        setExpirationTime(expirationTime);  
    }  
  
    // 构造函数,使用默认的最大缓存大小和过期时间创建对象  
    public RedisVolatileTtlCache() {  
        this(DEFAULT_MAX_SIZE, DEFAULT_EXPIRATION_TIME);  
    }  
  
    // 设置键值对,并设置过期时间  
    public void set(String key, String value) {  
        try (Jedis jedis = jedisPool.getResource()) {  
            jedis.setex(key, getExpirationTime(), value);  
        }  
    }  
  
    // 获取指定键的值  
    public String get(String key) {  
        try (Jedis jedis = jedisPool.getResource()) {  
            return jedis.get(key);  
        }  
    }  
  
    // 删除指定键  
    public void delete(String key) {  
        try (Jedis jedis = jedisPool.getResource()) {  
            jedis.del(key);  
        }  
    }  
  
    // 获取当前缓存中的键的数量  
    public long size() {  
        try (Jedis jedis = jedisPool.getResource()) {  
            return jedis.keys("*").size();  
        }  
    }  
  
    // 清空缓存  
    public void clear() {  
        try (Jedis jedis = jedisPool.getResource()) {  
            jedis.flushAll();  
        }  
    }  
  
    // 设置过期时间  
    private void setExpirationTime(int expirationTime) {  
        try (Jedis jedis = jedisPool.getResource()) {  
            // 设置Redis的配置参数,将过期策略设置为volatile-ttl  
            jedis.configSet("maxmemory-policy", "volatile-ttl");  
            jedis.configSet("maxmemory-samples", "3");  
            jedis.configSet("ttl", String.valueOf(expirationTime));  
        }  
    }  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值