Redis delete batch keys strips slashes from key names - redis

In my MacOs 10.15 environment I have a strange Redis behaviour when I list some keys with:
redis-cli -n 1 --scan --pattern "product_doctrine*"
It gives me for example:
product_doctrine[AppBundle\Entity\ColumnMapping\$GEDMO_TIMESTAMPABLE_CLASSMETADATA][21546]
But It doesn’t delete it using xargs:
redis-cli -n 1 --scan --pattern "product_doctrine*" | xargs -L 1 redis-cli -n 1 del
(integer) 0
Is it maybe of the key name having special characters? Because if I run this inide the redis-cli:
SCAN 0 MATCH product_doctrine*
it shows the keys with escaped antislash:
"product_doctrine[AppBundle\\Entity\\ShopSettings\\$GEDMO_SOFTDELETEABLE_CLASSMETADATA][11677]"
Inside redis-cli I can delete those kind of keys successfully with
127.0.0.1:6379[1]> del "product_doctrine[AppBundle\\Entity\\ShopSettings\\$GEDMO_SOFTDELETEABLE_CLASSMETADATA][11677]"
(integer) 1

On macOS 10.14 the following does it:
redis-cli --scan --pattern "foo*" | sed 's/\\/\\\\/' | xargs -L 1 redis-cli DEL
¯\_(ツ)_/¯

Related

Get all keys in Redis cluster

I am using Redis cluster version redis-5.0.5. I want to see all the keys present in my Redis cluster. I know for standalone we use KEYS * to get all the keys.
what is the way to see all keys in Redis cluster?
$ redis-cli -h hostname -p 90001 -c
hostname:90001> KEYS *
(empty list or set)
// I have data on my cluster
Basically, you'd need to run KEYS * (not in production, please!) on every one of the nodes. The cli can do this with the '--cluster call' command, like so:
redis-cli --cluster call hostname:90001 KEYS "*"
Requirement:
redis-cli
awk
grep
xargs
May be can try this assuming redis server reside in localhost with the default port 6379:
redis-cli cluster nodes | awk '{print $2" "$3}' | grep master | awk -F # '{print $1}' | awk -F : '{print " -h "$1" -p "$2" --scan"}' | xargs -L 1 redis-cli -c
Longer version base question above (90001 port number seriously?) and also you can change the pattern (* no filter) for filtering certain key pattern:
redis-cli -h hostname -p 90001 cluster nodes | awk '{print $2" "$3}' | grep master | awk -F # '{print $1}' | awk -F : '{print " -h "$1" -p "$2" --scan --pattern *"}' | xargs -L 1 redis-cli -c
It connects to any one of the redis node to get cluster info and then execute the keys scanning command on each of the master node.
The SCAN command may be what you're looking for, but it's O(N) so the more keys you have, the slower it's going to be. Also, check out this answer by Marc Gravell for another approach using sets: Get values by key pattern in StackExchange.Redis

unable to delete keys with prefix from redis

How does one deletes keys with certain prefix from Redis 5+?
I've tried following, yet didn't work for me(
root#1acb94e11aa2:/data# redis-cli --version
redis-cli 5.0.4
root#1acb94e11aa2:/data# redis-cli -n 9 KEYS ISO:* | wc -l
935
root#1acb94e11aa2:/data# redis-cli -n 9 KEYS ISO:* | xargs -0 redis-cli -n 9 DEL
(integer) 0
root#1acb94e11aa2:/data# redis-cli -n 9 KEYS ISO:* | wc -l
935
root#1acb94e11aa2:/data# redis-cli -n 9 --scan --pattern ISO:* | xargs -0 redis-cli -n 9 unlink
(integer) 0
root#1acb94e11aa2:/data#
Please advise.
As long as your key names do not include spaces, you should be able to run this:
$ redis-cli -n 9 --scan --pattern "ISO:*" | xargs -n 1 redis-cli -n 9 UNLINK
EDIT: if they do include spaces, you can do:
$ redis-cli -n 9 --scan --pattern "ISO:*" | xargs -n 1 -d "\n" redis-cli -n 9 UNLINK
FIX:
root#1acb94e11aa2:/data# redis-cli -n 9 KEYS ISO:* | xargs -d "\n" redis-cli -n 9 del
(integer) 262
root#1acb94e11aa2:/data#
root#1acb94e11aa2:/data# redis-cli -n 9 KEYS ISO:*
(empty list or set)
root#1acb94e11aa2:/data#

xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option

I'm trying to use redis-cli w/ xargs to delete keys matching my pattern, yet getting following error:
root#543b9f09e6a8:/data# redis-cli -n 0 --scan --pattern ISO:* | xargs redis-cli -n 0 DEL
xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option
(integer) 0
root#543b9f09e6a8:/data#
Please advise.
Thanks in advance!

How to get value by redis-cli keys

I want get value by redis-cli keys
This is work
redis-cli keys number_* | xargs redis-cli del
But this is not work
redis-cli keys number_* | xargs redis-cli get
The difference between DEL and GET, in this context, is that the former is variadic (i.e. accepts one or more arguments) whereas the latter isn't (one and only one key name is expected).
To solve this you can choose one of the following:
Use the -L switch with xargs, i.e.: redis-cli keys number_* | xargs -L 1 redis-cli get
Use MGET, i.e.: redis-cli keys number_* | xargs redis-cli mget
Important warning: KEYS is a dangerous command as it may block the server for a long time - do not use it in production!

redis keys command delete data but scan command does not

redis-cli -s /data/redis/redis.sock --scan --pattern "*abcd|6128*" | xargs -L 100 redis-cli -s /data/redis/redis.sock DEL
above command is not deleting adta from redis and giving following output
(integer) 0
While the keys command works perfectly
redis-cli -s /data/redis/redis.sock KEYS 'abcd|6291*' | xargs redis-cli -s /data/redis/redis.sock DEL;
Is there is something wrong i am doing
Try xargs with -L 1 instead. Worked for me.
redis-cli -s /data/redis/redis.sock --scan --pattern "*abcd|6128*" | xargs -L 1 redis-cli -s /data/redis/redis.sock DEL
BTW, KEYS should be avoided in production environments as it is a blocking command.
scan only applies to some keys (by default on 10 keys per iteration). It returns an offset to continuesly run scan until you reach offset 0. Then you have sampled all keys. More details are in the documentation: http://redis.io/commands/scan
Keys on the other hand samples all keys in the db in one pass. It is also blocking due to redises single threaded architecture which might be bad for performance of other clients.