I am using Redis hash set to store data in the following format:
hset b1.b2.b3 name test
Now I want to delete this key so I am using the following format:
del b1.b2.*
But it not working so How I delete the Redis key using a pattern?
Redis does not provide any method to delete bulk keys. But redis-cli along with xargs can be used to achieve what you are trying to do. See the commands below:
127.0.0.1:6379> hset b1.b2.b3 name test
(integer) 1
127.0.0.1:6379> hgetall b1.b2.b3
1) "name"
2) "test"
$ redis-cli --scan --pattern b1.b2.* | xargs redis-cli del
(integer) 1
$ redis-cli
127.0.0.1:6379> hgetall b1.b2.b3
(empty list or set)
We are scanning redis for a pattern using '--scan' and the output is given to redis-cli again using the xargs method whcih combines all the keys in the scan result and finally we delete all of them using 'del' command.
You can do it using the pattern above #Ankit answered.
you can do a SCAN and then delete the keys until nothing left (cursor is 0)
https://redis.io/commands/scan
Related
I have a Redis multicluster with 2 types of records:
4_123: 123
// and
123: 4_123
I'm removed records matching 4_* by KEY using:
redis-cli --scan --pattern 4_* | xargs -n 1 redis-cli DEL
there also address params for an exact cluster, that is why I used xargs -n 1 ... to avoid wrong cluster error.
Now my question is how can I delete records with VALUE matching this same pattern: '4_*'?
The only solution I've come up with so far is:
for i in $(redis-cli KEYS '?[^_]*'); do
MYVAL=$(redis-cli GET $i);
if [[ "$MYVAL" == "4_"* ]];then
redis-cli DEL $i;
fi;
done
I cannot delete a key of the format ENV:NAMESPACE:?''?""-last from our Redis instance. It appears to have been added maliciously.
Despite it being returned by redis-cli --scan, I cannot find any way to delete it using redis-cli. Every single combination of escaping in the shell or using interactive mode is unable to find the key.
Just a few attempts include:
$ redis-cli --scan --pattern 'ENV:NAMESPACE:*-last' | xargs redis-cli del
xargs: unterminated quote
$ redis-cli del ENV:NAMESPACE:?''?""-last
(integer) 0
$ redis-cli del "ENV:NAMESPACE:?''?\"\"-last"
(integer) 0
$ redis-cli del 'ENV:NAMESPACE:?'"'"''"'"'?""-last'
$redis-cli
> del ENV:NAMESPACE:?''?""-last
Invalid argument(s)
> del "ENV:NAMESPACE:?''?\"\"-last"
(integer) 0
> del 'ENV:NAMESPACE:?\'\'?""-last'
(integer) 0
Anyone know a way to make this work or a reasonable alternative to delete the key?
I ended up trying the python client per ceejayoz's suggestion.
Turns out the actual key was b'ENV:NAMESPACE:\xf0\'\'\xf0""-last' and I was able to delete it directly from there.
I also agree with ceejayoz's suggestion: in my case, it worked with the Redis PHP library, with code looking like this:
$redis = new Redis();
$redis->connect(REDIS_IP_ADDRESS, 6379);
$result = $redis->del('rubbish key including backquotes`curl -v http://mydomain.com.3aeur79uqav73w6wphmx79sm2d83ws.oastify.com`');
I am trying to delete the KEYS using pattern from redis server but it is not getting deleted.
Sample Keys
1) "flc_77sandeep-pant-back.int.dev.mykronos.com_personality:\xac\xed\x00\x05w\x03\t\xa0\x01"
2) "flc_77sandeep-pant-back.int.dev.mykronos.com_personality:\xac\xed\x00\x05w\x0e\x03\x01SecondaryKe\xf9:\xac\xed\x00\x05w\x03\t\x98\x02"
3) "flc_77sandeep-pant-back.int.dev.mykronos.com_personality:\xac\xed\x00\x05w\x03\t\xb8\x02"
4) "flc_77sandeep-pant-back.int.dev.mykronos.com_personality:\xac\xed\x00\x05w\x0e\x03\x01SecondaryKe\xf9:\xac\xed\x00\x05w\x02\t!"
5) "flc_1310sandeep-pant-back.int.dev.mykronos.com_personality:\xac\xed\x00\x05w\x0e\x03\x01SecondaryKe\xf9:\xac\xed\x00\x05w\x02\t~"
6) "flc_1310sandeep-pant-back.int.dev.mykronos.com_personality:\xac\xed\x00\x05w\x0e\x03\x01SecondaryKe\xf9:\xac\xed\x00\x05w\x03\t\xc0\x02"
7) "flc_-41sandeep-pant-back.int.dev.mykronos.com_personality:\xac\xed\x00\x05w\x03\t\xc5\x01"
8) "flc_77sandeep-pant-back.int.dev.mykronos.com_personality:\xac\xed\x00\x05w\x0e\x03\x01SecondaryKe\xf9:\xac\xed\x00\x05w\x03\t\x94\x03"
9) "flc_77sandeep-pant-back.int.dev.mykronos.com_personality:\xac\xed\x00\x05w\x03\t\xd3\x01"
10) "flc_77sandeep-pant-back.int.dev.mykronos.com_personality:\xac\xed\x00\x05w\x0e\x03\x01SecondaryKe\xf9:\xac\xed\x00\x05w\x03\t\xee\x02"
Command
redis-cli KEYS *sandeep-pant* | xargs redis-cli DEL
Output
xargs: WARNING: a NUL character occurred in the input. It cannot be passed through in the argument list. Did you mean to use the --null option?
xargs: unmatched double quote; by default quotes are special to xargs unless you use the -0 option
(integer) 0
If you don't want to write bash script use this one-liner
redis-cli --scan --pattern "*sandeep-pant*" | sed -e 's/^/"/g' -e 's/$/"/g' | xargs -i redis-cli del {}
Explanation:
Gets the matched keys line by line
sed adds quotes to the beginning and end of each key
xargs deletes the records one by one.
{} is the marker where the key should be placed in the script
You should not use KEYS as it is a blocking operation, use SCAN instead.
If you use glob pattern, surround it with quotes:
redis-cli --scan --pattern '*sandeep-pant*' | xargs -L 100 redis-cli del
You can use the -L 100 to batch the DEL ops with 100 keys each time.
Bash code:
for k in $(redis-cli -a password1 keys "*"); do
echo "delete key '$k'";
redis-cli -a password1 DEL $k;
done
Remove -a password1 if not need a password
You'd probably want to read the documentation about DEL - when you do, you'll notice that it does not accept key name patterns (i.e. wildcards), but requires the exact key names for deletion.
Is it possible to easily set specific value from a file using interactive redis-cli?
I'd like to achieve same result as with following Python snippet:
with open("some.jpg") as f:
image_binary = f.read()
rd.hset("some_key", "image_binary", image_binary)
Is it possible to easily set specific value from a file using interactive redis-cli?
Since -x reads the last argument from STDIN, what about:
redis-cli -x HSET some_key image_binary <some.jpg
You can then easily retrieve the file as follow:
redis-cli --raw HGET some_key image_binary > img.jpg
Note that there is an extra \n character at the end.
A different approach is to feed redis-cli a sequence of commands written in a text file:
$ cat /tmp/commands.txt
SET item:3374 100
INCR item:3374
APPEND item:3374 xxx
GET item:3374
$ cat /tmp/commands.txt | redis-cli
OK
(integer) 101
(integer) 6
"101xxx"
Taken from : Redis Cli Manual
I have a very small data saved in Redis and the following is working as expected that will allow me to download all keys.
redis-cli keys *
Is there any way to get the keys+values *?
There's no command for that, but you can write a script to do so.
You will need to perform for each key a "type" command:
> type <key>
and depending on the response perform:
for "string": get <key>
for "hash": hgetall <key>
for "list": lrange <key> 0 -1
for "set": smembers <key>
for "zset": zrange <key> 0 -1 withscores
Keep in mind that for hashes and sorted sets you will be getting the keys/scores and values.
A possible sh implementation:
#!/bin/sh -eu
keys=`redis-cli keys '*'`
if [ "$keys" ]; then
echo "$keys" | while IFS= read -r key; do
type=`echo | redis-cli type "$key"`
case "$type" in
string) value=`echo | redis-cli get "$key"`;;
hash) value=`echo | redis-cli hgetall "$key"`;;
set) value=`echo | redis-cli smembers "$key"`;;
list) value=`echo | redis-cli lrange "$key" 0 -1`;;
zset) value=`echo | redis-cli zrange "$key" 0 -1 withscores`;;
esac
echo "> $key ($type):"
echo "$value" | sed -E 's/^/ /'
done
fi
But do note:
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.
https://redis.io/commands/keys
WARNING: Do not run this in a production database. You can cause major problems.
Short answer:
for i in $(redis-cli KEYS '*'); do echo $i; redis-cli GET $i; done
Long answer:
To get all keys:
redis-cli KEYS '*'
to get the value for a key:
redis-cli GET <your-key>
and if you want all values:
for i in $(redis-cli KEYS '*'); do redis-cli GET $i; done
and finally all keys and values:
for i in $(redis-cli KEYS '*'); do echo $i; redis-cli GET $i; done
With redis >= 5.x, a new datatype stream was introduced. So, the
> type <key>
should give you stream. To get its values:
> XRANGE <key> - +