有没有支持持久连接的PHP Redis客户端?

11

如题,我正在寻找一个支持持久连接的php Redis客户端,因为我的Web应用程序接收了大量请求(每个请求都会将一个项目放入Redis队列中),我希望避免在每个请求中创建新的连接。

5个回答

9

我不确定这是否被支持,但你应该一定要看看Predis和Rediska,这两个库(特别是Predis)是目前最好的PHP Redis客户端。


谢谢Antirez,我以前从未尝试过Predis,它似乎支持持久连接。我相信一个C实现作为php模块应该会更快,但我会尝试它们并进行比较。 - secmask
问题是Predis是否支持持久连接,因为它是纯PHP实现而不是基于C的扩展。根据维护者的说法,如果您的PHP进程配置为常驻内存,则Predis支持持久连接。这在严肃的生产PHP + Apache设置中很常见,不过您的特定安装可能会有所不同,并且可能需要进行一些配置。 Predis FAQ 指出,当Predis是持久化的且PHP进程被用于请求时,连接是持久的。 - kevinlawler
免责声明:我尚未测试Predis。我首先尝试了C扩展,因为Predis似乎使用非常冗长的风格构建。我也不喜欢依赖于PHP的自动加载机制。 - kevinlawler
1
phpredis 据说比 predis 快得多。 - Prof. Falken

4

PhpRedis目前支持持久连接。使用PHP 7.0和PhpRedis 3.0,可以像这样使用pconnect()建立持久连接:

for ($i=0;$i<1000;$i++) {
    $redis = new Redis();
    $result = $redis->pconnect('127.0.0.1'); 
    $redis->set("iterator",$i);
    $response=$redis->get("iterator");
    $redis->close();
    unset($redis);
}

connect()相比,速度约快10倍(每个连接9.6毫秒对0.83毫秒):

for ($i=0;$i<1000;$i++) {
    $redis = new Redis();
    $result = $redis->connect('127.0.0.1'); 
    $redis->set("iterator",$i);
    $response=$redis->get("iterator");
    $redis->close();
    unset($redis); 
}

注意:“此功能在线程版本中不可用”。(我在Windows上运行IIS,因此运行NTS版本。)

2

Predis支持持久连接。您只需将persistent参数添加为1。

您可以使用以下代码:

$client = new Predis\Client(array(
   'scheme'    => 'tcp',
   'host'      => '127.0.0.1',
   'port'      => 6379,
   'database'  => 15,
   'persistent'=> 1
));

替代

$client = new Predis\Client('tcp://127.0.0.1:6379?database=15');

您可以在此处找到有关连接的更多参数: https://github.com/nrk/predis/wiki/Connection-Parameters


0

Predis自v0.8.0版本开始,使用PhpiredisStreamConnectionpersistent=1标志语法支持持久连接:

<?php
$client = new Predis\Client('tcp://127.0.0.1?persistent=1', array(
    'connections' => array(
        'tcp'  => 'Predis\Connection\PhpiredisStreamConnection',
        'unix' => 'Predis\Connection\PhpiredisStreamConnection',
    ),
);

我使用PhpiredisStreamConnection添加了persistant=1,但看起来仍然会得到相同的TIME_WAIT套接字。 - Nico AD

-2

PHP-Redis支持持久连接,因为它使用了一个用C语言编写的php扩展,这使得它具有在请求之间共享连接的机制。请查看popen和pconnect的文档。

Predis无法支持持久连接,因为它是100% PHP,而PHP在每个请求之间不共享任何内容。


1
根据Predis的作者,这个答案是不正确的。他声称当PHP进程配置为在请求之间保持常驻状态时(正如许多实现所做的那样),PHP请求可以共享信息。 - kevinlawler
1
同意,这个答案是错误的。popen()本来就是错误的资源类型(p == 管道进程)。pconnect()完全能够支持Zend内部的“xport”资源处理,从而允许维护持久连接。Predis本身使用stream_socket_client(),带有可选的STREAM_CLIENT_PERSISTENT标志。当PHP进程由像Apache这样的后端进程/线程池维护时,这些持久连接在后端的生命周期内保持存在。 - Joe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接