phpredis 中的 connect 和 pconnect
phpredis 是 PHP 开发 Redis 的封装,已经被广泛使用
The phpredis extension provides an API for communicating with the Redis key-value store.
It is released under the PHP License, version 3.01. This code has been developed and maintained by Owlient from November 2009 to March 2011.
phpredis 官网:https://github.com/phpredis/phpredis
现在不管是在缓存方面,还是NoSQL方面,Redis很火也很流行,但是使用方面的经验不是很多,包括Redis的一些优化配置,还有使用Redis的一些技巧和经验都没有一个官方的指导,所以在网上能搜索到很多相关的东西,但是发现不一定完全匹配自己遇到的一些问题,而且有的文章只是告诉你要这么做,但是没有深究到底是为什么?
最近碰到一个项目的优化,该项目其实逻辑很简单,大的结构就是处理用户的请求,然后读Redis,返回对应的数据。而问题的所在在于该项目有个特点,就是存在整点效应——平时访问量比较低,服务器压力不大,但是整点的时候并发能够达到平时的4-5倍,服务器完全抗不住。所以我们就慢慢梳理整个项目的架构,还有流程,想从中发现问题的所在。
为了先解决并发高服务器负载过高的问题,我们首先分析了…(话扯远了,背景就介绍到这里,呵呵。。)
首先先介绍下connect
和pconnect
的区别。
connect:脚本结束之后连接就释放了。
pconnect:脚本结束之后连接不释放,连接保持在php-fpm进程中。
为了验证这点,我们可以写个脚本测试一下。
其中服务器是nginx
,php-fpm
采用静态方式,因为动态方式下php-fpm
的进程数量可能会变化,所以为了简单我们采用静态方式启动。
其中php-fpm的数量我们设置成5个。
下面的脚本测试使用connect
的情况,我们让脚本连接到redis,然后休眠10s
<?php $app = new App (); $app->get ( '/', function () { $redis = new Redis (); $redis->connect ( '127.0.0.1' ); sleep(10); echo 'Hello World'; // $redis->close (); } ); return $app;
然后运行5个请求:
curl http://localhost:8081/
这时候我们可以看下redis中的connect_clients
:
$ redis-cli info | grep connected_clients
connected_clients:14
等脚本运行完毕之后我们再看一下connect_clients
:
$ redis-cli info | grep connected_clients
connected_clients:9
之前建立的redis连接资源被释放了。
我们修改上面的代码,把connect
改成pconnect
:
<?php $app = new App (); $app->get ( '/', function () { $redis = new Redis (); $redis->pconnect ( '127.0.0.1' ); sleep(10); echo 'Hello World'; // $redis->close (); } ); return $app;
和上面同样的操作,发现脚本脚本运行结束后connected_clients
还是14:
$ redis-cli info | grep connected_clients
connected_clients:14
这说明脚本运行结束后,redis
连接资源并没有释放,而是由php-fpm
进程保持(可以通过 kill php-fpm
看到,当脚本停止运行后连接释放)
所以使用pconnect
代替connect
,可以减少频繁建立redis连接的消耗。
另外,使用pconnect
还可以减少同一个进程(php-fpm
)频繁建立连接的消耗,可以通过以下代码验证:
使用connect
的情况:
<?php $redis1 = new Redis(); $redis1->connect('127.0.0.1'); sleep(5); $redis2 = new Redis(); $redis2->connect('127.0.0.1'); sleep(5); //$redis->close(); //$redis2->close();
运行上述脚本,会发现connect_clients
会增加2个。
使用pconnect
的情况:
<?php $redis1 = new Redis(); $redis1->pconnect('127.0.0.1'); sleep(5); $redis2 = new Redis(); $redis2->pconnect('127.0.0.1'); sleep(5); //$redis->close(); //$redis2->close();
而运行上述代码,connect_clients
只会增加1个,
这说明在一个进程中,pconnect
是可以保持redis连接状态提供复用的。
参考推荐:
版权所有: 本文系米扑博客原创、转载、摘录,或修订后发表,最后更新于 2018-03-29 05:10:21
侵权处理: 本个人博客,不盈利,若侵犯了您的作品权,请联系博主删除,莫恶意,索钱财,感谢!