How to parse redis slowlog - redis

I try to parse redis slowlog to a files with csv format (comma, column or space as delimiter), but I am not sure how to do that.
If I run redis-cli -h <ip> -p 6379 slowlog get 2, I get below output:
1) 1) (integer) 472141
2) (integer) 1625198930
3) (integer) 11243
4) 1) "ZADD"
2) "key111111"
3) "16251.8488247"
4) "abcd"
5) "1.2.3.4:89"
6) ""
2) 1) (integer) 37214
2) (integer) 1525198930
3) (integer) 1024
4) 1) "ZADD"
2) "key2"
3) "1625.8"
5) "1.2.3.4:89"
6) "client-name"
Note the item 4) of each log entry may contain different numbers of arguments, e.g. 4) of log entry 1) has 4 arguments, while 4) of log entry 2) has 3 arguments; and the item 6) can be a string like client-name or can be empty.
If I run the command using below shell script:
results=$(redis-cli -h <ip> -p $port slowlog get 2)
echo $results
I get below output:
472141 1625198930 11243 ZADD key111111 16251.8488247 abcd 1.2.3.4:89 37214 1525198930 1024 ZADD key2 1625.8 1.2.3.4:89 client-name
As you see, the output of the command becomes lots of words. Besides, it is hard to figure out which group of words belong to the same log entry. what I want is to get a csv file like:
472141 1625198930 11243 ZADD key111111 16251.8488247 abcd 1.2.3.4:89
37214 1525198930 1024 ZADD key2 1625.8 1.2.3.4:89 client-name
Is there anyway I can parse the redis slowlog to a cvs file as I want? any script like python, shell is welcomed. and any existing code is welcomed.

Related

Redis increment keyN or key:N

in Redis, increment value can be stored or we can increment value of keys. Like
127.0.0.1:6379> set _inc 0
OK
127.0.0.1:6379> INCR _inc
(integer) 1
127.0.0.1:6379> INCR _inc
(integer) 2
127.0.0.1:6379> get _inc
"2"
or we can save items like
item:UNIQUE-ID
item:UNI-QUE-ID
But how to save items with increment N ID like:
item:1
item:2
item:3
item:4
...
So far I found a solution with LUA Script
127.0.0.1:6379> eval 'return redis.call("set", "item:" .. redis.call("incr","itemNCounter"), "item value")' 0
OK
...
127.0.0.1:6379> keys item:*
1) "item:10"
2) "item:14"
3) "item:13"
4) "item:6"
5) "item:15"
6) "item:9"
7) "item:4"
8) "item:1"
9) "item:5"
10) "item:3"
11) "item:12"
12) "item:7"
13) "item:8"
14) "item:11"
15) "item:2"
Question: Is there a method to make it without running Lua script or reliable method?
I expect that there would be a Redis command to make it.
Question: Is there a method to make it without running Lua script or reliable method?
No, there isn't. However, EVAL is supported since Redis version 2.6 and LUA scripts are first-class citizens in Redis.

Redis - Sort and filter hash store using string attribute

I have a redis hash store that looks like Item:<id>, with attribute name. I want to filter the hash store by a prefix for name attribute.
What I'm trying to do is store the name (lowercased) in a separate Z-set called Item:::name while setting the score to 0. By doing this, I'm successfully able to get the desired result using ZRANGEBYLEX however I'm unable to map the results back to the original Items. How should I go about implementing something like this?
I've seen multiple autocomplete examples for Redis which require the same functionality but without linking the words back to an actual Item (hash in this case)
In sorted sets the member can't be duplicated, it has to be unique. So different users with the same name will cause problem.
My suggestion requires application layer coding to parse response array and executing hash commands (it will be like secondary indexes);
127.0.0.1:6379> HSET user:1 name jack
(integer) 1
127.0.0.1:6379> HSET user:2 name john
(integer) 1
127.0.0.1:6379> HSET user:3 name keanu
(integer) 1
127.0.0.1:6379> HSET user:4 name jack
(integer) 1
127.0.0.1:6379> ZADD item:names 0 jack::user:1 0 john::user:2 0 keanu::user:3 0 jack::user:4
(integer) 4
127.0.0.1:6379> ZRANGE item:names 0 -1 WITHSCORES
1) "jack::user:1"
2) "0"
3) "jack::user:4"
4) "0"
5) "john::user:2"
6) "0"
7) "keanu::user:3"
8) "0"
127.0.0.1:6379> ZRANGEBYLEX item:names [jack [jo
1) "jack::user:1"
2) "jack::user:4"
At the end you will have name::hash-key formatted array elements. At application layer if you separate each element to two substrings by using ::(any other string such as !!! or || etc) you will have user:1 and user:4.
127.0.0.1:6379> HGETALL user:1
1) "name"
2) "jack"
127.0.0.1:6379> HGETALL user:4
1) "name"
2) "jack"
127.0.0.1:6379>

Redis CLUSTER NODES showing in slowlog

I am using a redis cluster with 3 master and 3 slave as mysql cache,and the client is redisson with #Cacheabel annotation.But I found some slow logs with the command CLUSTER NODES like:
3) 1) (integer) 4
2) (integer) 1573033128
3) (integer) 10955
4) 1) "CLUSTER"
2) "NODES"
5) "192.168.110.102:57172"
6) ""
4) 1) (integer) 3
2) (integer) 1573032928
3) (integer) 10120
4) 1) "CLUSTER"
2) "NODES"
5) "192.168.110.90:59456"
6) ""
So ,I want to know what was the problem?

Merge Redis set members values using a pattern

I have a simple zset named pets:
redis-cli zadd pets 1 cat1
redis-cli zadd pets 1 cat2
redis-cli zadd pets 1 cat3
redis-cli zadd pets 1 rat1
redis-cli zadd pets 1 rat2
The value is always 1. Now the set state is redis-cli zrange pets 0 -1 withscores:
1) "cat1"
2) "1"
3) "cat2"
4) "1"
5) "cat3"
6) "1"
7) "rat2"
8) "1"
9) "rat1"
10) "1"
Is there a way to merge set members based on a pattern? I want to sum all the members with the name starting with a prefix, in my case the pet type, so as to end up with the following:
1) "cat"
2) "3"
3) "rat"
4) "2"
I have tried zinterstore and zunionstore but they enforce having the same name for members of the sets.
Nope, there isn't a built-in Redis gimmick for that, but you could majik it with a Lua script (see the EVAL command).
That said, if what you need is count of pet by prefix, you should consider an alternative data model that can serve that.

How to decode values in Redis database?

I stored the geoset in redis database with GEOADD command as -
GEOADD city 13.361389 38.115556 'paris'
and able to get the stored values with following command -
127.0.0.1:6379> ZRANGE city 0 -1
but I am getting response as -
1) "1"
2) "3484047800163752"
3) "10"
4) "3484047800163752"
5) "2"
6) "3484047800163752"
Can anybody please help me to find out decoded values like 13.361389 38.115556
Thanks
Read the documentation, specifically that of the GEOPOS command:
redis> GEOPOS city 1 2 3