Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redis Key expire notification with Jedis

Tags:

java

redis

jedis

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.

like image 365
Rocky Ray Avatar asked Oct 16 '14 13:10

Rocky Ray


People also ask

What happens when Redis key expires?

After the timeout has expired, the key will automatically be deleted. A key with an associated timeout is often said to be volatile in Redis terminology. The timeout will only be cleared by commands that delete or overwrite the contents of the key, including DEL , SET , GETSET and all the *STORE commands.

What is Redis Keyspace notifications?

Redis keyspace notifications allow you to subscribe to PubSub channels. Through the channel, clients receive published events when a Redis command or data alteration occurs. These notifications are useful when an application must respond to changes that occur to the value stored in a particular key or keys.

How do I set Redis to expire?

To create a Redis with an expiration time, use the SET command and the EX option to set the expiration time. The EX option takes a number in seconds and sets the number of seconds the key is valid until expiration. You can also use PX to specify the expiration time in Milliseconds.


1 Answers

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!

like image 167
Kuntal-G Avatar answered Nov 02 '22 21:11

Kuntal-G