redis / node-redis

Redis Node.js client
https://redis.js.org/
MIT License
16.95k stars 1.89k forks source link

The values ​​do not expire #2847

Closed xr0master closed 1 month ago

xr0master commented 1 month ago

Description

Hi, I'm a bit confused as I'm not even sure if this is a bug or something else.

We use Redis as a cache, which we add via the setEx command. However, recently, we have started to have some keys that return -1 with the TTL command. It doesn't happen often, but such events do occur. What could be causing this?

The decrBy command is called with the same keys. Can this somehow affect the expire field?

Node.js Version

20

Redis Server Version

7.2.3

Node Redis Version

4.7.0

Platform

alpine

Logs

No response

leibale commented 1 month ago

[INCR|DECR][BY] does not change the key TTL:

> SET key 0 EX 100
OK
> EXPIRETIME key
(integer) 1728320556
> DECRBY key 1
(integer) -1
> EXPIRETIME key
(integer) 1728320556

but, depending on your code, you might have a race condition.. assuming your code is doing something like:

> EXISTS key
(integer) 1

then doing some work, and then:

> DECRBY key 1

the key TTL might be in between the EXISTS and the DECRBY, which means EXISTS will return true, but DECRBY will recreate the key, without setting a new TTL on it.

xr0master commented 1 month ago

Oh, o, ooo! You've pointed out our logic quite closely and a possible problem. Thank you so much! We'll write our own LUA script to avoid making a decrBy if there is no value.