How to answer Redis multithreaded interview questions?

Insert picture description here
Redis used to be a single-threaded model. This was once an advantage of Redis. With the release of multi-threaded version 6.0, this version has completely abandoned the single-threaded model design. Redis, which originally used a single-threaded operation, has also begun to selectively use a multi-threaded model.

It seems that nothing can escape the "True Fragrance Law". Insert picture description here
So in the future, how to answer the question about Redis: Is Redis multi-threaded or single-threaded?

Think about it carefully, this problem can actually be divided into two main problems:

(1) Why did Redis choose the single-threaded model in the first place (the benefits of single-threaded)?

(2) Why did Redis add multithreading after 6.0 (in some cases, single thread has its shortcomings, and multithreading can solve it)?

In fact, it’s not really a problem, but with the continuous changes of the times, there are more and more problems, what we need more is to be compatible, different problems use different solutions, after all, there is no best technology, only the best match.

Then let's restore the Redis scene again

The author Antirez wrote on his blog when the RC1 version was released:

the most "enterprise" Redis version to date // the most "enterprise"

the largest release of Redis ever as far as I can tell // 最大的

the one where the biggest amount of people participated // the biggest amount of people participatedInsert picture description here

With this change, there is a rapid improvement in performance~

First po to release the new and old performance graphs. Insert picture description here
Insert picture description here
From the above, we can see that the performance of the GET/SET command in 4-thread IO is almost doubled compared to single-threaded. In addition, these data are just to simply verify whether multi-threaded IO really brings performance optimization, and does not perform stress testing for rigorous delay control and different concurrency scenarios. The data is only for verification and reference and cannot be used as an online indicator. It is only the performance of the current unstble branch. It does not rule out that the performance of the subsequent official version will be better.

Why Redis used single thread in the beginning

Whether it is single-threaded or multi-threaded, it is to improve the development efficiency of Redis, because Redis is a memory-based database and has to handle a large number of external network requests, which inevitably requires multiple IOs. Fortunately, Redis uses many excellent mechanisms to ensure its high efficiency.

Redis developed a network event processor based on the Reactor model. This processor is called a file event processor. It is composed of 4 parts: multiple sockets, IO multiplexing program, file event dispatcher, and event handler. Because the consumption of the file event dispatcher queue is single-threaded, Redis is called the single-threaded model.Insert picture description here

Generally speaking, the bottleneck of Redis is not in CPU, but in memory and network. If you want to use multiple CPU cores, you can build multiple Redis instances to solve it.

In fact, Redis 4.0 started with the concept of multithreading, such as Redis deleting objects in the background through multithreading, and blocking commands implemented through the Redis module.

So why is Redis designed to be single-threaded? It can be summarized as follows:

(1) IO multiplexing

Let's take a look at the top-level design of Redis. Insert picture description hereFD is a file descriptor, which means that the current file is in a readable, writable or abnormal state. Use the I/O multiplexing mechanism to monitor the readable and writable status of multiple file descriptors at the same time. You can understand it as having the characteristics of multi-threading.

Once a network request is received, it will be processed quickly in memory. Since most of the operations are pure memory, the processing speed will be very fast. That is to say, in single-threaded mode, even if there are a lot of connected network processing, because of IO multiplexing, it can still be ignored in high-speed memory processing.

(2) High maintainability

Although the multithreading model performs well in some aspects, it introduces the uncertainty of program execution order and brings a series of problems with concurrent reading and writing. In single-threaded mode, debugging and testing can be carried out conveniently.

(3) Based on memory, the efficiency is still high in a single-threaded state

Multithreading can make full use of CPU resources, but for Redis, because of its memory speed, it can handle 100,000 user requests in one second. If 100,000 user requests per second cannot be satisfied, then we will You can use Redis sharding technology to hand it over to different Redis servers. This approach avoids the introduction of a large number of multi-threaded operations in the same Redis service.

And based on memory, unless AOF backup is to be performed, basically no I/O operations will be involved. The reading and writing of these data only occurs in memory, so the processing speed is very fast; it may not be a good solution to process all external requests with a multi-threaded model.

Now we know that it can basically be summarized in two sentences, based on memory and using multiplexing technology, single-threaded speed is very fast, but also to ensure the characteristics of multi-threading. Because there is no need to use multiple threads.

Why introduce multithreading?

Because the bottleneck of Redis is not the CPU, but the memory and network.

