如何使用Spring Data Redis配置Redis TTL?

2023/05/12

1. 简介

在这个快速教程中,我们将了解如何在Spring Data Redis中配置key过期。

2. 设置

让我们创建一个基于Spring Boot的API来管理由Redis支持的持久化Session资源。我们需要四个主要步骤来做到这一点。有关更详细的设置,请查看我们关于Spring Data Redis的指南。

2.1 依赖

首先,让我们将以下依赖项添加到我们的pom.xml中:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>3.0.4</version>
</dependency>

spring-boot-starter-data-redis将传递添加spring-data-redis和lettuce-core。

2.2 Redis配置

其次,让我们添加RedisTemplate配置:

@Configuration
public class RedisConfiguration {

    @Bean
    public RedisTemplate<String, Session> getRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Session> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        return redisTemplate;
    }
}

2.3 模型

第三,让我们创建Session模型:

@RedisHash
public class Session {
    @Id
    private String id;
    private Long expirationInSeconds;
}

2.4 Redis Repository

最后,让我们创建SessionRepository,它提供与Redis的交互来管理我们的Session实体:

public interface SessionRepository extends CrudRepository<Session, String> {}

3. 方法

我们将介绍设置TTL的三种方法。

3.1 使用@RedisHash

让我们从最简单的开始。@RedisHash允许我们为其timeToLive属性提供一个值:

@RedisHash(timeToLive = 60L)
public class Session {
    @Id
    private String id;
    private Long expirationInSeconds;
}

它以秒为单位获取值。在上面的示例中,我们将过期时间设置为60秒。当我们想为所有Session对象提供一个常量值TTL时,这种方法很有用。指定默认TTL也很有用

3.2 使用@TimeToLive

在前面的方法中,我们可以为所有Session对象设置相同的常量TTL。使用@TimeToLive,我们可以标注任何数字属性或返回数值以设置TTL的方法:

@RedisHash(timeToLive = 60L)
public class Session {
    @Id
    private String id;
    @TimeToLive
    private Long expirationInSeconds;
}

这允许我们为每个Session对象动态设置TTL。就像之前的方法一样,TTL以秒为单位。@TimeToLive的值取代了@RedisHash(timeToLive)

3.3 使用KeyspaceSettings

继续下一个方法,KeyspaceSettings设置TTL。Keyspace定义用于为Redis哈希创建实际键的前缀。现在让我们为Session类定义我们的KeyspaceSettings:

@Configuration
@EnableRedisRepositories(keyspaceConfiguration = RedisConfiguration.MyKeyspaceConfiguration.class)
public class RedisConfiguration {

    // Other configurations omitted

    public static class MyKeyspaceConfiguration extends KeyspaceConfiguration {

        @Override
        protected Iterable<KeyspaceSettings> initialConfiguration() {
            KeyspaceSettings keyspaceSettings = new KeyspaceSettings(Session.class, "session");
            keyspaceSettings.setTimeToLive(60L);
            return Collections.singleton(keyspaceSettings);
        }
    }
}

就像之前的方法一样,我们以秒为单位指定了TTL。这种方法与@RedisHash非常相似。此外,如果我们不想使用@EnableRepositories,我们可以通过编程方式设置它:

@Configuration
public class RedisConfiguration {

    // Other configurations omitted

    @Bean
    public RedisMappingContext keyValueMappingContext() {
        return new RedisMappingContext(new MappingConfiguration(new IndexConfiguration(), new MyKeyspaceConfiguration()));
    }

    public static class MyKeyspaceConfiguration extends KeyspaceConfiguration {

        @Override
        protected Iterable<KeyspaceSettings> initialConfiguration() {
            KeyspaceSettings keyspaceSettings = new KeyspaceSettings(Session.class, "session");
            keyspaceSettings.setTimeToLive(60L);
            return Collections.singleton(keyspaceSettings);
        }
    }
}

4. 比较

最后,让我们比较一下我们看到的三种方法,并确定何时使用哪一种。

@RedisHash和KeyspaceSettings都允许我们为所有实体实例(Session)一次性设置TTL。另一方面,@TimeToLive允许我们为每个实体实例动态设置TTL。

KeyspaceSettings提供了一种在多个实体的配置中的一个位置设置默认TTL的方法。另一方面,对于@TimeToLive和@RedisHash这将需要在每个实体类文件中发生。

@TimeToLive的优先级最高,其次是@RedisHash,最后是KeyspaceSettings。

5. Redis Key过期事件

通过所有这些在Redis中设置key过期的方法,我们可能还会对此类事件发生的时间感兴趣。为此,我们可以使用RedisKeyExpiredEvent。让我们设置一个EventListener来捕获RedisKeyExpiredEvent:

@Configuration
@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP)
@Slf4j
public class RedisConfiguration {
    // Other configurations omitted

    @Component
    public static class SessionExpiredEventListener {
        @EventListener
        public void handleRedisKeyExpiredEvent(RedisKeyExpiredEvent<Session> event) {
            Session expiredSession = (Session) event.getValue();
            assert expiredSession != null;
            log.info("Session with key={} has expired", expiredSession.getId());
        }
    }
}

我们现在能够知道Session何时过期,并能够在需要时采取一些行动:

2023-02-10T15:13:38.626+05:30  INFO 16874 --- [enerContainer-1] c.t.t.s.config.RedisConfiguration: Session with key=edbd98e9-7b50-45d8-9cf4-9c621899e213 has expired

6. 总结

在本文中,我们研究了通过Spring Data Redis设置Redis TTL的各种方法。最后,我们查看了RedisKeyExpiredEvent以及如何处理过期事件。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章