Swoole 4.4 coordinated preemptive scheduler

  coroutine, php, swoole

Preface

SwooleThe column set up by the kernel team will gradually devote itself to writing articles and introductions.SwooleThe development process, implementation principle, application practice, etc., we can better communicate, learn and build together.PHPEcology.

Coordinated scheduling

Last yearSwooleLaunched4.0After the release, full supportPHPConcorde, we can realize it based on ConcordeCSPProgramming, developers around exclaimed, the original PHP code can also be written like this.SwooleBy default, the coordination process is based on IO scheduling. Blocking in the program will automatically give up the current coordination process. We will not discuss the advantages of coordination process here. If it isIOIntensive scenes can be performed very well. But forCPUIntense scenes will lead to some coordination because they cannot be obtained.CPUThe movie was starved to death.

Preemptive scheduling

We planned to achieve this early this year.SwooleIn order to meet the problems caused by unbalanced scheduling in some scenarios. We have gone through several versions, and here we share with you the motivation and solutions in the development process.

图片描述

Our aim is to balance the scheduling of each tripCPUTime, for example, Xiecheng 3 requires a relatively long execution time, we must put Xiecheng 3CPUTime is actively interrupted without relying on it.IOEvents, so that each trip gets an average execution time.

At first, our idea was that we could start fromPHPIf the limit is reached, the current coordination routine can be automatically released. Because, after all, few people take up a lot of writing by Ma Pingchuan.CPUMost of the codes are controlled by loop conditions. wehookLoop instruction, every time we execute the loop instruction, we check the execution time of the coordination routine. We are very glad to get the original version. But doing so compares hack, andopcodeafteropcacheAfter optimization, the situation will become somewhat complicated.

Later we used itPHPTheticksMechanism, that is, inPHPDuring code compilation, injectionticksInstructions, can execute the corresponding functions, we can detect processing time in these functions, to achieve preemptive effect, but there is a problem here.PHPThedeclare(ticks=N)The syntax is only valid for the current script scope, that is, the project is slightly larger.requireOr ..includeIncoming scripts will not be injected automatically.ticksInstruction, soSwooleDevelopers are almost unacceptable. We are also trying to givePHPThe official mentioned onePR, you can set a global default at the extension layerticksHowever, the government is not willing to accept our submission, because the government feels that this function has a large loss of performance and is likely to be used inPHP8removeThis function. In fact, the measured performance loss is not large, and we have already verified it in the production environment and have achieved remarkable results, that is, we can yield someCPUDense logic makes the whole corresponding service time more balanced.
The following figure shows a comparison of the caller statistics of an RPC interface in our production environment. The waiting timeout time of the client is 2s, and the timeout is counted as an error.
图片描述
There is no preemptive scheduling on the left side and preemptive scheduling on the right side. It can be found that there will always be occasional timeout on the left side. After optimization, there is no overtime request. The response time of the request is very smooth and the stability of the service is improved.
图片描述
As can be seen from the above figure, due to the addition of preemptive scheduling, burrs with high request time consumption are removed, making the average request time smoother and more stable.

Want to do preemptive scheduling, forPHPIn general, there are two ways

  1. Single threadedPHPThe execution flow of, by executing instructions, can be inPHPLogic is injected into the execution process to check the execution time, plusSwooleThe coordination ability of can be switched in different coordination processes to achieve preemption.CPUThe purpose of.
  2. Consider opening a thread and check the execution time of the current execution coordination routine.

After trying the above methods, the number of ways to inject instructions is basically unable to get official support. We can only find another way out and open one more thread, which is only responsible for checking the current coordination process. The specific approach is to usePHP-7.1.0incomingVM interruptMechanism, the default every 5ms to check whether the current association process reached the maximum execution time, the default is 10ms, if more than, then give up the current association process, to be other association processPreemptionThe purpose of.

Sample code

NeedSwoole 4.4Or later

<?  php
 Co::set(['enable_preemptive_scheduler' => 1]);
 $start = microtime(1);
 echo "start\n";
 $flag = 1;
 
 go(function () use (&$flag) {
 echo "coro 1 start to loop\n";
 $i = 0;
 for (;  ;  ) {
 if (!  $flag) {
 break;
 }
 $i++;
 }
 echo "coro 1 can exit\n";
 });
 
 $end = microtime(1);
 $msec = ($end - $start) * 1000;
 echo "use time $msec\n";
 go(function () use (&$flag) {
 echo "coro 2 set flag = false\n";
 $flag = false;
 });
 echo "end\n";

Results of implementation

start
 coro 1 start to loop
 use time 11.121988296509
 coro 2 set flag = false
 end
 coro 1 can exit

It can be found that the code logic can be automatically executed from the dead cycle of the first synergetic processyieldCome out and execute the second coordination routine. Without this feature, the second coordination routine will never be executed, resulting in starvation. In this way, the second coordination routine can be successfully executed, and after the final execution, the first coordination routine will continue to be executed. To reach our second synergetic initiativePreemptionThe First ConcordeCPUThe effect of.

This feature is very useful in production environments, especially for real-time systems or scenarios where response time is sensitive.

Last

Thank you for being rightSwooleLong-term support and attention of the.