How to flush Redis keyspace of expired keys? - redis

Backstory: The keyspace of the Redis database in question reports a large amount of expired keys and memory usage is maxed out. The application using this database is experiencing (rare) intermittent timeouts and I thought (in my limited knowledge) perhaps it is because Redis is having to eject expired keys each time a new key is created.
So to my question: how do I tell Redis to remove all the expired keys?
Secondarily -- is it possible to access/see expired keys with redis-cli?
Here's a slice of the INFO I'm looking at:
maxmemory_policy:allkeys-lru
expired_keys:24326586
evicted_keys:134022997
keyspace_hits:2684031719
keyspace_misses:186380210
slave_expires_tracked_keys:0
active_defrag_key_hits:0
active_defrag_key_misses:0
db2:keys=12994468,expires=3193,avg_ttl=1891176

Answer for myself, posterity, and any other Redis newbies out there. I was looking at the wrong "database". I was under the WRONG impression that Redis only had single table but looking at my question you see "db2". I searched into that and found that Redis can have up to 16 databases identified by a zero-based index. In this case:
SELECT 2
That selects "db2" and now doing a DBSIZE gives a more accurate output.
Oye -- so the problem is that the keys are still there! Otherwise when Redis expires a key it deletes it.
Whoops! I'm leaving my question because someone else might think to ask the same thing and be on the wrong route.

Related

Redis expiration replication to slaves

I am interested in using Redis to store a customer's session on the server side for authorization. Basically, when a customer logs in a hash will be stored in a Redis cluster and the key returned to the client. On each request, the client will pass the key as a header and the service will check that the hash still exists in Redis, if it doesn't then an error message will be returned. This key will expire after X minutes resulting in any requests using that key to fail. However, I have been reading online that some people experienced issues because of the way the expiration is replicated to slaves. Slaves only expire a key when they receive a del command from the master so if a "get" is made on a slave before this command, the value at that key will be returned.
https://github.com/antirez/redis/issues/187
Does this issue still exist? It seems like a big issue to me and would create a bit of a security hole. Maybe not a big deal for stale data but when using for authorization it is a big deal
A) no, not really — since 2014, a GET of an expired key will return "not found" on a slave even if the slave hasn't yet received a DEL from the replication stream. The outstanding issue has to do with EXISTS being inconsistent with GET, which only matters if you rely on the output of the EXISTS command.
B) Completely independent of this issue, the possibility of replication lag always exists. The security of your app shouldn't depend on the premise that replicas are always up-to-date.

redis expiry keys holding memory

We are expiring 1000 keys per sec by average while taking snapshot we happened to see the size of the dump is comparatively lesser than the primary since because the snapshot is excluding the expired key's memory. Since expiring keys holding much memory in our platform, is there any way that we can make redis to release the memory held for expired keys periodically. (we are using 2.8.21 engine) or latest redis engine versions will resolve this problem little efficiently.
Please guide me to the correct platform if stackoverflow is not appropriate for my question.
Reclaim memory guide : https://docs.redislabs.com/latest/ri/memory-optimizations/reclaim-expired-keys-memory-faster/ ( but need suggestion, whether upgrading will help a lot or doing scan will be good as mentioned in the doc)
Expired keys are removed from memory:
Passively: when you try to access it and the key is found to be timed out. This is how doing a full SCAN would help you, it forces a passive removal across all the keyspace.
Actively: every 100 ms, it tries to remove from memory expired keys at random, never investing more than 1 ms per cycle at it, until it estimates that less than 25% of expired keys remain. The logic is not that trivial, see activeExpireCycle (2.8.21 version).
Upgrading may help as there new features/configuration settings, like activedefrag.
Please see Redis filling up memory fast, running --bigkeys free it up for solutions including eviction policy and active expiring frequency.

how to check the expiration for all keys in a production environment for a Redis database

some keys do not have expiration date. Best way I can think of is to use "get *" (but there are millions of keys), store that and then use the TTL to see if has an expiry. If it doesn't then you set it.
Would this be the way to go?
I see a similar question here, that's not a unix command. How would I implement this in unix or maybe C#(I am using SSH Nuget package)?
2 ways to do that:
through the redis database notification, you can know the op on redis key, and by subscribe those messages, you can run ttl on those keys.
run a task that scan the redis key set and run ttl on them.
The main idea is that do it quick and dont block the redis.

How to get all redis keys close to expire

I want to make the key live longer if some condition met.
What I think is if I can query all the keys close to expire (like 10 minutes to expire), then I can do the query-check-activate intervally.
I seached but not found any clue, if you know how to achieve it, please tell me.
Any help will be highly appreciated!
Querying for keys based on their expiration time is not supported by Redis at the moment.
You can work around this by not using Redis' built-in expiration and managing it yourself, e.g. by using a Sorted Set to track expiration times and implementing passive and active expiration in your application.
Alternatively, you can use SCAN to crawl the keyspace, fetching TTLs and performing your evaluations.

Make All Keys Expire By Default In Redis

I'm using MSETNX (http://redis.io/commands/msetnx) as a locking system, whereby all keys are locked only if no locks already exist.
If a machine holding a lock dies, that lock will be stuck locked - this is a problem.
My ideal answer would be that all keys expire in 15 seconds by default, so even if a machine dies it's held locks will auto-reset in a short time. This way I don't have to call expire on every key I set.
Is this possible in any way?
To build a reliable lock that is high available please check this document: http://redis.io/topics/distlock
The algorithm is still in beta but was stress-tested in a few sessions and is likely to be far more reliable than a single-instance approach anyway.
There are reference implementations for a few languages (linked in the doc).
Redis doesn't have a built-in way to do MSETNX and expire all keys together atomically. Nor can you set a default expiry tube for keys.
You could consider instead:
1. Using a WATCH/MULTI/EXEC block that wraps multiple 'SET key value EX 15 NX', or
2. Doing this using a Lua server-side script.