Go deep into php redis pconnect
The api used by the client to connect to the server in pconnect and phpredis.
The connection will not be closed on close or end of request until the php process ends.
This is the original text in the api description.
The problem arises:
1.Does php process ends end a php Execution or fpm? If it is the latter, it means that the redis connection will not be released even after one php Execution is completed, and the redis connection will be reused during the next execution.
2.The connection will not be closed on close means that if pconnect is used, The connection will not be closed even if The call close () shown in The Code is called?
With these two questions, let's conduct an experiment and take a closer look at what pconnect has done.
Preparations
Environment:
Nginx + fpm
Php5.3
We configure fpm
pm.max_children = 1pm.start_servers = 1pm.max_spare_servers = 1
In this way, our page request will be executed by a fixed fpm process to facilitate strace tracking.
Php code for the corresponding page request:
$ip = 10.136.30.144; $port = 7777; $redis = new Redis();$redis->pconnect($ip, $port, 1);$key = test;$value = this is test;$redis->set($key, $value);$d = $redis->get($key);var_dump($d);
The function of the code is very simple. Connect to redis, set a value first, and then retrieve it.
Test Question 1
Ideas:
Use strace to observe fpm system calls. If the connection life cycle is one php Execution, there will be a connect system call for each page call to connect to redis; if the lifecycle of a connection is the end of fpm, only the first page call will have a connect system call. After the connection is reused, you can directly send a command request without using connect.
Start a new fpm (process number 28082 ).
Run
strace -p 28082 -s 1024 -o redis_1
Record the system call of a page request. As shown in:
We can see that the process first establishes a socket connection (the file descriptor is 9 ). Then, send a series of commands to the reids to get the result string of "this is test. Redis commands or system calls related to connection are not closed. <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4NCjxwPtKzw + bH68fzveHK + Lrzo6zO0sPH1rTQ0DwvcD4NCjxwcmUgY2xhc3M9 "brush: java;"> lsof -n -p 28082
As you can see, the fpm process still maintains a reids connection to 10.136.30.144, and its file descriptor is 9 (which is consistent with the strace result ).
Run
strace -p 28082 -s 1024 -o redis_2
Record the system call of the second page request. The following result is displayed.
The difference from the first request is that the reids command is sent directly to get the result, saving the trouble of establishing a connection!
Use lsof-n-p 28082 to view the file descriptor opened by fpm. The result is the same as that of the above file.
It indicates that the connection is indeed reused and has not been created.
Execute the 6th page request (because we configured it during preparation, fpm is already a new process) and use lsof to view the file descriptor opened by the process.
We found that although there is still a reids connection with the descriptor 9, the temporary ports of the two tcp connections are different, that is, the connection has changed!
So far, we come to the conclusion of Question 1:
When pconnect is used, the connection is reused. the lifecycle of the connection is the lifecycle of the fpm process, not the execution of php once..
Test Question 2
For comparison, let's take a look at using connect to redis and call the redis-> close () System Call. (Change pconnect in the above Code to connect, and add redis-> close () at the end ())
We can see that in addition to establishing connections, the quit command is sent to reids at the end of the program, and the file descriptor of the connection is closed.
Next, let's see what table stuffing plug-ins exist in redis-> close () after pconnect is used? Http://www.bkjia.com/kf/yidong/wp/ "target =" _ blank "class =" keylink "> WPGJyIC8 + DQq0 + sLrtffV + 86qo7o8L3A + DQo8cHJlIGNsYXNzPQ =" brush: java; ">$ip = 10.136.30.144;$port = 7777;$redis = new Redis();$redis->pconnect($ip, $port, 1);$key = test;$value = this is test;$redis->set($key, $value);$d = $redis->get($key);var_dump($d);$redis->close();try{ $redis->get($key);} catch (Exception $e){ echo $e->getMessage();}
Let's take a look at the system calls of the 2nd page requests.
No connection is established, and a command is sent directly to obtain the result. Indicates that the connection is reused. At the same time, the quit command is not sent to the reids server, nor is there a system call to close the connection.
Note:
So far, we have come to the conclusion of Question 2:
If pconnect is used in the Code, the function of close is only to make the current php unable to carry out redis requests, but it cannot really close the redis persistent connection, and the connection will still be reused in subsequent requests, the lifecycle of the fpm process ends.
Conclusion
1. When pconnect is used, the connection will be reused. the lifecycle of the connection is the lifecycle of the fpm process, not the execution of php once.
2. if pconnect is used in the Code, the function of close is only to make the current php unable to carry out redis requests, but it cannot really close the redis persistent connection, and the connection will still be reused in subsequent requests, the lifecycle of the fpm process ends.