PHP REDIS 使用长连接多数据库存储到最后一个数据库中的问题解决

原创 2017年12月01日 13:58:23

在使用redis持久连接时,不同的库存储操作不同的数据,但是存储数据时默认存储到最后一个库了,解决方法在最后

风.fox

redis connect 短连接 单例模式没有此问题

class Connect2
{
    /**
     * 类单例数组
     *
     * @var array
     */
    private static $instance = [];
    /**
     * redis连接句柄
     *
     * @var \Redis
     */
    private $redis;
    /**
     * hash的key
     *
     * @var int
     */
    private $db_index;

    /**
     * 私有化构造函数,防止类外实例化
     *
     * @param int $db_index
     */
    private function __construct($options = [], $db_index = 0)
    {
        $config         = config('cache');
        $db_index       = (int)$db_index;
        $this->db_index = $db_index;
        $this->redis    = new \Redis();
        $this->redis->connect($config['host'], $config['port']);
        $this->redis->select($db_index);
    }

    private function __clone()
    {
    }

    /**
     * 获取类单例
     *
     * @param int $db_index
     * @return self
     */
    public static function getRedisInstance($options = [], $db_index = 0)
    {
        $db_index = (int)$db_index;
        if (!isset(self::$instance[$db_index])) {
            self::$instance[$db_index] = new self($options, $db_index);
        }
        return self::$instance[$db_index];
    }

    /**
     * 获取redis的连接实例
     *
     * @return \Redis
     */
    public function getConnect()
    {
        return $this->redis;
    }

    /**
     * 关闭单例时做清理工作
     */
    public function __destruct()
    {
        self::$instance[$this->db_index]->redis->close();
        self::$instance[$this->db_index] = null;
    }
}

////////
////////
$config = config('cache');
$r3     = Connect2::getRedisInstance($config, 3);
$r4     = Connect2::getRedisInstance($config, 4);
$r3->getConnect()->set('33333333333', '22222222', 600);
$r4->getConnect()->set('44444444444', '22222222', 600);

执行上面代码就会在redis缓存中的,db(3),db(4)看到相应的键值。

redis pconnect 持久连接(长连接)会自动存储到最后一个db库中

错误的 类如下

/** redis 参数介绍  http://www.cnblogs.com/weafer/archive/2011/09/21/2184059.html
 * @category    Extend
 * @package     Extend
 * @subpackage  Driver.Cache
 * @author      fox
 */
class RedisAliMulti
{
    protected $options = ['host'       => '127.0.0.1',
                          'port'       => 6379,
                          'password'   => '',
                          'select'     => 0,
                          'timeout'    => 0,
                          'expire'     => 0,
                          'persistent' => false,
                          'prefix'     => '',
    ];
    //数据库编号
    private $db_index;
    /**
     * 类单例数组
     *
     * @var array
     */
    private static $instance = [];
    /**
     * redis连接句柄
     *
     * @var \Redis
     */
    private $handler;

    /**
     * 构造函数
     * @param array $options 缓存参数
     * @param null  $select
     * @access public
     */
    public function __construct($options = [], $select = null)
    {
        if (!empty($options)) {
            $this->options = array_merge($this->options, $options);
        }
        $func          = $this->options['persistent'] ? 'pconnect' : 'connect';
        $this->handler = new \Redis;
        $this->handler->$func($this->options['host'], $this->options['port'], $this->options['timeout']);
        if ('' != $this->options['password']) {
            $this->handler->auth($this->options['password']);
        }
        $this->db_index = (int)$select;
        $this->handler->select($this->db_index);
    }

    /**
     * 析构释放连接
     * @access public
     */
    public function __destruct()
    {
        self::$instance[$this->db_index]->getConnect()->close();
        self::$instance[$this->db_index] = null;
        if (isset($this->handler)) {
            $this->handler->close();
            $this->handler = null;
        }
    }

    /**
     * @return \Redis
     */
    public function getConnect()
    {
        return $this->handler;
    }

    /**
     * 获取类单例
     * @param array $options
     * @param int   $db_index
     * @return self
     */
    public static function getRedisInstance($options = [], $db_index = 0)
    {
        $db_index = (int)$db_index;
        if (!isset(self::$instance[$db_index])) {
            self::$instance[$db_index] = new self($options, $db_index);
        }
        return self::$instance[$db_index];
    }
}
////////
///////
//////
$r31 = RedisAliMulti::getRedisInstance($config, 3);
$r41 = RedisAliMulti::getRedisInstance($config, 4);
$r31->getConnect()->set('33333333333===', '22222222', 600);
$r41->getConnect()->set('44444444444===', '22222222', 600);

以上执行后,只会在db(4)看到这2个键值,并不是我们预期的db(3)db(4)相应的键值。
解决方法如下:

/** redis 参数介绍  http://www.cnblogs.com/weafer/archive/2011/09/21/2184059.html
 * @category    Extend
 * @package     Extend
 * @subpackage  Driver.Cache
 * @author      fox
 */
class RedisAliMulti
{
    protected $options = ['host'       => '127.0.0.1',
                          'port'       => 6379,
                          'password'   => '',
                          'select'     => 0,
                          'timeout'    => 0,
                          'expire'     => 0,
                          'persistent' => false,
                          'prefix'     => '',
    ];
    //数据库编号
    private $db_index;
    /**
     * 类单例数组
     *
     * @var array
     */
    private static $instance = [];
    /**
     * redis连接句柄
     *
     * @var \Redis
     */
    private $handler;

