How can I update a redis value without affecting the remaining TTL?
Solution 1
The KEEPTTL option will be added to SET in redis>=6.0
https://github.com/antirez/redis/pull/6679
The SET command supports a set of options that modify its behavior:
EX seconds -- Set the specified expire time, in seconds.
PX milliseconds -- Set the specified expire time, in milliseconds.
NX -- Only set the key if it does not already exist.
XX -- Only set the key if it already exist.
(!) KEEPTTL -- Retain the time to live associated with the key.
Solution 2
According to Redis documentation, the SET
command removes the TTL because the key is overwritten.
However you can use the EVAL
command to evaluate a Lua script to do it automatically for you.
The script bellow checks for the TTL value of a key, if the value is positive it calls SETEX
with the new value and using the remaining TTL.
local ttl = redis.call('ttl', ARGV[1]) if ttl > 0 then return redis.call('SETEX', ARGV[1], ttl, ARGV[2]) end
Example:
> set key 123
OK
> expire key 120
(integer) 1
... after some seconds
> ttl key
(integer) 97
> eval "local ttl = redis.call('ttl', ARGV[1]) if ttl > 0 then return redis.call('SETEX', ARGV[1], ttl, ARGV[2]) end" 0 key 987
OK
> ttl key
96
> get key
"987"
Solution 3
Maybe the INCR
, INCRBY
, DECR
, etc. can help you. They don't modify the TTL.
> setex test 3600 13
OK
> incr test
(integer) 14
> ttl test
(integer) 3554
Solution 4
It is possible to change the value without affecting TTL on it's key by changing value bits one by one according to new value by using SETBIT.
Disadvantage of this approach however is obviously performance impact, especially if value is quite big.
NOTE: It is advisable to execute this in transaction (multi exec) block
Maintaining TTL by ourselves by
-
Fetching current TTL
-
Set new value
-
Restoring TTL after setting value
is obviously not advisable due to unknown durability of the commands executed.
Another alternative is to use List as data type and after adding new value to the list with LPUSH use LTRIM to maintain size of list to single element. This wont change TTL on the key.
Related videos on Youtube
paulkon
Updated on July 09, 2022Comments
-
paulkon almost 2 years
Is it possible to
SET
redis keys without removing their existing ttl? The only way I know of at the present time is to find out the ttl and do aSETEX
but that seems less accurate. -
Muhammad Ali about 2 yearsthis worked perfectly for me as I was dealing with integer values.