I have set an expiration value to a key in redis, and want to get the opportunity to run a piece of code before the key will be deleted by redis. Is it possible, and if so how...?
Thanks
My solution was to create a new key, with the same name as the one I wanted to hook, only I added a prefix for it indicating it's a key for timeouts usage ("TO") - something like:
set key1 data1
set TO_key1 ""
expire TO_key1 20
In the example above, as soon as "TO_key1" will expire, it will notify my program and I'll get the opportunity to run my code before I will manually delete "key1".
I found this link very useful for creating the listener for redis: Redis Key expire notification with Jedis
This isn't possible with standard OS Redis... yet. There is a way, however, to do something similar without too much hassle. If you stop using Redis' expiry (at least for those keys that you're interesting in "hooking") and manage expiry "manually" in your code, you can do anything you want before/during/after the expiry event.
Since Redis offers key-level expiry out of the box, people are usually content with it. In some cases, i.e.g. expiring members in a Set, the only way to go is the manual approach but that approach is still valid for regular keys when you need finer control.
Related
According to Redis documentaiton, EXPIREAT has the 'exact same effect and semantic as EXPIRE'.
EXPIRE invalidates itself when a key is retrieved via GET. There is no mention in the EXPIREAT documentation of a similar behaviour, but it would not make sense for EXPIREAT to no longer expire upon key retrieval.
Due to the vague nature of the documentation I am unable to tell what the actual behaviour of EXPIREAT is in this scenario.
Actually expiring itself when the key is retrieved is not the only way, according to documentation
Redis keys are expired in two ways: a passive way, and an active way.
A key is passively expired simply when some client tries to access it, and the key is found to be timed out.
Of course this is not enough as there are expired keys that will never be accessed again. These keys should be expired anyway, so periodically Redis tests a few keys at random among keys with an expire set. All the keys that are already expired are deleted from the keyspace.
For your question;
There is a generic expire function in the Redis codebase and in the comments section it says
This is the generic command implementation for EXPIRE, PEXPIRE, EXPIREAT and PEXPIREAT.
"my optimistic guess" is that these different expire( or *at) commands invoke this function with different parameters by making a conversion. So EXPIREAT command also has the same behavior as EXPIRE and the keys are expired with the same two ways.
I'm working with Spring Data Redis and I'm a little bit confused about the utility of phantom key. Below some questions about that :
What's the goal of Phantom Key for Spring Data Redis?
When should I save it or not? What are the impacts?
Is there best practices on this subject?
Thank advance for your feedback.
When the expiration is set to a positive value, the corresponding
EXPIRE command is run. In addition to persisting the original, a
phantom copy is persisted in Redis and set to expire five minutes
after the original one. This is done to enable the Repository support
to publish RedisKeyExpiredEvent, holding the expired value in Spring’s
ApplicationEventPublisher whenever a key expires, even though the
original values have already been removed. Expiry events are received
on all connected applications that use Spring Data Redis repositories.
By default, the key expiry listener is disabled when initializing the
application. The startup mode can be adjusted in
#EnableRedisRepositories or RedisKeyValueAdapter to start the listener
with the application or upon the first insert of an entity with a TTL.
See EnableKeyspaceEvents for possible values.
The RedisKeyExpiredEvent holds a copy of the expired domain object as
well as the key.
For more information see https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/#redis.repositories.expirations
I'm curious about best practices as far as expiring secondary indexes in Redis.
For instance, say I have object IDs with positions that are only considered valid for 5 seconds before they expire. I have:
objectID -> hash of object info
I set these entries to automatically expire after 5 seconds.
I also want to look up objects by their zip code, so I have another mapping:
zipCode -> set or list of objectID
I know there's no way to automatically expire elements of a set, but I'd like to automatically remove objectIDs from that zip code mapping when they expire.
What is the standard practice for how to do this? If there were an event fired upon expiration I could find the associated zip code mapping and remove the objectID, but not sure there is (I will be using Go).
If there were an event fired upon expiration I could find the associated zip code mapping and remove the objectID, but not sure there is
YES, there is an expiration notification, check this for an example.
You can have a client subscribing to the expiration event, and delete items from the zipCode set or list.
However, this solution has two problems:
The notification is NOT reliable. If the client disconnects from Redis, or just crashes, client will miss some notifications. In order to make it more reliable, you can have multiple clients listening to the notification. If one client crashes, others can still remove items from zipCode.
It's NOT atomic. There's a time window between the key expiration and removing items from zipCode.
If you're fine with these 2 problems, you can try this solution.
I have a program that utilizes a redis key with an expire time set. I want to detect when there is a new entry to the data set. I can tell when there is a removal by listening for the "expired" event, but the "set" and "expire" events are fired every time the key is set, even if it's already in the database.
Is there a keyspace event for a NEW key appearing?
There's no keyspace configuration that detects that a key was overwritten vs. newly added.
If you are primarily using the SET command, you may be able to take advantage of the NX option and publish a custom event based on the result. Obviously this isn't an ideal approach, but it's something.
https://redis.io/commands/set
Example of a custom event:
PUBLISH __keyevent#0__:new_data_entry new_key
Details on that here: https://redis.io/topics/notifications#type-of-events
Hope that helps.
I'm trying to solve the following problem in Redis.
I have a list that contains various available keys:
List MASTER:
111A
222B
333C
444D
555E
I'd like to be able to pop an element off of the list and use it as a key with an expires.
After the expires is up, I'd like to be able to push this number back onto MASTER for future use. I don't see any obvious way to do this, so I'm soliciting for a creative one.
The best method would be to get called back by Redis when the key expires and then take action.
However, callbacks support is still to be added (http://code.google.com/p/redis/issues/detail?id=360).
You can either use a Redis version that contains a custom/community modification to support this feature (like the last one in the link I've posted), or worse :): start tracking keys and timeouts in your client app.