Redis It's single threaded , Put that aside , It's going sideways , The truth that everyone knows . Now it's different ,Redis Changed . Say that again , There has to be a questioning tone to argue with you . Not determined , Maybe we'll just surrender , Follow others .
What is it like , Ladies and gentlemen, please go down with Xiao Lai ：
Figure note ： Mind mapping
Reactor mode , You may not know much about , If you read the last article, you should have some impression . involves Redis Thread is a topic that can't be bypassed .
1、 The traditional block IO Model
Before we talk about reactor mode , It's necessary to mention the traditional blocking IO How models are handled .
In traditional blocking IO In the model , By an independent Acceptor Thread to listen for client connections , Whenever a client requests to come , It will assign a new thread to the client to process . When multiple requests come at the same time , The corresponding number of threads will be allocated to the server . This will lead to CPU Switch frequently , Waste resources .
Some connection requests come over and do nothing , But the server will also allocate the corresponding thread , This results in unnecessary thread overhead . It's like you go to a restaurant , You look at the menu for a long time, and you find that it's really expensive , And then you leave . The server waiting for you to order during this period is equivalent to a corresponding thread , Your order can be seen as a connection request .
meanwhile , Every time a connection is established , When a thread calls a read-write method , Threads will be blocked , Until there's data to read and write , In the meantime, the thread cannot do anything else . It's also an example of eating in the upper restaurant , You go out for a walk and find that this one is the most cost-effective . I went back to this restaurant and looked at the menu for a long time , The waiter will wait for you to finish your order . In the process, the waiter can't do anything , That's the only way to do it , This process is equivalent to blocking .
Look at this way , Each request is assigned a thread , And you have to wait for the thread to finish processing . Some requests just come and connect , Nothing to do , You have to assign it a thread , How high is the server resource requirement . Encounter high concurrency scenarios , I can't imagine . For fixed architectures with small number of connections, we can consider .
2、 Pseudo asynchrony IO Model
You may have seen a solution with thread pool optimization , Using thread pool and task queue . This is called pseudo asynchrony IO Model .
When there is client access , Encapsulate the client's request as a task Post to the backend pool to process . The thread pool maintains a message queue and multiple active threads , Process the tasks in the message queue .
This solution , The problem of thread resource exhaustion caused by creating a thread for each request is avoided . But the underlying model is still synchronous blocking . If all threads in the thread pool are blocked , Then you can't respond to more requests . So this mode limits the maximum number of connections , It doesn't solve the problem fundamentally .
Let's continue to use the restaurant above as an example , The restaurant owner has been running it for a while , There are more customers , The original store 5 A waiter can't handle one-on-one service . So the boss used 5 Personal thread pool way . After serving one guest, the waiter goes to serve another immediately .
Then the problem arises , Some guests order very slowly , Waiters have to wait a long time , Until the guests have ordered . If 5 If all the guests order very slowly , this 5 A waiter has to wait all the time , It will lead to the state that the rest of the customers are not served . This is what we mentioned above in the thread pool where all threads are blocked .
So how to solve this problem ？ Don't worry. , Reactor The pattern is coming out .
3、Reactor Design patterns
Reactor The basic design idea of pattern is based on I/O Reuse the model to achieve .
Here under I/O Reuse model . And traditional IO Multithreading is different ,I/O In the reuse model, multiple connections share a blocking object , The application just needs to wait on a blocking object . When a connection has new data to process , The operating system notifies the application , Thread returns... From blocked state , Start business processing .
What does that mean ？ Restaurant owners also found that customers order slowly , So he took a bold approach , There's only one waiter left . When the guests order , The waiter went to entertain other guests , After ordering the meal, the guest calls the waiter to serve directly . The customer and the server can be seen as multiple connections and one thread respectively . The waiter is stuck with a customer , When another customer orders , She immediately went to serve other customers .
I understand reactor After the design idea of , Let's take a look at today's main character list reactor Single thread implementation scheme ：
Reactor adopt I/O Multiplexers monitor client request events , After receiving the event, it is distributed through the task dispatcher .
For the establish connection request event , adopt Acceptor Handle , And establish the corresponding handler Responsible for the follow-up business processing .
For disconnected Events ,Reactor The corresponding handler complete read-> Business processing ->write Processing flow , And return the result to the client .
The whole process is completed in one thread .
The era of single thread
I understand Reactor After the model , You may have a question , What does this have to do with our theme today . Maybe what you don't know is ,Redis Is based on Reactor Single thread mode to achieve .
IO After the multiplexer receives the user's request , All pushed to a queue , To the file dispatcher . For subsequent operations , And in reactor The same thing you see in a single threaded implementation , The whole process is completed in one thread , therefore Redis It's called a single threaded operation .
For single threaded Redis Come on , Memory based , And the time complexity of command operation is low , So the read-write rate is very fast .
Redis6 Multithreading is introduced in the version . As mentioned above Redis Single threaded processing is very fast , So why introduce multithreading ？ Where is the bottleneck of single thread ？
Let's start with the second question , stay Redis in , The performance bottleneck of single thread is mainly in the network IO Operationally . It's reading and writing the Internet read/write System calls take up most of the time during execution CPU Time . If you want to delete some large key value pairs , It can't be deleted in a short time , Then, for a single thread, the following operations will be blocked .
Think back to what I said above Reactor The mode of single thread processing . For disconnected Events ,Reactor The corresponding handler complete read-> Business processing ->write Processing flow , That is to say, this step will cause a performance bottleneck .
Redis In the design, the network data read-write and protocol analysis are processed by multithreading , For command execution , Still using single threaded operations .
- The traditional block IO Model client and server threads 1:1 Distribute , Not conducive to expansion .
- Pseudo asynchrony IO The model adopts thread pool mode , But the underlying layer still uses synchronous blocking , Limit the maximum number of connections .
- Reactor adopt I/O Multiplexers monitor client request events , Distribute through a task dispatcher .
The era of single thread
- be based on Reactor Single thread mode implementation , adopt IO After the multiplexer receives the user's request , All pushed to a queue , Leave it to the file dispatcher for processing .
- Single thread performance bottleneck is mainly in the network IO On .
- The network data reading and writing and protocol parsing are processed by multithreading , For command execution , Still using single threaded operations .
本文为[PHP open source community]所创，转载请带上原文链接，感谢