7

I am using Redis as a cache service in my Big Data application. The main purpose of Redis is to validate key which we receive from every request.

We use RMap for storing key and value pairs, example of which is as follows,

key = 1212sads23sads341212saas23asds45
value = Regular java object with some complex data.

I want to assign TTL for every key I insert and I know I can do that using RMap.expire(). What I am not getting is, how can I listen to when particular key expires. As every key is going to have a different TTL and as mentioned in Redis documentation, it takes care of auto expiration of keys and also generates events.

My question is,

  1. How can I capture the generated EXPIRE event and also get for which key it got generated in Redisson java library?

  2. Is this better approach(redis inbuilt autoexpiration), or running some thread which checks expired keys is better?

Rahul Borkar
  • 2,742
  • 3
  • 24
  • 38

1 Answers1

9

Since 3.4.3 version Redisson offers ability to register listener for map entry expiration.

Here is the usage example:

RMapCache<String, String> mapCache = redisson.getMapCache("myMap");
int expireListener = map.addListener(new EntryExpiredListener<String, String>() {
    @Override
    public void onExpired(EntryEvent<String, String> event) {
      event.getKey(); // expired key
      event.getValue() // expired value
      // ...
    }
});

map.put("key", "value", 10, TimeUnit.SECONDS);
Nikita Koksharov
  • 10,283
  • 1
  • 62
  • 71
  • I have 2 doubts further, 1. From where can I download latest version. 2. Is using listener better approach, because on Redis, they mentioned that, there can be significant delay in actual expire event and notification?? – Rahul Borkar Jul 19 '17 at 14:30
  • 1
    @RahulBorkar Answering to your questions: 1. Here is [quick start](https://github.com/redisson/redisson#quick-start) guide. 2. It uses own expiration approach not available in Redis. Yes, some delay could happen between actual expiration time and fire event moment. – Nikita Koksharov Jul 19 '17 at 17:05
  • Thanks for detailed response. Do you have any performance measures regarding delay which you mentioned? – Rahul Borkar Jul 20 '17 at 10:42
  • @RahulBorkar I'm afraid no – Nikita Koksharov Jul 20 '17 at 10:48
  • Is there any way to add an expiration listener to RBuckets? – zwebie Apr 23 '19 at 12:27
  • 2
    @zwebie Sure, use `RObject.addListener` method – Nikita Koksharov Apr 24 '19 at 12:06
  • @NikitaKoksharov thanks! Didn't see this since it was only added recently. – zwebie Apr 28 '19 at 08:59
  • This is implemented with topics so everyone will get and potentially act on a desired action. There is a case made for just one of the living connections to take care of it. To achieve that seems very complex. I propose that the redisson library add an intuitive way for easily managing just one consumer to get a message which will ideally be requed automatically if left in pending for too long. I've spent countless hours trying to implement something to get a solid queue kind behaviour but still not there. The queue and stream stuff is just not satisfactory as of now. – mjs Aug 27 '20 at 07:01
  • there is a connectionmanager accesiible only by casting or extending Redisson (why does create return a RedissonClient rather than Redisson?) and a connectionwatcher but not yet comprehended how I can utilize them rather than write my own connectionwatcher. there is no way as I can see to subscribe to any connection being closed to perform and move pending streams. it just logs. – mjs Aug 27 '20 at 07:04
  • "This is implemented with topics so everyone will get and potentially act on a desired action" - you can use RLock object to avoid that or RAtomicLong.compareAndSet – Nikita Koksharov Aug 27 '20 at 09:53
  • @NikitaKoksharov You mean to add it as part of the value? – mjs Aug 28 '20 at 20:00
  • @NikitaKoksharov Pease also consider adding a global event listener for IdleConnectionWatcher. It's nice that it logs, but it would be nice to be able to act on it. Right now, adding an expiry timeout on connected clients and renewing by putting again. When consumers of a stream goes idle, the pendings has to be taken care of and claimed. Right now, I am putting clients in a mapcache with TTL and renewing the time. At that point I would like to allow others to claim them. Not sure this is the best approach. – mjs Aug 28 '20 at 20:03
  • I posted a question related to the topic broadcasted on expiry: https://stackoverflow.com/questions/63639863/redis-will-a-topic-pub-sub-always-be-delivered-to-at-least-one-subscriber – mjs Aug 28 '20 at 20:03
  • The goal is not to miss the event ever of a consumer dying. I can probably thread poll a consumer going idle, but there should be better ways. A consumer going idle for me is based on a connectionid going idle. – mjs Aug 28 '20 at 20:04
  • Also, if you could clarify. How do I best fire a global event for that consumer going dead, for existing consumers to claim them? Should I create a separate stream for that since they will act as a queue? Or a topic and have a lock as a value to the topic. In my case since I am only interested in one consuming it a stream might be better. I think i am getting the hang of it. I saw your comment addressed to me by accident googling since you did not include my name :) – mjs Aug 28 '20 at 20:06
  • @NikitaKoksharov, why `EntryExpiredListener` instead of `EntryExpiredListener`? Shouldn't it be the same type as the `RMapCache`? – RCaetano Jun 04 '21 at 17:37