I want to use Redis as a random seed cache. When I want the value for a key, if nothing's there yet, I'll produce a random string and store it for later reuse.
How do I perform an atomic GET EXISTING OR SET AND RETURN THIS VALUE?
You could use SETNX to try and set the value first. Then the GET would give you the existing value or the new one you tried to set.
SETNX key value
This may return 0 or 1 if you care to know if this is a new value
It seems there is no single command that can do this. Using MULTI and WATCH:
First:
GET key
If null, then:
WATCH key
MULTI
SET key value
EXEC
If [null] (indicating the transaction aborted), the key was created in the meantime and must exist by now:
GET key
Related
I have case where i need to save values to redis SET structure under given key so i am using command from my code in the loop
SADD key value
EXPIRE KEY 100
However, i would like to set expiration time only on first save of the set key.
Is it possible to set expire time only at the moment of first set key creation ?
it is also should be noted that i can use EXISTS key call to redis to check if key exist and depending on that set expiration time or not - but this operation is not atomic.
To answer the question - no, there isn't such a command.
As you noted, this could be worked around with EXISTS. To address the atomicity (and save on network) requirement you can use a Lua script (see EVAL).
Redis 7.0 has a new option "NX -- Set expiry only when the key has no expiry". So, you could solve the problem with EXPIRE KEY 100 NX.
However, that it doesn't matter if you call EXPIRE KEY 100 1 or, let's say, 5 times. The key will expire after 100 seconds, thus checking EXISTS key is also an option.
I'm working with redis 2.8 with win10-64. As you can see in the screenshot I have a number of long keys. Rather than type or cut and paste them , is there a way to get the value by selecting their number in the list (you can see my 2 failed attempts) ?
Can you select the value of a REDIS key by the number of key in list?
NO, You can't.
Because Redis-cli does not support this feature. And even though if you know the key, you can't fetch the data without knowing it's data type.
Suppose you have a set/HashMap corresponding to a key. For that key command get <key> will not work for that typed data.
I would like to increase a value only if a certain key exists. If the key does not exist, the value should be set to 1. Is it possible to implement this logic as an atomic step?
The INCR command does exactly what you want.
If the key does NOT exist, the value will be set to 0 before performing the increase operation, i.e. the value will be set to 1. And the command runs atomically.
UPDATE
If the key to be increased is NOT the same key whose existence is checked, you have to write a Lua script to do the work in a transaction.
if (redis.call("exists", KEYS[1]) > 0) then redis.call("incr", KEYS[2]) end
I want to increment a redis counter but I want to start counting not from zero but from a defined starting number (for example -5).
I know how this can be achieved via SET/INCR inside a Lua script but I was wondering if I can achieve it only with INCR command. Something similar we define for INCRBY where the increment is defined, can we define the starting point?
Lua is perfectly fine for this procedure, but you can also do it with a transaction:
MULTI
SET counter -5 NX
INCR counter
EXEC
The INCR will run every time, so if you want your first call to set it to -5 you should change the SET value to -6. You can also pipe those 4 commands to avoid the 4 RTTs of sending the commands.
You can't do it with the INCR command alone. I would inspect the value of SETNX and if it returns 0 (meaning the key existed), then increment it.
Notice that if you are talking about non expiring counters, you can achieve atomicity this way without Lua, at the price of two roundtrips: If the key did not exist, we create it, set it to the initial value and that's it, one roundtrip, atomic. If it did exist, we increment it, but we are still consistent (unless the key expired or was deleted between the two calls).
However, there is no reason not to use a Lua script for this, it's the preferred way to do this stuff.
I am interested in creating several different redis based counters in my web application. A lot of this stuff is basically for metrics etc, but that doesn't make a difference. My question is essentially the following, is it possible to avoid doing:
if $redis.get(key) != null
// increment key
else
// create key with a counter of 1
Ideally something like this would be more optimal
$redis.incr(key, 1) // increment key by 1, and if it does not exist, start it at the value 1
am I overlooking the redis documentation? Is there a way to do this currently?
there is a INCR command, which if the key does not exists sets the value of the key to 1
$redis.incr()
should work.
see http://redis.io/commands/incr