This article will take you to understand the thread model in Redis6, and introduce the single-thread model and multi-thread model. I hope it will be helpful to you!
If we simply say that redis is single-threaded or multi-threaded, this answer is definitely not rigorous. The threading models used by different versions are different. [Related recommendations: Redis Video Tutorial]
multi-threading Stuff (Asynchronous Deletion).
Mainly means that Redis's network IO and key-value pair reading and writing are completed by one thread. When Redis processes the client's request, it includes acquisition (socket reading), parsing, execution, content return (socket writing), etc. Processed by a sequential main thread, this is called "single threaded". This is also the main process for Redis to provide external key-value storage services.
But other functions of Redis, such aspersistence, asynchronous deletion, cluster data synchronization, etc., are actually executed by
extra threads.
It can be said that the Redis worker thread is single-threaded. However, the entire Redis is multi-threaded;
2.2 Reasons for fast single-thread performance
Redis 3 .x Single-threaded era but The main reason for fast performance:
Based on memory operations: all data is stored in memory, so all operations are at the memory levelSimple data structure: Redis's data structure is specially designed, and most of the time complexity of searching and operating these simple data structures is
Avoid context switching: Because it is a single-threaded model, unnecessary context switching and multi-thread competition can be avoided. This can save the time and performance consumption caused by multi-thread switching, and single-thread switching can be avoided. Threads will not cause deadlock problems
Redis is based on memory operations, so it The bottleneck may be the machine's memory or network bandwidth rather than the CPU. Since the CPU is not the bottleneck, it is natural to use a single-threaded solution. Moreover, using multi-threading is more troublesome. However, Redis 4.0 began to support multi-threading, such as background deletion and other functions
.Simply put, there are three main reasons why single-threading has been used before Redis 4.0: Using a single-threaded model makes the development and maintenance of Redis simpler, because single-threading The model facilitates development and debugging; although the multi-threaded model performs well in some aspects, it introduces uncertainty in the order of program execution, brings about a series of problems with concurrent reading and writing, increases system complexity, and may Performance loss caused by thread switching, even locking and unlocking, and deadlock. Redis has very high processing performance through AE event model and IO multiplexing and other technologies, so there is no need to use multi-threading. The single-thread mechanism greatly reduces the complexity of Redis's internal implementation. Hash's inertia, Rehash, Lpush and other "thread-unsafe" commands can be executed without locks.
performance bottleneck is memory or network bandwidth rather than CPU
.3. Redis multi-threading model
Since single thread is so good, why introduce multi-threading?
Single thread also has its own troubles, such as Large key deletion problem:
Under normal circumstances, the del instruction can be used to delete data quickly. However, when the deleted key is a very large object, such as a hash set containing thousands of elements, the del instruction will cause the Redis main The thread is stuck.
Therefore, a new multi-threading module was added in Redis 4.0. Of course, the multi-threading in this version is mainly to solve the problem of relatively low data deletion efficiency. You can effectively avoid Redis lag problems (large key deletion, etc.) through lazy deletion. The steps are as follows:
unlink key: with DEL It is a lazy free implementation of the same key deletion function. The only difference is that when UNLINK deletes a set type key, if the number of elements in the set key is greater than 64, the main thread only removes the key to be deleted from the database dictionary, and the real The memory release operation is performed by a separate bio. If the number of elements is small (less than 64) or of type String, they will also be deleted directly in the main thread.
flushall/flushdb async: For the flush database command flushall/flushdb, the async asynchronous cleanup option is added, so that redis operates asynchronously when clearing the database. The implementation logic is to create a new empty dictionary for the database, and give the original old database dictionary to the background thread to delete the data one by one and release the memory.
lazy free is to remove
certain costs (main time replication, occupying the main thread cpu time slice) with higher deletion operations, from redis The main thread is stripped to let the bio sub-thread handle it, which greatly reduces the main thread blocking time. This reduces performance and stability issues caused by deletion.
3.2 Working principle of multi-threading
I/O reading and writing itself is blocked. For example, when there is data in the socket, Redis The data will be copied from the kernel space to the user space through the call, and then handed over to Redis for the call. This copy process is blocking. When the amount of data is larger, the copy will take more time, and these operations are It is done based on single thread. In Redis 6.0, a newmulti-threading function is added to improve the I/O read and write performance. His main implementation idea is to combine the IO read and write tasks of the main thread. Split it into a group of independent threads for execution, so that the reading and writing of multiple sockets can be parallelized. The use of multi-channel I/O multiplexing technology can allow a single thread to efficiently handle multiple connection requests (minimize the network IO time consumption), the most time-consuming Socket reading, request parsing, and writing are outsourced separately. The remaining command execution is still executed serially by the main thread and interacts with the data in the memory. Combined with the above figure, we can see that
reading and writing network data and parsing the request protocol are processed through multiple IO threads. For real command execution, the main thread operation is still used (thread safety), is a good compromise. Therefore, is multi-threaded for the entire Redis, but it is still single-threaded for the worker thread (command execution) .
The process is briefly described as follows:
Reading the socket is completed
(If the command is not received, it will wait for IO to continue next time)
Completed writing the data back to the socket (if it is not finished once, it will be written again next time)
Features are as follows:
After careful consideration Stress test, The current performance can be improved by more than 1 times.
Question 1: Is the waiting list always blocked and not processed if it is not full?
Reply: What is detected when blocking is whether the IO thread still has tasks. Wait until the processing is completed before continuing. These tasks are added during execution. If the number of tasks I still have some doubts about this. Can anyone explain it (comment)?
3.4 Is multi-threading enabled by default?
In Redis6.0, The multi-threading mechanism is turned off by default
. If you need to use the multi-threading function, you need to complete two settings in redis.conf.
If it is an 8-core CPU, it is recommended that the number of threads be set to 6
. The number of threads must be less than The number of machine cores and threads is not necessarily better. Redis itself is excellent since its debut, based on memory operations, simple data structure, multiplexing and non-blocking I/O, avoiding It eliminates unnecessary thread context switching and other features, and is still very fast in a single-threaded environment;
But the key deletion of big data is still very slow, so multi-threaded unlink key/flushall was introduced in Redis 4.0 Commands such as async are mainly used for asynchronous deletion of Redis data;
I/O multi-threaded reading and writing was introduced in Redis 6.0, so that more tasks can be processed more efficiently. Redis just Turn I/O reading and writing into multi-threading
, and command execution is still executed serially by the main thread
, so operating Redis under multi-threading will not A thread safety issue occurs
.
Redis Whether it is the original single-threaded design or the current multi-threaded design that is contrary to the original design, there is only one purpose: to make Redis faster and faster.
For more programming-related knowledge, please visit: Introduction to Programming! !
The above is the detailed content of A brief analysis of single-threaded and multi-threaded models in Redis6. For more information, please follow other related articles on the PHP Chinese website!