“This is the 22nd day of my participation in the First Challenge 2022. For details: First Challenge 2022.”

Redis has always been a representative of high performance distributed cache middleware, we often say that Redis is single-threaded, also some people say that Redis in version 6.0 using multi-threading, so Redis is using single-threaded? Multithreading? In this article we find out.

1 introduction

Is Redis single-threaded or multi-threaded?

First, Redis is a high-performance distributed cache middleware. The complexity is self-evident, and Redis as a whole is certainly not a single thread.

We often say that Redis is single-threaded, which mainly means that Redis adopts a thread to complete IO and key-value pair reading and writing in the network, which is also the core process of Redis to provide key-value storage service externally. However, other Redis functions, such as persistence, asynchronous deletion, and cluster data synchronization, are actually performed by additional threads.

Why multithreading?

Advantages of single threading:

  • Using a single thread avoids frequent context switches
  • There are various types of data operations in Redis, including some transaction processing. If multi-threading is adopted, software complexity may be improved due to locking, and performance loss may be caused by unlocking or even deadlock. Therefore, using single thread will have better performance

Disadvantages of single threading:

  • Unable to take advantage of multi-core CPUS
  • Services are blocked when large builds are deleted
  • QPS reached a bottleneck

Redis has also been optimized to introduce Lazy Free and multithreaded IO in version 4.0 and 6.0, respectively.

3 Redis single-threaded model

Redis developed the network event handler based on the Reactor pattern, which is called the file event handler.

There are four important components of a file event handler:

  • Multiple socket requests
  • IO multiplexer
  • File event dispatcher
  • Event handler

Every call of Redis client to server has experienced three processes: sending command, executing command and returning result. In the command execution stage, because Redis is a single thread to process commands, every command that reaches the server will not be executed immediately. All commands will enter a queue and then be executed one by one. And the order of execution of commands sent by multiple clients is uncertain. However, you can be sure that no two commands will be executed at the same time and no concurrency problems will occur. This is the basic single-threaded model of Redis, as shown in the figure below.

Guide you to understand the Redis process

4.1 Event processing process prior to Redis 4.0

We first introduce the implementation principle of Redis (before 4.0). We listen the socket network connection from the client through IO multiplexer, and then process the IO request and command by the main thread. All operations are linear, we can understand abstractly as the following figure.

4.2 Redis 4.0 introduced Lazy Free

Prior to Redis 4.0, client commands and IO operations were handled in a single thread and no other client requests were responded. However, if the client sent a long command to Redis, such as deleting a Set key containing millions of objects, or executing the flushdb, flushall operation, The Redis server needs to reclaim a large amount of memory, which can cause the Redis service to block, which can be a disaster for a heavily loaded cache system. In order to solve this problem, Redis 4.0 introduced Lazy Free to asynchronize slow operations. This is also a step towards multi-threading in event processing. The process can be seen in the following figure.

4.3 Network IO asynchronization after Redis 6.0

Even single-threaded Redis can respond very quickly, except for a few extremely time-consuming commands. This has been optimized in version 4.0, but can we further optimize Redis? As you can see from the figure above, the main thread not only processes a large number of commands, but also needs to process a large number of network IO. Redis6.0 is based on this, and the IO operation is handed over to other threads.

Multithreading in Redis6.0 is disabled by default and only the main thread is used. To enable this function, modify the redis.conf configuration file: io-threads-do-reads yes

After enabling multi-threading, you also need to set the number of threads, otherwise it will not take effect.

The number of threads must be less than the number of machine cores. The number of threads is not always better, and the official view is that more than eight threads is almost meaningless.

To set the number of threads, modify the redis.conf configuration file: io-threads 6