Redis缓存过期的实现示例

 更新时间:2023年12月19日 11:01:04   作者:小安爱学习  
Redis缓存的过期策略是保证缓存可靠性和性能的关键之一,本文主要介绍了Redis缓存过期的实现示例,具有一定的参考价值,感兴趣的可以了解一下

Redis缓存是一种常用的缓存技术,可以提高系统性能和响应速度。然而,如果不采取适当的过期策略,缓存可能会占据大量内存,并且数据也可能会过期并失效。

一、Redis缓存过期策略的基础知识

了解Redis缓存过期策略的前提是必须掌握Redis内存模型以及数据结构,在此我们不再赘述。Redis缓存过期策略的核心思想是根据key的过期时间来决定key是否被删除的。当一个key的过期时间到达指定时间后,Redis会自动将其删除。这个过程是由Redis内部负责的,程序员只需要设定好key的过期时间即可。

二、Redis缓存过期策略常见的类型以及如何实现

1)TTL(Time-To-Live)

TTL是Redis最简单的过期策略之一,它需要程序员手动为每个key设置过期时间。当key的过期时间到达后,Redis会自动将其删除。我们可以使用TTL命令获取key的剩余时间或者使用EXPIRE命令设置key的过期时间。例如:

# 设置 key 为 value, 并将过期时间设置为 10 秒钟 
SET key value EX 10 # 获取 key 的剩余过期时间 TTL key

2)惰性删除

惰性删除策略也是Redis默认的过期策略之一。它不会把所有的过期 key 都删除掉,而是等到有客户端来查询这个 key 的时候才检查该 key 是否已过期,并在发现过期的情况下删除该 key。因此惰性删除存在缺陷:如果有大量的过期 key 没有被查询,就会占用过多的内存空间。所以在某些场景中,需要结合其他策略来使用惰性删除。

3)定期删除

定期删除是与惰性删除相对应的一种过期策略,它会每隔一段时间主动检查过期 key,并删除过期的 key 。Redis会启动一个专门负责删除过期 key 的线程,并且可以通过配置文件指定清除频率(redis.conf文件中,default-db-deletion-size配上db * rows-per-second * 3600 )。与惰性删除不同,定期删除会消耗一定的CPU资源和IO资源,但相对惰性删除而言,它可以更快的将大量过期 key 删除掉。

二、Redis如何处理超时key

当一个key过期后,程序员无需干预,Redis会自动开始进行以下两个操作:

1)简单地将该key打上过期标记,并不立即从内存中删除;

2)通过惰性删除或定期删除策略,在之后的某个时间从内存中清除带有过期标记的key。

需要注意的是,Redis并不能保证所有过期的key都能在第一时间被后台线程清理掉。为了避免缓存泄漏和数据更新问题,应用程序在使用Redis缓存时,最好添加逻辑判断,比如在获取value之前先检查key是否存在或者手动删减过期key 。

三、基于时间的过期策略

1. 设置过期时间

在Redis中,可以使用EXPIRE和PEXPIRE命令为键设置生存时间,以秒或毫秒为单位。例如:

// 设置键为mykey的值,确保它在30秒之后过期
redisTemplate.opsForValue().set("mykey", "Hello, Redis!");
redisTemplate.expire("mykey", 30, TimeUnit.SECONDS);

2. 查看剩余生存时间

可以使用TTL命令或PTTL命令来查看键的剩余生存时间(以秒或毫秒为单位)。例如:

// 查看mykey的生存时间(以秒为单位)
redisTemplate.ttl("mykey");

// 查看mykey的生存时间(以毫秒为单位)
redisTemplate.pttl("mykey");

3. 取消过期时间

可以使用PERSIST命令来取消键的生存时间,使其永久保存。例如:

// 取消mykey的生存时间
redisTemplate.persist("mykey");

四、基于LRU算法的淘汰机制

1. 设置最大内存

可以使用maxmemory和maxmemory-policy两个配置参数设置Redis的最大内存和相应的淘汰策略。例如:

# 设置Redis最大内存为100MB
maxmemory 100mb

# 设置淘汰策略为LRU
maxmemory-policy allkeys-lru

2. 修改默认淘汰策略

除了使用maxmemory-policy命令来设置全局的淘汰策略外,也可以通过将某些键标记为VOLATILE来单独设置LRU淘汰策略。例如:

// 将mykey的生存时间设置为10秒,并标记为VOLATILE
redisTemplate.expire("mykey", 10, TimeUnit.SECONDS);
redisTemplate.execute(new RedisCallback<Boolean>() {
    @Override
    public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
        // 将mykey标记为VOLATILE
        connection.setEx(redisTemplate.getKeySerializer().serialize("mykey"), 10000L,
                redisTemplate.getValueSerializer().serialize("Hello, Redis!"));
        return true;
    }
});

3. 查看Redis内存使用情况

可以使用INFO命令或redis-cli工具来查看Redis的内存使用情况。例如:
# 使用INFO命令查看Redis内存使用情况

redisTemplate.execute(new RedisCallback<String>() {
    @Override
    public String doInRedis(RedisConnection connection) throws DataAccessException {
        return connection.info();
    }
});
# 使用redis-cli工具查看Redis内存使用情况
$ redis-cli info memory

五、通过Java代码演示实操

以下是一个通过Java Redis API演示基于时间的过期策略和LRU淘汰机制的示例程序。

