Home >Database >Redis >Is redis single-threaded or multi-threaded? Why?

Is redis single-threaded or multi-threaded? Why?

青灯夜游
青灯夜游Original
2020-12-18 15:08:2621103browse

Before Redis4.0, it ran in a single thread; after Redis4.0, it started to support multi-threading. The reasons why single-threading was used before Redis 4.0: 1. The single-threaded mode is convenient for development and debugging; 2. Redis uses epoll-based multiplexing internally; 3. The main performance bottleneck of Redis is memory or network bandwidth.

Is redis single-threaded or multi-threaded? Why?

(Learning video sharing: redis video tutorial)

Different versions of Redis are different, in Redis4. Before 0, Redis ran in a single thread, but single thread does not mean low efficiency. Nginx and Nodejs are also single-threaded programs, but their efficiency is not low.

The reason is that Redis is based on memory. Its bottleneck lies in the machine's memory and network bandwidth, not the CPU. Before the CPU reaches the bottleneck, the machine memory may be full, or the bandwidth may reach the bottleneck. Therefore, the CPU is not the main reason, so single-threading is naturally used. Moreover, using multi-threading is more troublesome.

But in Redis 4.0, it has begun to support multi-threading, such as background deletion and other functions.

Simply put, Redis used single-threaded mode before 4.0 because of the following three reasons:

  • Using Redis in single-threaded mode, its development and maintenance are more complicated. Simple, because single-threaded mode facilitates development and debugging.

  • Even if a single-threaded model is used, multiple client requests can be processed concurrently, mainly because Redis uses epoll-based multiplexing internally.

  • For Redis, the main performance bottleneck is memory or network bandwidth, not CPU.

