Redis Key 过期通知 Jedis

Posted

技术标签:

【中文标题】Redis Key 过期通知 Jedis【英文标题】:Redis Key expire notification with Jedis 【发布时间】:2014-12-11 22:22:33 【问题描述】:

当我的密钥在 redis 数据存储中过期时,我正在尝试使用 redis 实现过期密钥通知。 redis网站提供了一些关于http://redis.io/topics/notifications的描述,但我找不到任何示例如何使用Jedis等redis java客户端来做到这一点?

任何可能的带有插图的代码都会非常有帮助,因为我是 redis 的新手。

【问题讨论】:

【参考方案1】:

您只能使用 pub-sub 模型来做到这一点 启动 Redis 服务器

将 redis.conf 中的 notify-keyspace-events 更改为 KEA(这取决于您的要求)。redis 文档http://redis.io/topics/notifications 中提供了详细信息。

Redis Java 客户端(Jedis),试试以下:

通知监听器:

public class KeyExpiredListener extends JedisPubSub 

@Override
    public void onPSubscribe(String pattern, int subscribedChannels) 
        System.out.println("onPSubscribe "
                + pattern + " " + subscribedChannels);
    

@Override
    public void onPMessage(String pattern, String channel, String message) 

        System.out
                .println("onPMessage pattern "
                        + pattern + " " + channel + " " + message);
    

//add other Unimplemented methods



订阅者:

****Note** jedis.psubscribe(new KeyExpiredListener(), "__key*__:*"); -- 此方法支持基于正则表达式模式的通道 而 jedis.subscribe(new KeyExpiredListener(), ""__keyspace@0__:notify"); --此方法采用完整/准确的频道名称

public class Subscriber 

    public static void main(String[] args) 
        JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost");

        Jedis jedis = pool.getResource();
        jedis.psubscribe(new KeyExpiredListener(), "__key*__:*");

    


测试类:

public class TestJedis 

    public static void main(String[] args) 
        JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost");

        Jedis jedis = pool.getResource();
        jedis.set("notify", "umq");
        jedis.expire("notify", 10);

    

现在首先启动您的订阅者,然后运行 ​​TestJedis。您将看到以下输出:

onPSubscribe __key*__:* 1
onPMessage pattern __key*__:* __keyspace@0__:notify set
onPMessage pattern __key*__:* __keyevent@0__:set notify
onPMessage pattern __key*__:* __keyspace@0__:notify expire
onPMessage pattern __key*__:* __keyevent@0__:expire notify
onPMessage pattern __key*__:* __keyspace@0__:notify expired
onPMessage pattern __key*__:* __keyevent@0__:expired notify

现在有一个用例,您也对过期密钥的 感兴趣。

注意: Redis 仅在 key 过期时通过 keyspace 事件的通知提供 key,key 过期后 value 丢失。为了使您的密钥过期,您可以使用阴影密钥的棘手概念执行以下工作:

当您创建通知键时,还要创建一个特殊的过期“影子”键(不要使实际通知过期)。例如:

// set your key value
SET notify umq 
//set your "shadow" key, note the value here is irrelevant
SET shadowkey:notify "" EX 10 

// 获取频道中的过期消息 keyevent@0:expired // 在“:”(或您决定使用的任何分隔符)上拆分密钥,获取第二部分以获得您的原始密钥

// Then get the value and do whatever with it
GET notify
// Then delete the key
DEL notify

请注意,shadowkey 的值未使用,因此您希望使用可能的最小值,可以是空字符串“”。设置需要做更多的工作,但上述系统完全可以满足您的需要。开销是一些额外的命令来实际检索和删除您的密钥以及空密钥的存储成本。

否则,您必须以包含附加值的方式准备密钥。

希望对你有帮助!

【讨论】:

它看起来很棒..你节省了我很多时间..我整天都在搜索这个..感谢 @Kuntal-G 的代码和正确的插图。 有什么方法可以获取onPMessage中的"umq"的值吗? 请查看更新后的答案,了解检索键过期值的方法。 如何先跑课?【参考方案2】:

这可能会对你有所帮助。

        JedisPool jedisPool=null;
        JedisPoolConfig poolConfig = null;

        try 

            poolConfig=new JedisPoolConfig();
            jedisPool = new JedisPool(poolConfig,"127.0.0.1" /*Host IP*/,1234 /*Port*/, 0);             
            Jedis jedis=jedisPool.getResource();            
            jedis.expire("KeyName", 10 /*Key Expires in 10 seconds*/);  

         catch (Exception e) 

        

【讨论】:

据我了解,用户询问如何在密钥过期时获得通知。而不是如何使密钥过期,如代码中所示。 @Vishvesh,感谢您的回复。但 Kuntal 是对的,我知道过期,但我正在寻找关于密钥过期的通知机制,如 redis 文档中所述。

以上是关于Redis Key 过期通知 Jedis的主要内容,如果未能解决你的问题,请参考以下文章

Redis中取得所有Key过期时间配置与获取Key过期通知。

Redis Key 过期事件监听

redis中键空间通知

Redis实践操作之—— keyspace notification(键空间通知)

Redis过期事件通知实现订单自动关闭

keyspace notification(键空间通知)