My redis cluster is borked. One node seems to think it's a 3-node cluster with no replication, another node seems to think it's alone, and the third node agrees with the first. I want to have a 3-node cluster with 2 replicated nodes (no splitting).
I don't want to have to figure out how to un-bork my redis cluster, instead: I want to start over.
The existing question How do I delete everything in Redis? doesn't include clusters, for which everything is way more complicated.
Desired result: Clean installation. No cluster config.
Unfortunately simply reinstalling the whole program appears insufficient. How do I tell it to really --yes-I-am-really-sure forget everything about itself and all the other nodes it knows? In particular:
Remove all non-config-file-cluster-configuration.
The command CLUSTER FORGET gets me partway there, but nodes can't forget themselves? Why not? Anyway, somehow convincing them to do that might be enough.
The difficult part is in realizing these three things:
There's both redis-cli CLUSTER and redis-cli --cluster, and the cluster commands are randomly divided between the two.
When usingredis-cli --cluster for something involving two nodes, the -a password parameter must be provided twice, both before and after the --cluster part. The one provided after is for the target node, the one provided before is for the 'config' node.
Commands using redis CLUSTER only apply to one node, so must be repeated for each node. (They cannot access the other nodes)
Knowing this, we can proceed wiping the necessary things:
redis-cli -h host01 -a password CLUSTER NODES
prints a list of nodes with long identifiers. Proceed with
# forget about the other nodes in the cluster on each node
redis-cli -h host01 -a password1 CLUSTER FORGET <host02 key>
redis-cli -h host01 -a password1 CLUSTER FORGET <host03 key>
redis-cli -h host02 -a password2 CLUSTER FORGET <host01 key>
redis-cli -h host02 -a password2 CLUSTER FORGET <host03 key>
redis-cli -h host03 -a password3 CLUSTER FORGET <host01 key>
redis-cli -h host03 -a password3 CLUSTER FORGET <host02 key>
# flush all data so that the node can be reset
redis-cli -h host01 -a password1 FLUSHALL
redis-cli -h host02 -a password2 FLUSHALL
redis-cli -h host03 -a password3 FLUSHALL
# reset the node
redis-cli -h host01 -a password1 CLUSTER RESET
redis-cli -h host02 -a password2 CLUSTER RESET
redis-cli -h host03 -a password3 CLUSTER RESET
Related
We have a Redis cluster (3 master, 3 slave) and are seeing a large number of keys on one of the master nodes (and related slaves) which appear to be empty and cannot be deleted.
If I connect to the master node which has a large number of entries (as determined by DBSIZE), I can SCAN for and see the keys:
--> redis-cli -h 192.168.100.81 -p 6381
192.168.100.81:6381> scan 0 match mykey-* count 10
1) "2359296"
2) 1) "mykey-1be333a7"
2) "mykey-e85a9d31"
3) "mykey-d9162eff"
4) "mykey-41d12fd8"
5) "mykey-a6e755d3"
6) "mykey-c2aa1eaa"
7) "mykey-c0597cac"
8) "mykey-10e69376"
9) "mykey-7263aef0"
10) "mykey-7fa9de50"
However, if I try and GET the value of a key, it shows it has moved:
192.168.100.81:6381> get mykey-1be333a7
(error) MOVED 8301 192.168.3.107:6380
If I connect to the node to which the key has moved, I am not able to GET or DEL the value:
--> redis-cli -h 192.168.3.107 -p 6380
192.168.3.107:6380> get mykey-1be333a7
(nil)
192.168.3.107:6380> del mykey-1be333a7
(integer) 0
I am also unable to GET or DEL the value using the cluster (-c) flag for redis-cli:
--> redis-cli -h 192.168.100.81 -p 6381 -c get mykey-1be333a7
(nil)
--> redis-cli -h 192.168.100.81 -p 6381 -c del mykey-1be333a7
(integer) 0
--> redis-cli -h 192.168.3.107 -p 6380 -c get mykey-1be333a7
(nil)
--> redis-cli -h 192.168.3.107 -p 6380 -c del mykey-1be333a7
(integer) 0
What can I do to remove these types of keys?
Interesting question!
How to reproduce the problem
The following is a scenario that will reproduce your problem:
You create a standalone Redis instance, and set some data into it. However, one day, you configure this standalone Redis as a member of a Redis Cluster, without flushing the old data or moving the old data to the right node of the cluster. Let's call these data as dirty data.
In this scenario, you can SCAN all keys on this instance, including the dirty data. However, you cannot read or write these dirty data, since your Redis is in cluster mode, it will redirect your request to the right node, which doesn't have such data.
How to solve the problem
In order to remove these dirty data, you should reconfigure your Redis instance into standalone mode, i.e. cluster-enabled no, and delete dirty data in standalone mode.
Then you can make it join the cluster again.
When I scan the Redis using below command:
redis-cli -h <redis_master_ip> -p 6379 --scan --pattern '*'
it returns keys which belong to this node, but it also returns many keys which belong to another redis node. Therefore if I run below command:
redis-cli -h <redis_master_ip> -p 6379 object freq <some_keys_from_scan>
I get error like Error: MOVED 90 <another_redis_master_ip>:6379
Due to the same reason, I get the same error when running:
redis-cli -h <redis_master_ip> -p 6379 --hotkeys
Note both the <redis_master_ip> and <another_redis_master_ip> are a part of redis cluster.
The document https://redis.io/commands/scan defines scan as: "iterates the set of keys in the currently selected Redis database". My understanding is it should only scan the keys belong to the current node. my redis cluster is 6.0.10.
Does anybody know why executing scan return the keys of another node? I am only interested in getting the keys of this node.
I see another link mentioned the same issue but no solution yet: https://github.com/redis/redis/issues/4810
I have URL and PORT of remote Redis server. I am able to write into Redis from Scala. However I want to connect to remote Redis via terminal using redis-server or something similar in order to make several call of hget, get, etc. (I can do it with my locally installed Redis without any problem).
redis-cli -h XXX.XXX.XXX.XXX -p YYYY
xxx.xxx.xxx.xxx is the IP address and yyyy is the port
EXAMPLE from my dev environment
redis-cli -h 10.144.62.3 -p 30000
REDIS CLI COMMANDS
Host, port, password and database By default redis-cli connects to the
server at 127.0.0.1 port 6379. As you can guess, you can easily change
this using command line options. To specify a different host name or
an IP address, use -h. In order to set a different port, use -p.
redis-cli -h redis15.localnet.org -p 6390 ping
There are two ways to connect remote redis server using redis-cli:
1. Using host & port individually as options in command
redis-cli -h host -p port
If your instance is password protected
redis-cli -h host -p port -a password
e.g. if my-web.cache.amazonaws.com is the host url and 6379 is the port
Then this will be the command:
redis-cli -h my-web.cache.amazonaws.com -p 6379
if 92.101.91.8 is the host IP address and 6379 is the port:
redis-cli -h 92.101.91.8 -p 6379
command if the instance is protected with password pass123:
redis-cli -h my-web.cache.amazonaws.com -p 6379 -a pass123
2. Using single uri option in command
redis-cli -u redis://password#host:port
command in a single uri form with username & password
redis-cli -u redis://username:password#host:port
e.g. for the same above host - port configuration command would be
redis-cli -u redis://pass123#my-web.cache.amazonaws.com:6379
command if username is also provided user123
redis-cli -u redis://user123:pass123#my-web.cache.amazonaws.com:6379
This detailed answer was for those who wants to check all options.
For more information check documentation: Redis command line usage
In Case of password also we need to pass one more parameter
redis-cli -h host -p port -a password
One thing that confused me a little bit with this command is that if redis-cli fails to connect using the passed connection string it will still put you in the redis-cli shell, i.e:
redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected>
You'll then need to exit to get yourself out of the shell. I wasn't paying much attention here and kept passing in new redis-cli commands wondering why the command wasn't using my passed connection string.
if you got Error: Server closed the connection
try with --tls switch:
redis-cli --tls -h my-redis.redis.cache.windows.net -p 6379 -a myRedisPassword
h 👉 hostname
p 👉 port
a 👉 password
I have a health check I'm trying to use that executes the redis-cli command from the redis servers to the redis-sentinels remotely.
redis-cli -h 10.10.10.10 -p 26379 SENTINEL MASTER testing
There is a logic that sorts out whether there is a quorum and it all works fine unless a sentinel's network interface is unavailable. The redis-cli command hangs indefinitely in this case and the health check fails even though there are two healthy sentinels with a quorum.
I can't seem to find a way to set a timeout for the redis-cli on the client side to prevent it from hanging. Is there a way with redis-cli to do this or will I have to go outside the command to ensure it doesn't hang indefinitely?
I decided to use the timeout command to wrap the redis-cli command. It seems to work very well for my purposes!
timeout 3 redis-cli -h 10.10.10.10 -p 26379 SENTINEL MASTER testing
How to delete keys matching a certain pattern in redis using redis-cli. I would like to delete all foo's from the following list.
KEYS *
foo:1
foo:2
bar:1
foo:3
bar:2
foo:4
As mentioned in the comment on the question, there are many other answers to this here already. Definitely read the one linked above if you are thinking about doing this in a production sever.
The one I found most useful for occasional command-line cleanup was:
redis-cli KEYS "*" | xargs redis-cli DEL
from "How to atomically delete keys matching a pattern using Redis".
I wanted to delete thousands of keys by pattern after some searches I found these points:
if you have more than one db on redis you should determine the database using -n [number]
if you have a few keys use del but if there are thousands or millions of keys it's better to use unlink because unlink is non-blocking while del is blocking, for more information visit this page unlink vs del
also keys are like del and is blocking
so I used this code to delete keys by pattern:
redis-cli -n 2 --scan --pattern '[your pattern]' | xargs redis-cli -n 2 unlink
I just published a command line interface utility to npm and github that allows you to delete keys that match a given pattern (even *) from a Redis database.
You can find the utility here:
https://www.npmjs.com/package/redis-utils-cli
If someone want to do same operation in AWS Elasticache redis, then you can connect with SSH to your EC2 server which is supposed to access AWS Redis server then you can use below command.
redis-cli -h <HOST> -p <PORT> --scan --pattern "patter*n" | xargs redis-cli -h <HOST> -p <PORT> unlink
Replace Host and port with AWS redis server host and port.
Also if your redis setup needs password authentication then use,
redis-cli -h <HOST> -p <PORT> -a <PASSWORD> --scan --pattern "patter*n" | xargs redis-cli -h <HOST> -p <PORT> -a <PASSWORD> unlink
Replace Host, port and password with AWS redis server host, port and password.
You can also use above commands for localhost.