Redis - keys disappear - redis

Is it possible to disappear keys in Redis without reason? I'm adding keys to redis:
Transaction transaction = jedis.multi();
transaction.incrBy(positionsQuantityKey, positionQuantity);
transaction.expire(positionsQuantityKey, 24 * 3600);
transaction.exec();
but after few minutes I ran command:
jedis.keys("*");
and the key disappeared. What could delete this key? I'm sure that expire time was succesfully set, because result of this command was 1.
I'm using redis 2.6

If you're not doing anything else with Redis during that time, open a MONITOR session with redis-cli and look what goes on - another process could be deleting your key.
Alternatively, perhaps you're running low on RAM and Redis' eviction policy is configured to evict volatile keys.

Related

Redis creating a Set with expiry

When I create a new Set (using SADD) I need to set the expiration for that Set.
Is there any way to create a Set key with expiry?
Note: I need to do that in one command, because my program checks if the set exists before going to update it - so if its existing with no expiration no update will occur.
My program runs on AWS so if I split it to 2 commands, only the creation can be executed without the expiration (happened to me in the past).
Thanks!
I couldn't find a way to set expiry on a Set other than using the EXPIRE command - risking in the program crashing before the EXPIRE command (i.e. AWS service restarting for any reason) and the Set existing with no expiration.
Edit: I found a work-around, when I can check if the TTL of the key is < 0 instead of EXISTS, so if the EXPIRE didn't work for some reason I will update the Set anyway. This can help but I prefer to also save traffic when expiring the Set, and send one command (i.e. SADD with expiry) instead of SADD and EXPIRE.
What about using transactions? For example:
multi
sadd key member1 member2 ...
expire key seconds
exec
It is guaranteed that the sadd and expire will be executed as a single unit on the node and on replicas if you use any. If you use pipelining you don't need to do it in multiple rounds from the client so perf will have minimal / no impact.

Avoid distributed lock when executing an update transaction on Redis?

I have the following Redis read/writes needs to be run in a transaction (atomically).
Read key 1
Read key 2
Read key 3
Write key X
And,
When a transaction is running, other processes are not allowed to write key 1, 2, 3, or X.
The transaction is atomic, no two transactions can be run at the same time.
I can use Redis lock (distributed lock) to achieve this. However, I heard that a lot of time it cannot acquire the lock from another team. Is it a way to avoid Redis lock?

How do I ensure I have TTL for every key in Redis?

I insert values to Redis, with the following code :
await this.redisClient.rpushAsync(namespaceKey, value);
await this.redisClient.expireAsync(namespaceKey, TTL);
If code fails after the first command, I'll have an entry in Redis without TTL -> forever.
How can I ensure I have TTL for every key in Redis?
Will using MULTI-EXEC solve my problem? from Redis documentation I see that Redis does not support rollbacks, so in that case, the first command (rpush) succeed but the second command fail, and there is no rollback, so I'll have key without TTL.

Redis replication order

In a master-slave scenario, Redis replication is made in an asynchronous way. But is it guaranteed that the commands are replicated in order? If I have these commands:
SET key1 111
SET key2 222
SET key3 333
If the slave node has "key2", then I can say for sure that it'll also have "key1"?
Yes, commands are replicated in order. Anything else wouldn't actually be replication.
As described in the documentation, both the master and the replica keep track of an offset indicating where they are in the stream of commands. That allows the replica to know if it receives a command out of order and not process it prematurely.

How to skip GTID transaction for a particular channel in MyQL?

We can skip a error in GTID based replication by following steps:
STOP SLAVE;
set GTID_NEXT='SERVER_UUID:LAST_TRANSACTION_NUMBER+1' ;
BEGIN; COMMIT; SET GTID_NEXT="AUTOMATIC";
START SLAVE;
But if a replication is running with channel information, than how to skip the transaction for a particular channel ?
We can give "for channel" keyword in stop slave and start slave. But how to skip transaction for a particular channel, like in set GTID_NEXT command or what ?
In a replication topology GTID is a global unique identified for any transaction, therefore if transaction is required to skip, specifying channel becomes irrelevant here.
It is similar to MySQL Replication Filters [MySQL 5.7] are global , or in other words, will be applied for all running replication channels