But Redis introduced lazy deletion (also called asynchronous deletion) in 4.0 and later versions, which means that we can use an asynchronous method to delete data in Redis, for example :

  • unlink key: Similar to del key, delete the specified key. If the key does not exist, the key will be skipped. However, del will cause blocking, and the unlink command will reclaim memory in another thread, that is, it is non-blocking [http://www.redis.cn/commands/unlink.html];

  • flushdb async: Delete all data in the current database [http://www.redis.cn/commands/flushdb.html];

  • flushall async: Delete all data in all libraries Data [http://www.redis.cn/commands/flushall.html].

The advantage of this processing is that it will not cause the main thread of Redis to get stuck, and these operations will be handed over to the background thread for execution.

[Normally, using the del command can delete data quickly, but when the deleted key is a very large object, for example: when deleting a hash set containing thousands of elements , then the del instruction will cause the Redis main thread to freeze, so using lazy deletion can effectively avoid the Redis freeze problem. 】

Test point analysis:

Questions about the Redis thread model (single-threaded or multi-threaded) are almost one of the questions that Redis must ask, but those who answer well Not many, most of them can only answer that Redis is single-threaded and state the many benefits of single-threading, but they can accurately answer the characteristics of multi-threading in Redis4.0 and Redis6.0, especially in Redis6.0. There are very few people. Regarding the relevant knowledge of single-threading and multi-threading, there are also the following interview questions.

1. Since the Redis main thread is single-threaded, why is it so fast?

2. Introduce IO multiplexing in Redis?

3. Introduce multi-threading in Redis6.0?

1. Why is Redis so fast?

The reasons are as follows:

a. Memory-based operation: All data of Redis is stored in memory, so all operations are at the memory level, so its performance relatively high.

b. Simple data structure: The data structure of Redis is relatively simple and is specially designed for Redis. The time complexity of searching and operating these simple data structures is O(1).

c. Multiplexing and non-blocking IO: Redis uses the IO multiplexing function to listen to clients with multiple socket connections, so that one thread can be used to handle multiple situations, thereby reducing threads The overhead caused by switching also avoids IO blocking operations, thus greatly improving the performance of Redis.

d. Avoid context switching: Because it is a single-threaded model, unnecessary context switching and multi-thread competition are avoided, which saves the time and performance overhead caused by multi-thread switching. And single thread will not cause deadlock problems.

The official benchmark test results show that single-threaded Redis can achieve a throughput of 10W/S.

2.What is IO multiplexing?

The read and write methods of the socket are blocking by default. For example, when the read operation read method is called, the buffer does not have any data, then the thread will be stuck here until there is data in the buffer. Or when the connection is closed, the read method will return and the thread can continue to process other business.

But this obviously reduces the execution efficiency of the program, and Redis uses non-blocking IO, which means that the IO reading and writing process is no longer blocking, and the reading and writing methods are completed and returned instantly. That is to say, it will use the strategy of reading as much as it can read and writing as much as it can write to perform IO operations, which is obviously more in line with our pursuit of performance.

But this kind of non-blocking IO also faces a problem, that is, when we perform a read operation, it is possible that only a part of the data is read; the same is true for writing data, when the buffer is full , and our data has not been written yet, then it becomes a question when the effective data will be written.

The multiplexing of IO solves the above problem. The simplest way to use IO multiplexing is to use the select function. This function is the API interface provided by the operating system to the user program. Use It is used to monitor the readability and writability of multiple file descriptors, so that the read and write events of the file descriptors can be monitored. When the corresponding time is monitored, the thread can be notified to process the corresponding business, thus ensuring the normal execution of the Redis read and write function.

[However, the select function is basically not applicable to the current operating system, and the epoll function (Linux) is called instead. macOS uses Kqueue (inherited from Unix), because the select function is very important in the file descriptor. Performance is very poor when there are many. 】

3. Multi-threading in Redis6.0?

The single-threaded advantage of Redis is very great. It not only reduces the responsibility of the internal implementation of Redis, but also allows all operations to be performed without locks, and there is no deadlock or thread switching. performance and time consumption; but its shortcomings are also obvious. The single-thread mechanism makes it difficult to effectively improve Redis's QPS (Query Per Second, queries per second) (although it is fast enough, people still have to have higher pursuit).

Although Redis introduced multi-threading in version 4.0, multi-threading in this version can only be used for asynchronous deletion of large amounts of data, and is not of great significance for non-deletion operations.

If we use Redis multi-threading, we can share the pressure of Redis's synchronous read and write IO, make full use of multi-core CPU resources, and effectively improve Redis's QPS. Although Redis uses IO multiplexing and operates based on non-blocking IO, the reading and writing of IO itself is blocking. For example, when there is data in the socket, Redis will first copy the data from the kernel space to the user space, and then perform related operations. However, this copy process is blocking, and when the amount of data is larger, the time required for copying will increase. The more, and these operations are completed based on a single thread.

Therefore, a new multi-threading function has been added to Redis6.0 to improve IO reading and writing performance. Its main implementation idea is to split the IO reading and writing tasks of the main thread into a group of independent threads. Execution, so that the reading and writing of multiple sockets can be parallelized, but Redis commands are still executed serially by the main thread.

But note: Redis6.0 disables multi-threading by default, but it can be enabled by setting io-threads-do-reads in the configuration file redis.conf equal to true. But it's not enough. In addition, we also need to set the number of threads to correctly enable the multi-threading function. We also need to modify the Redis configuration, for example, setting io-threads 4 means opening 4 threads.

[Regarding the setting of the number of threads, the official recommendation is that if it is a 4-core CPU, then set the number of threads to 2 or 3; if it is an 8-core CPU, then set the number of threads to 6. In short, the number of threads is certain It should be smaller than the number of CPU cores of the machine. The larger the number of threads, the better. 】

Regarding the performance of Redis, the author of Redis mentioned at the 2019 RedisConf conference that the multi-threaded IO feature introduced in Redis 6.0 has at least doubled the performance. Chinese people also conducted comparative tests using the 4-threaded Redis version and the single-threaded Redis on Alibaba Cloud. They found that the test results were consistent with what the Redis author said, and the performance could basically be doubled.

Summary:

This article introduces the reasons why Redis is still fast in single thread before 4.0: based on memory operation, simple data structure, IO multiplexing and non-blocking IO, avoiding unnecessary Thread context switching. And in Redis 4.0, it began to support multi-threading, which is mainly reflected in the asynchronous deletion of big data, such as: unlink key, flushdb async, flushall async, etc. The multi-threading of Redis 6.0 increases the concurrency capability of IO reading and writing to better improve the performance of Redis.

For more programming-related knowledge, please visit: Programming Teaching! !

The above is the detailed content of Is redis single-threaded or multi-threaded? Why?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn