predis和phpredis都是redis的php客户端,区别如下

 

Redis的PHP客户端rediska、phpredis、predis

Redis支持的客户端种类非常多,包括C、Java、PHP、Python等,本文主要介绍PHP客户端的安装和使用。 

Redis的客户端实际上担负了通过网络协议与Redis Server进行通信的过程,通信的过程必须遵循协议规范,让客户的调用更加符合特定语言的使用习惯。

现有PHP客户端:rediska、phpredis、Predis,这些客户端中,有纯PHP的实现方案,也有二进制版本的实现方案。

rediska 官网https://github.com/shumkov/rediska

predis   官网: https://github.com/nrk/predis

phpredis 官网https://github.com/phpredis/phpredis

 

rediska、phpredis、predis 对比

官方提供的PHP客户端列表如下:

- predis phpredis rediska
易扩展  
客户端策略和Hash算法定义  
实现方式 纯PHP PHP扩展(C语言) 纯PHP
测试数据(本地环境下) 18900 SET/sec using 12 bytes for both key and value 29000 SET/sec using 12 bytes for both key and value  
  18300 GET/sec while retrieving the very same values 30000 GET/sec while retrieving the very same values  
  0.210 seconds to fetch 30000 keys using KEYS *. 0.037 seconds to fetch 30000 keys using “KEYS *”“.  
测试结果(网络环境下) 3150 SET/sec using 12 bytes for both key and 3300 SET/sec using 12 bytes for both key and  
  3150 GET/sec while retrieving the very same 3300 GET/sec while retrieving the very same  
  0.212 seconds to fetch 30000 keys using “KEYS *”. 0.088 seconds to fetch 30000 keys using “KEYS *”.  

 

predis

Predis是一个灵活和特性完备(PHP>5.3)的支持Redis的PHP客户端。

当前版本为0.6.3,默认不支持PHP5.2,主要特性如下:

 1. 完整的支持从1.2到2.4的Redis,并且支持当前正在开发的版本;
 2. 提供客户端实现的一致性哈希算法,支持自定义;
 3. 在单个或聚合连接中支持命令管道;(Command pipelining on single and aggregated connections) 
 4. 能够通过TCP/IP或者Unix domain sockets连接到redis,支持持久连接;
 5. 自动连接Redis实例,使用“懒惰”方式,只在第一个命令发出时执行连接;
 6. 可以灵活定义客户端的命令集合; 

 

phpredis 

这是一个二进制版本的PHP客户端,按照的说法,效率要比Predis高。

这个版本支持作为Session的Handler。

这个扩展的优点在于无需加载任何外部文件,使用比较方便。

缺点在于难于扩展,一般的PHP程序员无法对其做出扩展。

考虑到Redis正在飞速发展过程中,缺乏扩展的特性还是有些影响的,需要维护过程中注意进行升级更新。

 

Rediska

rediska 目前(2011年)还处于 beta 阶段。好久没人维护了,不推荐

他的代码托管在github上,可以方便的获取。

另外也提供了PEAR版本,所以获取和安装都非常方便。可以使用PEAR包安装。

 

 

phpredis是php扩展由C语言编写,诞生较早,很多PHPer都熟悉。 

predis是用PHP语言编写,由于最近几年composer的盛行,以及很多框架的支持composer,存于composer库的predis也被大量应用。

pconnect()是phpredis里的方法,区别于connect(),详细可以看米扑博客《PHP 高并发下请求 Redis 异常处理

总结就是pconnect方法建立后的连接并不随这请求的结束而关闭,而是依赖于php-fpm进程,php-fpm进程不死,redis connect就一直存在,直到空闲超时自动断开。

也就是建立了持久连接,适用于高并发下PHP请求Redis

 

但是predis没有pconnect()方法,该如何实现类似的功能呢? 

项目使用的是Laravel框架,但是在文档中并没有找到相关的配置参数。

于是只能读插件源码,最后在/src/Connection/StreamConnection.php类中找个了实现连接redis的方法:

    /**
     * Initializes a TCP stream resource.
     *
     * @param ParametersInterface $parameters Initialization parameters for the connection.
     *
     * @return resource
     */
    protected function tcpStreamInitializer(ParametersInterface $parameters)
    {
        if (!filter_var($parameters->host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
            $address = "tcp://$parameters->host:$parameters->port";
        } else {
            $address = "tcp://[$parameters->host]:$parameters->port";
        }
        $flags = STREAM_CLIENT_CONNECT;
        if (isset($parameters->async_connect) && $parameters->async_connect) {
            $flags |= STREAM_CLIENT_ASYNC_CONNECT;
        }
        if (isset($parameters->persistent)) {
            if (false !== $persistent = filter_var($parameters->persistent, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) {
                $flags |= STREAM_CLIENT_PERSISTENT;
                if ($persistent === null) {
                    $address = "{$address}/{$parameters->persistent}";
                }
            }
        }
        $resource = $this->createStreamSocket($parameters, $address, $flags);
        return $resource;
    }

 

在第19行的 $parameters->persistent 可以看到一个陌生的参数persistent,翻译为‘持久’。

所以只要在使用predis连接redis的时候,加上参数persistent,并赋给一个true或1,就可以实现phpredis的pconnect(),简单方便。

下边是邮件佐证,说明没有错误理解源码:

Can the predis support the function pconnect() which in php-redis?
Yes, just add in the connection parameters persistent=1 (when using URI strings) or persistent => true (when using a named array).

 

这个坑是怎么踩到的呢?

还是因为框架文档的原因,目前很多PHP框架都已经支持了composer,如Laravel,Yii,CI等,但是并不能保证文档及时更新,尤其是中文文档,所以还是要有阅读源码的能力。

其实从上边的代码中还可以看到很多内容:

  1. predis使用了tcp的方式连接redis,主要用到的函数是stream_socket_client(predis还有一种http的方式连接redis,主要用curl,不在这个类中)。
  2. predis并不依赖phpredis。很多项目环境安装了phpredis又在框架里安装了predis,就以为后者依赖前者,这是错误的。
  3. 在上述代码第16行还可以看到另一个参数async_connect,用于异步连接,也很重要,但是在很多文档里都没有介绍。

 

 

 

参考推荐

phpredis 中的 connect 和 pconnect

PHP redis pconnect 长连接详解

PHP 高并发下请求 Redis 异常处理