Debugging

Lets see what are the ways to find out what is happening inside Redis.

Monitoring commands

When we need to see what is Redis doing, we can connect to it and monitorarrow-up-right all the commands that are executed.

$ redis-cli -h myservice.redis.mycompany.com monitor
1515185542.880199 [0 1.1.1.1:34578] "hget" "somekey" "-1566720763"
1515185548.931294 [0 1.1.1.1:47306] "exists" "anotherkey"

Then we receive all the commands and we can figure out what is wrong.

Then we can dump the redis logs into a file and do a little analyzes.

$ redis-cli -h myservice.redis.mycompany.com monitor > redis-logs.txt

Lets create very simple and stupid script that will give us an idea what is happening in redis. Like how many commands were executed.

import java.text.DateFormat
import java.text.SimpleDateFormat
import java.time.Duration

println "Starting..."

File file = new File("/Users/ondrej/Documents/redis-logs.txt")
println "File exits: ${file.exists()}"

boolean firstLineRead = true
String firstLine
String lastLine

int lineCount = 0
Map<String, Integer> aggregator = [:]
file.eachLine { String it ->
    if (it.contains(']')) {
        if (firstLineRead) {
            String[] split = it.split('\\[')
            firstLine = split[0]
            firstLineRead = false
        }
        String[] split = it.split(']')
        String raw = split[1].trim().replaceAll('"', '')
        String[] commands = raw.split(' ')
        String command = commands[0]
        if (aggregator.containsKey(command)) {
            Integer value = aggregator.get(command)
            aggregator.put(command, value + 1)
        } else {
            aggregator.put(command, 1)
        }
        lineCount++
    }
}

DateFormat df = new SimpleDateFormat("ss.SSSSSSS")

int lastLineCounter = 0
file.eachLine { String it ->
    if (it.contains('[')) {
        if (it.contains('keys')) { // there are too many keys called, lets debug and see more about those
            String[] split = it.split('\\[')
            String date = split[0]
            println df.parse(date).toString() + ' ' + it
        }
        if (lineCount - 1 == lastLineCounter) {
            String[] split = it.split('\\[')
            lastLine = split[0]
        }
        lastLineCounter++
    }
}

println 'Line Count: ' + lineCount
println 'Duration: ' + Duration.between(df.parse(firstLine).toInstant(), df.parse(lastLine).toInstant())
println 'From: ' + df.parse(firstLine).toInstant()
println 'To: ' + df.parse(lastLine).toInstant()
println 'Aggregated: ' + aggregator

When we run the script we find that there are too many keys command calls, that can be causing performance issues.

Status of Redis

We can find out a lot by running infoarrow-up-right command. Things like, how much memory is used or how many clients are connected.

How many keys is there

dbsizearrow-up-right is used to get how many keys our Redis has.

Find slow commands

We can find commands that are slow. The slowlogarrow-up-right is aggregated in memory and then returned to client.

The most exciting number is 3) (integer) 29747, which says number milliseconds the command took to execute. 1) is ID and 2) is timestamp.

We can see that we got problem with using keysarrow-up-right command too much. There is a warning that keys command shouldn't be used with care in production.

Latency

We can measure latency of a Redis instance.

Last updated