public class CacheDemo {
    private static finalStringRedisTemplate redisTemplate = new StringRedisTemplate();

    static {
        // 设置Redis服务器的主机名和端口号
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("localhost", 6379);
        // 创建连接池
        LettuceConnectionFactory factory = new LettuceConnectionFactory(config);
        factory.afterPropertiesSet();
        // 设置RedisTemplate的连接工厂
        redisTemplate.setConnectionFactory(factory);
        redisTemplate.afterPropertiesSet();
    }

    public static void main(String[] args) {
        // 设置键值对缓存
        redisTemplate.opsForValue().set("key1", "value1");
        redisTemplate.opsForValue().set("key2", "value2");

        // 设置key1的生存时间为10秒,并标记为VOLATILE
        redisTemplate.expire("key1", 10, TimeUnit.SECONDS);
        redisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                connection.setEx(redisTemplate.getKeySerializer().serialize("key1"), 10000L,
                        redisTemplate.getValueSerializer().serialize("value1"));
                return true;
            }
        });

        // 查看key1的剩余生存时间
        System.out.println(redisTemplate.getExpire("key1"));

        // 设置Redis的最大内存为10MB,淘汰策略为LRU
        redisTemplate.execute(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                connection.getConfig("maxmemory");
                connection.getConfig("maxmemory-policy", "allkeys-lru");
                return null;
            }
        });

        // 查看Redis内存使用情况
        System.out.println(redisTemplate.execute(RedisServerCommands::info).get("used_memory"));
    }
}

六、总结

Redis缓存的过期策略是保证缓存可靠性和性能的关键之一。基于时间的过期策略通过设置生存时间来实现,而基于LRU算法的淘汰机制则根据访问频率和时间排序来删除最近没有使用的key。在实际使用中,可以结合两种策略来避免出现缓存占据大量内存和过期失效等问题。在Java中,可以使用RedisTemplate来对Redis进行操作。通过设置键值对缓存、设置过期时间、取消过期时间、修改默认淘汰策略和查看Redis内存使用情况等操作,可以实现对缓存的控制和管理。

需要注意的是,在设置缓存过期时间和淘汰机制时,应根据业务场景和数据类型来选择合适的时间和策略。如果需要缓存的数据变化频繁,建议采用基于LRU算法的淘汰机制;如果数据比较固定或重要性较高,可以使用基于时间的过期策略。

到此这篇关于Redis缓存过期的实现示例的文章就介绍到这了,更多相关Redis缓存过期内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Redis深入了解内存淘汰与事务操作

    Redis深入了解内存淘汰与事务操作

    将Redis用作缓存时,Redis数据存在内存中,如果内存空间用满,就会自动驱逐老的数据。Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断
    2022-07-07
  • 深入理解Redis被覆写后的失效时间

    深入理解Redis被覆写后的失效时间

    Redis覆写已存在的键会导致其旧的失效时间被新的键值对所取代,本文详细解析了在键被覆写时,其失效时间的变化,具有一定的参考价值,感兴趣的可以了解一下
    2024-09-09
  • redis zrange 与 zrangebyscore的区别解析

    redis zrange 与 zrangebyscore的区别解析

    这篇文章主要介绍了redis zrange与zrangebyscore的区别,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • Redis消息队列实现异步秒杀功能

    Redis消息队列实现异步秒杀功能

    在高并发场景下,为了提高秒杀业务的性能,可将部分工作交给 Redis 处理,并通过异步方式执行,Redis 提供了多种数据结构来实现消息队列,总结三种,本文详细介绍Redis消息队列实现异步秒杀功能,感兴趣的朋友一起看看吧
    2025-04-04
  • redis 设置生存和过期时间的原理分析

    redis 设置生存和过期时间的原理分析

    这篇文章主要介绍了redis 设置生存和过期时间的原理,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • 关于Redis未授权访问漏洞利用的介绍与修复建议

    关于Redis未授权访问漏洞利用的介绍与修复建议

    Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API,下面这篇文章主要给大家介绍了关于Redis未授权访问漏洞利用的介绍和修复建议,文中介绍的非常详细,需要的朋友可以参考下。
    2017-07-07
  • 利用Supervisor管理Redis进程的方法教程

    利用Supervisor管理Redis进程的方法教程

    Supervisor 是可以在类 UNIX 系统中进行管理和监控各种进程的小型系统。它自带了客户端和服务端工具,下面这篇文章主要给大家介绍了关于利用Supervisor管理Redis进程的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-08-08
  • redis集群实现清理前缀相同的key

    redis集群实现清理前缀相同的key

    这篇文章主要介绍了redis集群实现清理前缀相同的key,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Redis热点Key问题分析与解决方案

    Redis热点Key问题分析与解决方案

    文章主要介绍了Redis热点Key的概念、危害、产生原因以及如何检测和解决热点Key问题,热点Key会导致Redis节点负载过高、集群负载不均、性能下降、数据不一致和缓存击穿等问题,解决热点Key问题的方法包括数据分片、读写分离、缓存预热、限流和熔断降级
    2025-01-01
  • Spring Boot 中的 Redis 分布式锁

    Spring Boot 中的 Redis 分布式锁

    这篇文章主要介绍了Spring Boot 中的 Redis 分布式锁及,Redis分布式锁的优化需要的朋友可以参考下
    2023-10-10

最新评论