Redis cli - KEYS * not showing all keys - redis

I am connecting to an AWS redis cluster using following command
redis-cli -c -h host.amazonaws.com -p 6379
I pushed two key "X1" and "X2" into redis cache from a springboot application (API methods are not annotated with #Cacheable) and now when I run KEYS * from cli terminal it would list either "X1" or "X2" but not both. GET for both keys works fine though.
info keyspace return following;
Keyspace
db0:keys=11,expires=1,avg_ttl=1975400
What am I missing here?

You probably have cluster mode enabled. In cluster mode, the data you store is partitioned by key. One of the advantages of this is that you can now have a larger dataset than would reasonably fit on one machine (hundreds of terabytes, if you want) since every shard has some fraction of the entire data set.
A downside is that multi-key commands no long work like you would expect if the keys end up in different hash slots. The KEYS command is such a multi-key command.
To make a long story short:
KEYS is apparently giving you only the keys on the cluster node you're hitting. It would perhaps have been nicer to give you an error, instead, but it doesn't.
GET is unaffected: redis-cli, with the -c flag, knows how to find the right cluster node (perhaps after hitting the wrong one and being told the key has MOVED).
If you ask every individual primary node in your cluster for KEYS *, and add up all the results, you should get all the keys. This question has some examples of using the redis-cli to do this.

Related

Redis Commander - command to show last key

I'm doing some diagnostics on a system (I didn't develop), and it's running Redis and Bull to queue API calls. I need to see if/why some API calls are failing. I have access to a web interface of Redis Commander.
There's 90,000+ keys, and when you expand the "tree", it takes several minutes to load.
I would just like a command to run that shows me the last 10 keys added.
(or a command that tells me the ID # of the last key, and another command that let's me display the data of the key, without needing to expand the tree)
I'm guessing this is really simple, I'm just inexperienced with Redis.
MONITOR is a debugging command that streams back every command processed by the Redis server. It can help in understanding what is happening to the database. This command can both be used via redis-cli and via telnet.

Way to get INFO status for a redis cluster as a whole?

I've got a 6-node (3 primary, 3 secondary) cluster. I can get stats from individual nodes (e.g. instantaneous_ops_per_second) using INFO, and I can get some information on the cluster config using CLUSTER INFO.
Is there a way to get the stats from INFO, but for the whole cluster? Using the -c switch to connect in cluster mode doesn't seem to change the output, and googling isn't revealing anything that seems to be useful (though I'm getting plenty of tips on things to monitor in general at least...)
I'd prefer not to have to use an external program to combine the stats, though that's an obvious solution - I'm hoping for something that's built in to redis that'll let me look at, for example, the number of commands per second the whole cluster is processing.
This should do it:
redis-cli --cluster call <ip>:<port> INFO
Where <ip> and <port> are one of the cluster's nodes.

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.

Redis not blocking when running slow commands

We're having a severe config/product bug on our installation. We've been experiencing concurrency related errors that we've been blaming to Jedis usage, but it seems that it might be a product / config issue.
This is a single redis installation with over 4M keys. Whenever we run a long running command from redis-cli, like a keys *, our client code (Jedis based) starts to throw errors, like trying to cast a string into a binary (typical concurrency errors in Jedis conf). The worst scenario is that sometimes it seems that it returns wrong keys. We were using a Jedis instance in each actor instance, so it shouldn't be an issue but we changed to JedisPool nevertheless. But the problem remained (we are using Jedis 2.6.2).
But the main thing was when trying from different redis-cli. We run KEYS * that stays a long time running and then a GET command which returned. It was our understanding that the KEYS * should block everyone, but the GET command keeps working. This also happens with a SLEEP command.
Is this related to a config setting or this is something that shouldn't happen, or the KEYS command isn't blocking and my problem lies elsewhere?
Redis.io documentation for KEYS clearly states that KEYS is a debug command and should not be used in production:
Warning: consider KEYS as a command that should only be used in
production environments with extreme care. It may ruin performance
when it is executed against large databases. This command is intended
for debugging and special operations, such as changing your keyspace
layout. Don't use KEYS in your regular application code. If you're
looking for a way to find keys in a subset of your keyspace, consider
using SCAN or sets.

Redis SLAVEOF for single database

I'm hoping to run a SLAVEOF command from a new redis box to migrate data from an Elasticache node to a normal EC2 box running redis. Ideally I would run something like SLAVEOF IP DB_INDEX so that I'm only pulling data from DB_INDEX on the master instead of all available databases. Is this possible?
No, you can not replicate just a single "database" in Redis. It is easier to think of these as "keyspaces" rather than individual databases. Further, according to the documentation at Elasticache the way to import data is to upload a snapshot (RDB file) - not via a replication command.
Since you are just doing a migration you could:
Replicate to a clean instance
Iterate over all databases you don't want and do a FLUSHDB (do NOT do a FLUSHALL).
Then, if you want the data to be on DB0 and it is not there, you can use the MOVE command on each key to put it in the default 0 database.
This would result in having your new instance having just the data you want there, in the "0" database - if you chose to move the keys.