If the memory is not enough, you can add memory or do data structure optimization and other optimizations, but the performance optimization of the network is the big one. The read and write of network IO takes up most of the CPU time during the entire execution of Redis. If you deal with this part of the network Making it into a multi-threaded processing method will greatly improve the performance of the entire Redis.

The multi-threaded part of Redis is only used to process network data reading and writing and protocol analysis, and the execution of commands is still single-threaded. The reason for this design is that Redis does not want to become complicated due to multi-threading, and it needs to control the concurrency problems of key, lua, transaction, LPUSH/LPOP, etc.

Redis has added some delete operations that can be processed asynchronously by other threads in the latest versions, such as: UNLINK, FLUSHALL ASYNC and FLUSHDB ASYNC, why do we need these delete operations, and why they need to be processed asynchronously by multi-threading ?

We know that Redis can use the del command to delete an element. If this element is very large, it may occupy tens of megabytes or hundreds of megabytes, then it cannot be completed in a short period of time. This requires multi-threaded asynchronous support. Insert picture description here
Now the deletion can be done in the background.

Optimization direction:

  • To improve network IO performance, typical implementations such as using DPDK to replace the kernel network stack.
  • Use multi-threading to make full use of multi-core, typical implementations such as Memcached.

So to sum up, Redis supports multi-threading mainly for two reasons:

  • The server CPU resources can be fully utilized, and currently the main thread can only use one core.
  • Multi-threaded tasks can share the Redis synchronous IO read and write load.

Does Redis 6.0 enable multi-threading by default?

No, configure in the conf file

io-threads-do-reads yes

io-threads number of threads

Official recommendation: The recommended setting for a 4-core machine is 2 or 3 threads, and the recommended setting for an 8-core machine is 6 threads. The number of threads must be less than the number of machine cores, and try not to exceed 8.

Redis 6.0 multi-threaded realization mechanism? Insert picture description here
The process is briefly described as follows:

  • The main thread is responsible for receiving the connection establishment request, obtaining the Socket and placing it in the global waiting read processing queue.
  • After the main thread processes the read event, these connections are allocated to these IO threads through RR (Round Robin).
  • The main thread blocks and waits for the IO thread to finish reading the Socket.
  • The main thread executes the request command in a single-threaded manner, requests the data to be read and parsed, but does not execute.
  • The main thread blocks and waits for the IO thread to write data back to the Socket.
  • Unbind and clear the waiting queue. Insert picture description here
    The design has the following characteristics:
  • IO threads are either reading or writing to the socket at the same time, not reading or writing at the same time.
  • The IO thread is only responsible for reading and writing Socket parsing commands, not for command processing.

After enabling multithreading, will there be thread concurrency safety issues?

No, the multi-threaded part of Redis is only used to process network data reading and writing and protocol analysis, and the execution commands are still executed sequentially in a single thread.

IO multiplexing is often mentioned in Redis threads. How to understand?

This is a type of IO model, the classic Reactor design pattern, sometimes called asynchronous blocking IO.Insert picture description here

At last

Redis chooses to use the single-threaded model to process client requests mainly because the CPU is not the bottleneck of the Redis server, so the performance improvement brought by the multi-threaded model cannot offset the development and maintenance costs it brings. The performance bottleneck of the system is also mainly Network I/O operations; Redis introduces multi-threaded operations for performance reasons. For some large key-value pair deletion operations, releasing memory space through multi-threading non-blocking can also reduce the blocking time of the Redis main thread. , Improve the efficiency of execution.

Linux, C/C++ technology exchange group: [960994558] I have compiled some good learning books, interview questions from big companies, and popular technology teaching video materials to share in it (including C/C++, Linux, Nginx, ZeroMQ, MySQL) , Redis, fastdfs, MongoDB, ZK, streaming media, CDN, P2P, K8S, Docker, TCP/IP, coroutine, DPDK, etc.), you can add it yourself if you need it! ~

Insert picture description here
In one sentence: Single thread was used before because of the fast memory speed, and multiplexing has the effect of multiplexing, which is enough. Now it is introduced because some operations need to be optimized, such as delete operations, so Introduced multithreading.

Welcome to point out the above shortcomings and discuss them. Friends who feel good hope to get your forwarding support, and at the same time, they can continue to follow me and share the contents of dry goods every day!

Guess you like

Origin blog.csdn.net/weixin_52622200/article/details/114410884