34 Practical Investigation of Slow Queries in Redis

34 Practical Investigation of Slow Queries in Redis #

The purpose of Redis slow queries is similar to that of MySQL slow queries. They help us identify and avoid inefficient commands, enabling developers and operations personnel to improve the efficiency and health of the server. For Redis, which is single-threaded, improper usage is particularly detrimental, so mastering the skill of Redis slow queries is crucial for us.

How to Perform Slow Queries? #

Before we begin, let’s first understand the Redis configuration options related to slow queries. The important configuration options for Redis slow queries are as follows:

  • slowlog-log-slower-than: This option is used to set the threshold for slow queries, i.e., any command that exceeds this threshold will be recorded in the slow query log as a slow operation. The unit is microseconds (1 second equals 1,000,000 microseconds).
  • slowlog-max-len: This option is used to configure the maximum number of records in the slow query log.

Let’s take a look at their default values:

127.0.0.1:6379> config get slowlog-log-slower-than # Slow query threshold
1) "slowlog-log-slower-than"
2) "10000"
127.0.0.1:6379> config get slowlog-max-len # Maximum number of slow query records
1) "slowlog-max-len"
2) "128"

As we can see, the threshold for slow queries is set to 10,000 microseconds by default, and up to 128 slow query records are saved.

Modifying Configuration Options #

We can modify slowlog-log-slower-than and slowlog-max-len using the config set xxx format. For example, we can set the maximum number of slow query records to 200 by executing the following command:

127.0.0.1:6379> config set slowlog-max-len 200
OK

Slow Query Demonstration #

Let’s first set the threshold for slow queries to 0 microseconds so that all commands executed will be recorded. Execute the following command to set the threshold:

127.0.0.1:6379> config set slowlog-log-slower-than 0
OK

Next, let’s execute two insertion commands:

127.0.0.1:6379> set msg xiaoming
OK
127.0.0.1:6379> set lang java
OK

Finally, we can use slowlog show to query the slow query log. The result is as follows:

127.0.0.1:6379> slowlog get # Query slow logs
1) 1) (integer) 2 # Slow log index
   2) (integer) 1581994139 # Execution time
   3) (integer) 5 # Execution time (in microseconds)
   4) 1) "set" # Executed command
      2) "lang"
      3) "java"
   5) "127.0.0.1:47068"
   6) ""
2) 1) (integer) 1
   2) (integer) 1581994131
   3) (integer) 6
   4) 1) "set"
      2) "msg"
      3) "xiaoming"
   5) "127.0.0.1:47068"
   6) ""
3) 1) (integer) 0
   2) (integer) 1581994093
   3) (integer) 5
   4) 1) "config"
      2) "set"
      3) "slowlog-log-slower-than"
      4) "0"
   5) "127.0.0.1:47068"
   6) ""

Including the set commands themselves, there are a total of three “slow operation” records stored in the slow query log in reverse chronological order of insertion.

Tip: When the slow query log exceeds the maximum number of records set, the earliest executed commands will be discarded in sequence.

Querying a Specific Number of Slow Logs #

Syntax: slowlog get n.

127.0.0.1:6379> slowlog get 2 # Query two logs
1) 1) (integer) 20
   2) (integer) 1581997567
   3) (integer) 14
   4) 1) "slowlog"
      2) "get"
      3) "4"
   5) "127.0.0.1:47068"
   6) ""
2) 1) (integer) 19
   2) (integer) 1581997544
   ...
   3) (integer) 11
   4) 1) "slowlog"
      2) "get"
      3) "3"
   5) "127.0.0.1:47068"
   6) ""
127.0.0.1:6379> slowlog get 3 # Get three records
1) 1) (integer) 22
   2) (integer) 1581997649
   3) (integer) 25
   4) 1) "set"
      2) "msg"
      3) "hi"
   5) "127.0.0.1:47068"
   6) ""
2) 1) (integer) 21
   2) (integer) 1581997613
   3) (integer) 9
   4) 1) "slowlog"
      2) "get"
      3) "2"
   5) "127.0.0.1:47068"
   6) ""
3) 1) (integer) 20
   2) (integer) 1581997567
   3) (integer) 14
   4) 1) "slowlog"
      2) "get"
      3) "4"
   5) "127.0.0.1:47068"
   6) ""

Get the length of slow query queue #

Syntax: slowlog len.

127.0.0.1:6379> slowlog len
(integer) 16

Clear slow query logs #

Use slowlog reset to clear all slow query logs. Execute the command as follows:

127.0.0.1:6379> slowlog reset
OK

Code example #

In this article, we will use Java to implement slow query log operations. The code is as follows:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.util.Slowlog;
import utils.JedisUtils;

import java.util.List;

/**
 * Slow query
 */
public class SlowExample {
    public static void main(String[] args) {
        Jedis jedis = JedisUtils.getJedis();
        // Insert slow queries (as slowlog-log-slower-than is set to 0, all commands are considered slow operations)
        jedis.set("db", "java");
        jedis.set("lang", "java");
        // Length of slow query log
        long logLen = jedis.slowlogLen();
        // All slow queries
        List<Slowlog> list = jedis.slowlogGet();
        // Print in a loop
        for (Slowlog item : list) {
            System.out.println("Slow query command: " + item.getArgs() +
                    " Execution time: " + item.getExecutionTime() + " microseconds");
        }
        // Clear slow query logs
        jedis.slowlogReset();
    }
}

The output of the above code execution is as follows:

Slow query command: [SLOWLOG, len] Execution time: 1 microseconds
Slow query command: [SET, lang, java] Execution time: 2 microseconds
Slow query command: [SET, db, java] Execution time: 4 microseconds

Slow query command: [SLOWLOG, reset] Execution time: 155 microseconds

Summary #

In this article, we introduced two important parameters related to slow queries: slowlog-log-slower-than (used to set the threshold for determining slow queries) and slowlog-max-len (used to configure the maximum number of slow query log records). Then, by modifying config set slowlog-log-slower-than 0, we recorded all operations in the slow query log for testing purposes. We can use slowlog get [n] to query the slow query log and use slowlog reset to clear the slow query log. Finally, we recommend that you regularly check the slow query log to identify and improve any inefficient operations in Redis.