Redis - setex - value is not an integer or out of range - redis

The following used to work fine:
redis_client.setex(key, expiry_in_sec, value_json)
And now it suddenly returns:
value is not an integer or out of range

The issue is between the different redis clients.
When working with StrictRedis, the setex syntax is:
setex key, expiry, value
When working with Redis client, the setex syntax is:
setex key, value, expiry
our specific problem was that someone changed the redis client.

Redis will also return this error if the time value (or expiration time) is a float instead of an int.
In my case, using Redis in Python, I had to change the following:
Causes Error
ex = expiration_delta.total_seconds()
Fixed
ex = int(expiration_delta.total_seconds())
success = redis.set(name=redis_key, value=my_val, ex=ex, nx=True)
Note the ex argument to set() makes it work like setex.

Related

lua setting an expiration time using the redis command with 'setex' appears as a permanent key in openresty

setting an expiration time using the redis command appears as a permanent key when i do this in openresty with lua script.
the lua script is follow this:
local function ip_frequency(ip,red)
local limit_num=50
local key = "limit:frequency:"..ip
local resp, err = red:get(key)
if resp==nil then
local ok,err=red:setex(key,2,1)
if not ok then
return false;
end
end
if type(resp) == "string" then
if tonumber(resp) > limit_num then
return false
end
end
ok, err = red:incr(key)
if not ok then
return false
end
return true
end
When the openresty program has run for some time,some permanent keys appear in redis.From this function it can be seen that I did not set a key for the permanent time,but it just happens. Why is that,please help me answer this question. Thank you!
The software version is as follows:
openresty: 1.17.8.2
redis: 6.0+
centos: 8.0+
Openresty connects to redis database and uses it's functionality. Such usage of redis functions in lua or other language is not atomic. For redis server it means: [redis:get, pause, redis:setex] or [redis:get, pause, redis:incr]. During pause period can happen a lot of things, event if there is only 1ms, such as cleanup of 'dead' keys.
And this what could happen with your code:
local resp, err = red:get(key)
You get valid key value which is smaller than limit_num
ok, err = red:incr(key)
Redis checks if key is valid, and removes it if reaches ttl
Redis checks that there is no such key, so creates key with value=0 and increments key value
So at this point you have permanent key. If you want to avoid permanent keys, use something like: red:setex(key,2,tonumber(res)+1) istead of red:incr(key)

How to set value with NX option and expire using ServiceStack.Redis?

I'm using ServiceStack.Redis to execute commands on REDIS.
I would like to simply set value with expire and NX option (which is : set only if not exists).
SET resource_name my_value NX PX 30000
The problem is that ServiceStack.Redis client has only two methods:
client.SetValue() // <-- this one has Timespan expire argument
client.SetValueIfNotExists() // <-- this one doesn't
Is there a way to do this ?
I see a public bool SetValueIfNotExists(string key, string value, TimeSpan expireIn) in RedisClient.cs, line 183
Please mention what version are you using if you don't see it in your included package.

using .net StackExchange.Redis with "wait" isn't working as expected

doing a R/W test with redis cluster (servers): 1 master + 2 slaves. the following is the key WRITE code:
var trans = redisDatabase.CreateTransaction();
Task<bool> setResult = trans.StringSetAsync(key, serializedValue, TimeSpan.FromSeconds(10));
Task<RedisResult> waitResult = trans.ExecuteAsync("wait", 3, 10000);
trans.Execute();
trans.WaitAll(setResult, waitResult);
using the following as the connection string:
[server1 ip]:6379,[server2 ip]:6379,[server3 ip]:6379,ssl=False,abortConnect=False
running 100 threads which do 1000 loops of the following steps:
generate a GUID as key and random as value of 1024 bytes
writing the key (using the above code)
retrieve the key using "var stringValue =
redisDatabase.StringGet(key, CommandFlags.PreferSlave);"
compare the two values and print an error if they differ.
running this test a few times generates several errors - trying to understand why as the "wait" with (10 seconds!) operation should have guaranteed the write to all slaves before returning.
Any idea?
WAIT isn't supported by SE.Redis as explained by its prolific author at Stackexchange.redis lacks the "WAIT" support
What about improving consistency guarantees, by adding in some "check, write, read" iterations?
SET a new key value pair (master node)
Read it (set CommandFlags to DemandReplica.
Not there yet? Wait and Try X times.
4.a) Not there yet? SET again. go back to (3) or give up
4.b) There? You're "done"
Won't be perfect but it should reduce probability of losing a SET??

How to set a string with TTL with StackExchange.Redis

I'm looking for a way to do a very simple TTL string in Redis:
So how do I do the equivalent of the following in StackExchange.Redis?
SETEX lolcat 10 "monorailcat"
I found KeyExpire, but that means every key I set needs two calls?
Oops. Never mind:
_Redis.StringSet( "lolcat", "monorailcat", TimeSpan.FromSeconds(10) );

my redis keys do not expire

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.