    /**
     * 构造函数
     * @param array $options 缓存参数
     * @param null  $select
     * @access public
     */
    public function __construct($options = [], $select = null)
    {
        if (!empty($options)) {
            $this->options = array_merge($this->options, $options);
        }
        $func          = $this->options['persistent'] ? 'pconnect' : 'connect';
        //注意 $persistent_id 此处,持久连接设置标识
        $persistent_id = $this->options['persistent'] ? 'pconnect_' . $select : null;
        $this->handler = new \Redis;
        $this->handler->$func($this->options['host'], $this->options['port'], $this->options['timeout'], $persistent_id);
        if ('' != $this->options['password']) {
            $this->handler->auth($this->options['password']);
        }
        $this->db_index = (int)$select;
        $this->handler->select($this->db_index);
    }

    /**
     * 析构释放连接
     * @access public
     */
    public function __destruct()
    {
        self::$instance[$this->db_index]->getConnect()->close();
        self::$instance[$this->db_index] = null;
        if (isset($this->handler)) {
            $this->handler->close();
            $this->handler = null;
        }
    }

    /**
     * @return \Redis
     */
    public function getConnect()
    {
        return $this->handler;
    }

    /**
     * 获取类单例
     * @param array $options
     * @param int   $db_index
     * @return self
     */
    public static function getRedisInstance($options = [], $db_index = 0)
    {
        $db_index = (int)$db_index;
        if (!isset(self::$instance[$db_index])) {
            self::$instance[$db_index] = new self($options, $db_index);
        }
        return self::$instance[$db_index];
    }
}
////////
///////
//////
$r31 = RedisAliMulti::getRedisInstance($config, 3);
$r41 = RedisAliMulti::getRedisInstance($config, 4);
$r31->getConnect()->set('33333333333===', '22222222', 600);
$r41->getConnect()->set('44444444444===', '22222222', 600);

原因说明:要给持久连接设置一个数据库标识即可,即使用某个库时候,把这个库设置一个标识

如下代码片段

//注意 $persistent_id 此处,持久接设置标识
        $persistent_id = $this->options['persistent'] ? 'pconnect_' . $select : null;
        $this->handler = new \Redis;
        $this->handler->$func($this->options['host'], $this->options['port'], $this->options['timeout'], $persistent_id);

至此完美解决

版权声明:原创文章欢迎转载,不过要记得加出处哦 https://blog.csdn.net/wljk506/article/details/78685965

PHP中使用Redis长连接笔记

php中使用redis长连接踩过的坑,pconnect连接创建的redis实例,因为select db操作修改了redis实例,导致出现意想不到的问题...
  • f1520107395
  • f1520107395
  • 2017-05-03 23:40:47
  • 5704

深入php redis pconnect

pconnect, phpredis中用于client连接server的api。The connection will not be closed on close or end of request...
  • qmhball
  • qmhball
  • 2015-07-21 16:50:06
  • 16002

php pconnect 长连接原理

HP的MySQL持久化连接,美好的目标,却拥有糟糕的口碑,往往令人敬而远之。这到底是为啥么。近距离观察后发现,这家伙也不容易啊,要看Apache的脸色,还得听MySQL指挥。 对于作为Apach...
  • clh604
  • clh604
  • 2014-07-04 18:57:12
  • 6042

【高并发简单解决方案】redis队列缓存 + 批量入库 + php离线整合

需求背景:有个 调用统计日志存储和统计需求 ,要求存储到mysql中;存储数据高峰能达到日均千万,瓶颈在于 直接入库并发太高,可能会把mysql干垮 。 问题分析 思考:应用网站架构的衍化过程中,...
  • l754539910
  • l754539910
  • 2017-02-09 17:20:49
  • 2275

【高并发简单解决方案】redis队列缓存 + mysql 批量入库 + php离线整合 PHP解决抢购、秒杀

【高并发简单解决方案】redis队列缓存 + mysql 批量入库 + php离线整合 https://segmentfault.com/a/1190000004136250 PH...
  • liuxiaojun828
  • liuxiaojun828
  • 2016-07-06 14:49:21
  • 4169

关于phpredis中的connect和pconnect的一些见解

最近看到网上不少误导人的文章,高并发下应该使用pconnect,但是pconnect一定比connect好吗? 下面是我的一些见解,权当抛砖引玉了。 首先说下connect和pconnect的区别...
  • wuxing26jiayou
  • wuxing26jiayou
  • 2017-09-30 17:47:31
  • 374

PHP REDIS 使用长连接多数据库存储到最后一个数据库中的问题解决

在使用redis持久连接时,不同的库存储操作不同的数据,但是存储数据时默认存储到最后一个库了,解决方法在最后风.foxredis connect 短连接 单例模式没有此问题class Connect2...
  • wljk506
  • wljk506
  • 2017-12-01 13:58:23
  • 150

websocket-<em>redis长连接</em>订阅日志频道

<em>PHP</em>中使用<em>Redis长连接</em>笔记 <em>redis</em>三种连接方式 <em>PHP</em>中使用<em>Redis长连接</em>笔记 <em>redis长连接</em>的原理和示例 storm使用<em>redis</em>池与长链接的区别 <em>redis连接</em>过多的一个解决...
  • 2018年04月09日 00:00

redis入门指南 学习笔记(二) Redis的多数据库

Redis是一个字典结构的存储服务器,而实际上一个
  • qian_348840260
  • qian_348840260
  • 2014-05-05 16:05:16
  • 6556

PHP CI框架使用多个数据库

今天在做单元测试时发现要操作远程的数据库,所以就在论坛里找了相关的帖子。但发现问的人挺多的,但回答最多的就是查看手册:http://codeigniter.org.cn/user_guide/data...
  • haogaoming123
  • haogaoming123
  • 2016-07-26 16:20:42
  • 777
收藏助手
不良信息举报
您举报文章:PHP REDIS 使用长连接多数据库存储到最后一个数据库中的问题解决
举报原因:
原因补充:

(最多只允许输入30个字)