I want to implement Absolute and Sliding Caching In Redis. Does anyone have any resource link then it will be helpful
Redis already have many commands for this :
EXPIRE : Set a timeout on key.
EXPIREAT : Same as previous but takes an absolute Unix timestamp (seconds since January 1, 1970).
TTL : Returns the remaining time to live of a key that has a timeout
One important thing you have to know about Expiration on Redis : the timeout value is cleared only when the key is removed or overwritten using SET or GETSET. All others commands (INCR, LPUSH, HMSET, ...) will never change the initial timeout.
Absolute expiration is a native feature of Redis using EXPIRE. To implement a sliding expiration you simply need to reset to timeout value after each command.
A basic way to do this could be
MULTI
GET MYKEY
EXPIRE MYKEY 60
EXEC
Related
What is the maximum possible value that Apache2 Web Server allows for it's TimeOut directive in your httpd.conf or apache2.conf (in server config or vhost config) without failing back to the default value?
EDIT: To clarify, what I mean by 'failing back to the default value'.
It appears that when exceeding the upper bound of the directive, the value defining the TimeOut will revert back to 300. An example of this would be setting the TimeOut to 1800 (seconds), the server will continue to keep the request alive for 30 minutes succesfully. Whereas if you were to set the TimeOut to 31536000 (seconds) or 1 year, the server will revert or fail back to the default value of 300 (seconds) and only keeping the request alive for 5 minutes.
References:
http://httpd.apache.org/docs/2.0/mod/core.html#timeout
The default is set to 300 (seconds)
Though I am not sure I understand what you mean when you say - "without failing back to default value?", I am assuming that you are trying to determine the upper bound for Apache's Timeout directive. I dont believe org.apache.hc.core5.util.Timeout enforces an upper bound on its value. If you look at the source for Timeout, you will notice that timeout parameter values are Java longs. For example -
public static Timeout of(final long duration, final TimeUnit timeUnit) {
return new Timeout(duration, timeUnit);
}
So I believe that the directive's upper bound theoretically is the upper bound for Java long.
That said, please clarify what you mean by - "without failing back to default value?"
I have a use case where I'm aggregating until a TTL hits 0 on the key/value in Redis. As far as I can tell in the documentation, retrieval or a background job triggers all expired keys to be deleted immediately.
Is there anyway I can 'halt' that deletion and retrieve the value at the time of expiry? Or something similar to that effect?
My last question contains some context to my use case: Redis - any way to trigger an event when a value is no longer being actively written to?
I believe I found an answer to my question. Every row would have a corresponding row with with the convention expiry:{key}.
uniqueEventHash: [value1, value2, value3] // no expiry
expiry:uniqueEventHash: {no value} // set TTL to 60
Now, whenever a new value for that uniqueEventHash arrives, I do two things. I append it onto the uniqueEventHash row with an append, and then I also subsequently reset the TTL on expiry:uniqueEventHash to 60.
When events for that uniqueEventHash stop arriving, the second expiry:expiry:uniqueEventHash is deleted and a notification is sent out to a subscriber to EXPIRY events. In the message is the key that expired, which in this case is expiry:uniqueEventHash.
I can then do the following:
// pseudo code
onExpiryEvent(message):
[type, key] = eventMessage.split(':');
aggregatedValue = await getByKey(key);
del(key);
I can't find anywhere online what is default TTL in Redis.
I know that I can set TTL for specific SET, but don't know what is default TTL.
Can someone tell me what default time to live is in Redis?
There is no default TTL. By default, keys are set to live forever.
The keys with no expiration time set will not expire.
If you mean TTL command specifically, starting with v2.8, it will return -2 if no EXPIRE value is set.
Edit:
Itamar Haber's comment is true, I recalled false: There is no such setting in redis config for a global TTL. So I deleted the part about that.
Edit2: Also see the link to the official docs about default expiration of keys here: https://redis.io/commands/expire#appendix-redis-expires
I suppose value set to '-1' by default which means forever.
127.0.0.1:6379> set datakey "my-data"
OK
127.0.0.1:6379> TTL datakey
(integer) -1
127.0.0.1:6379>
REDIS Docs says
Starting with Redis 2.8 the return value in case of error changed:
The command returns -2 if the key does not exist.
The command returns -1 if the key exists but has no associated expire.
I would like to keep my objects in the Rails cache so long as there is a read within some interval (say 10 minutes). I can successfully set a TTL on cache object creation with:
Rails.cache.fetch('key', expires_in: 10.minutes) do
some_expensive_operation
end
But I notice that subsequent cache reads for 'key' do not up the TTL (at least not in my setup, which is Rails 3.2 + Redis).
Is there a way to have Rails.cache.{fetch,read} re-up the TTL for cache hits?
My alternative is to do the following, which seems potentially wasteful:
result = Rails.cache.read('key') || some_expensive_operation
Rails.cache.write('key', result, expires_in: 10.minutes)
Here's a redis-specific solution I came up with:
def fetch(key, ttl_seconds)
cached_value = $redis.get(key)
if cached_value
# re-up the TTL
$redis.expire(key, ttl_seconds)
result = Marshal.load(cached_value)
else
result = yield
$redis.setex(key, ttl_seconds, Marshal.dump(result))
end
result
end
fetch('key', 10.minutes) do
some_expensive_operation
end
I'd prefer something that's cache-provider neutral, but that just doesn't seem to be part of the Rails caching API, unless I've missed something.
As I understand you want update TTL on fetch just to make cache store only frequently used records. I guess the reason is cache size.
Just don't do that! Let cache engine to decide what records to keep. If you're using Memcached it does this job out of box, you can never bother deleting old records. If you're using Redis you need to configure it as an LRU cache.
My redis server does not delete keys when the time-to-live reaches 0.
Here is a sample code:
redis-cli
>SET mykey "ismykey"
>EXPIRE mykey 20
#check TTL
>TTL mykey
>(integer) 17
> ...
>TTL mykey
>(integer) -1
#mykey chould have expired:
>EXISTS mykey
>(integer) 1
>#oh still there, check its value
>GET mykey
>"ismykey"
If i check the info return by redis, it says 0 keys were expired.
Any idea?
thanks.
Since you're doing a '...' it's hard to say for sure, but I'd say you're setting mykey during that part, which will effectively remove the expiration.
From the EXPIRE manual
The timeout is cleared only when the key is removed using the DEL
command or overwritten using the SET or GETSET commands
Also, regarding the -1 reply from TTL
Return value
Integer reply: TTL in seconds or -1 when key does not
exist or does not have a timeout.
EDIT: Note that this behaviour changed in Redis 2.8
Starting with Redis 2.8 the return value in case of error changed:
The command returns -2 if the key does not exist.
The command returns -1 if the key exists but has no associated expire.
In other words, if your key exists, it would seem to be persistent, ie not have any expiration set.
EDIT: It seems I can reproduce this if I create the key on a REDIS slave server, the slave will not delete the key without master input, since normally you would not create keys locally on a slave. Is this the case here?
However while the slaves connected to a master will not expire keys
independently (but will wait for the DEL coming from the master),
they'll still take the full state of the expires existing in the
dataset, so when a slave is elected to a master it will be able to
expire the keys independently, fully acting as a master.