Redis Key expire notification with Jedis

23,386

You can do it with the pub-sub model only Start Redis Server

Change the notify-keyspace-events in redis.conf to KEA (this depends on your requirement).Details given in redis documentation http://redis.io/topics/notifications.

Redis Java Client (Jedis) ,Try the following:

Notification Listener:

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


}

Subscriber:

****Note** jedis.psubscribe(new KeyExpiredListener(), "__key*__:*"); -- This methods support regex pattern based channel whereas jedis.subscribe(new KeyExpiredListener(), ""__keyspace@0__:notify"); --This method takes full/exact channel name

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*__:*");

    }

}

Test Class:

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);

    }
}

Now first start your Subscriber and then Run the TestJedis.You wil see the following output:

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

Now one use-case where you are interested in the value of the expired key as well.

Note: Redis only provide the key on expiration of key through notification of keyspace events, value is lost once the key expire. In-order to get the value on your key expire you can do the following work around shown below with the tricky concept of shadow key:

When you create your notify key, also create a special expiring "shadow" key (don't expire the actual notify). For example:

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

// Get an expiration message in the channel keyevent@0:expired // Split the key on ":"(or whatever separator you decide to use), take the second part to get your original key

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

Note that the value of the shadowkey isn't used so you want to use the smallest possible value, could be an empty string "". It's a little more work to setup but the above system does exactly what you need. The overhead is a few extra commands to actually retrieve and delete your key plus the storage cost of an empty key.

Otherwise you have to prepare your key in such a way that it includes the value appended with it.

Hope it helps you!

Share:
23,386
Rocky Ray
Author by

Rocky Ray

Updated on July 09, 2022

Comments

  • Rocky Ray
    Rocky Ray almost 2 years

    I am trying to implement a expiry key notification with redis ,when my key expires in the redis data store. The redis website provides some description of how http://redis.io/topics/notifications, but Im unable to find any example how to do it using redis java client like Jedis?

    Any possible code with illustration will be very helpful as im new to redis.

  • Kuntal-G
    Kuntal-G over 9 years
    As per my understanding user is asking how to get notification when the key expire.Not how to expire a key as you have shown in your code.
  • Rocky Ray
    Rocky Ray over 9 years
    @Vishvesh,Thanks for your reply.But Kuntal is right,i know about the expiry,but i was looking for the notification mechanishm on key expire,as mention in redis documentation.
  • Rocky Ray
    Rocky Ray over 9 years
    It looks great..You saved lots of my time man..I was searching about this all day long..Thanks @Kuntal-G for your code and proper illustration.
  • Kaidul
    Kaidul over 7 years
    Is there any way to get the value "umq" in onPMessage?
  • Kuntal-G
    Kuntal-G over 7 years
    please check the updated answer for the way to retrieve the value on key expire.
  • Don Corleone
    Don Corleone over 6 years
    How to run a class first?