Redis Cli中仍显示过期的Redisson密钥 [英] Expired Redisson Keys still visible in Redis Cli

查看:101
本文介绍了Redis Cli中仍显示过期的Redisson密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚也了解了Redis和Redisson.基本上,我试图使用Redis在我的应用程序中存储用于授权的AcessTokens/RefreshTokens. 所以我想将令牌与到期时间一起存储.我使用了 Spring Data Redis 来存储令牌,但是没有Api会使Map中的每个条目都失效.我碰到了这篇文章 Spring Data Redis Expire Key ,因此查找了Redisson.我尝试了一个简单的maven java项目来测试到期时间. 这是pom.xml:

I just learnt about Redis and Redisson as well. Basically I am trying to use Redis for storing AcessTokens/RefreshTokens used for authorization in my app. So I want to store the tokens with an expiration time. I used Spring Data Redis to store the token but there is no Api to expire each entry in a Map. I came across this post Spring Data Redis Expire Key and hence looked up Redisson. I tried a simple maven java project to test the expiration. Here is pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bridgelabz</groupId>
    <artifactId>redissonApp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>redissonApp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.3.0</version>
        </dependency>

    </dependencies>
</project>

下面是令牌类

package com.bridgelabz.redissonApp;

public class Token {

    private String accessToken;
    private int id;

    public Token() { }


    public Token(String accessToken, int id) {

        this.accessToken = accessToken;
        this.id = id;
    }

    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Token [accessToken=" + accessToken + ", id=" + id + "]";
    }   

}

这是我的演示应用程序:

And here is my demo App:

package com.bridgelabz.redissonApp;

import java.util.concurrent.TimeUnit;

import org.redisson.Redisson;
import org.redisson.api.LocalCachedMapOptions;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.redisson.api.LocalCachedMapOptions.EvictionPolicy;
import org.redisson.config.Config;


public class App {
    public static void main(String[] args) {
        Config config = new Config();

        config.useSingleServer().setAddress("127.0.0.1:6379");

        // LocalCachedMapOptions localCachedMapOptions =
        // LocalCachedMapOptions.defaults()
        // .evictionPolicy(EvictionPolicy.LFU);

        RedissonClient redisson = Redisson.create(config);

        try {

            RMapCache<Integer, Token> map = redisson.getMapCache("TestMap");

            Token myToken = new Token("abc", 1);

            map.put(1, myToken, 10, TimeUnit.SECONDS);

            System.out.println("Stored value with key 1 is: " + map.get(1));

        }

        finally {

            redisson.shutdown();

        }

    }
}

运行App.java之后,我得到的输出是:

After running App.java I get the output I get the output as:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Stored value with key 1 is: Token [accessToken=abc, id=1]

只需注释一下放置代码并在10秒钟后运行应用程序,便可以得到部分期望的结果:

And just commenting the put code and running the app after 10 seconds gives me the partly desired result:

LF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Stored value with key 1 is: null

但是当我运行redis-cli时,我仍然在输出中获取值:

But when I run redis-cli I'm still getting the value in the output:

127.0.0.1:6379> hget TestMap 1
"\x00\x00\x00\x00\x00\x00\x00\x00H\x00\x00\x00\x00\x00\x00\x00{\"@class\":\"com.bridgelabz.redissonApp.Token\",\"accessToken\":\"abc\",\"id\":1}"

为什么还没有从Redis移除密钥?仅供参考:包括Redis在内的所有内容都在我的本地计算机上进行了测试.

Why isn't the key removed from redis also? FYI: Everything is being tested on my local machine only including redis.

推荐答案

Redis不支持将单个元素逐出以散列.因此,Redisson建立了自己的解决方案并将其命名为MapCache.

Redis does not support individual element eviction out of the box for hashes. So Redisson has built its own solution and named it MapCache.

因此,在MapCache中,您现在有两个级别的到期控制:Redis提供的密钥级别和Redisson提供的字段级别.

So with MapCache, you now have two levels expiry control: Key level which offered by Redis, and field level which offered by Redisson.

在您的测试代码中:

RMapCache<Integer, Token> map = redisson.getMapCache("TestMap");

Token myToken = new Token("abc", 1);

map.put(1, myToken, 10, TimeUnit.SECONDS);

您已在哈希TestMap的字段1上设置了到期时间.这意味着哈希没有针对它设置过期时间,而是针对它具有的字段之一设置了过期时间.因此,当您使用redis-cli查找时,哈希仍然存在.当Redisson到期过程开始时,它最终将消失.

You have set the expiry on the field 1 of the hash TestMap. That means the hash does not have an expiry set against it, rather that an expiry is set against one of the field it has. So when you look it up in using redis-cli, the hash still exists. It eventually will disappear when the Redisson expiration process kicks in.

这篇关于Redis Cli中仍显示过期的Redisson密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