欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

php redis 读写分离类,yii实现redis读写分离

发布时间:2023/12/19 39 豆豆
生活随笔 收集整理的这篇文章主要介绍了 php redis 读写分离类,yii实现redis读写分离 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

/**

* FileName:RedisCluster

* 配置说明

* 配置为1主多从 或者 1个独立的服务器

* 写往主的里面写

* 读是从从的里面读

* 'class'=>'RedisCache',

* 'servers'=>array(

* array(

* 'host'=>'IP1',

* 'port'=>'6380',

* 'master'=>true //主机

* ),

* array(

* 'host'=>'IP2',

* 'port'=>'6381'

* )

*

* 单独

* 'class'=>'RedisCache',

* 'servers'=>array(

* array(

* 'host'=>'IP1',

* 'port'=>'6380',

* ),

* @author zhonghailin

* @version v1.0

* @since v1.0

* @Date 2015-3-10 下午4:57:02

*/

class ERedisCache extends CCache{

// 是否使用 M/S 的读写集群方案

private $_isUseCluster = false;

// Slave 句柄标记

private $_sn = 0;

// 服务器连接句柄

private $_linkHandle = array(

'master'=>null,// 只支持一台 Master

'slave'=>array(),// 可以有多台 Slave

);

//配置文件

private $_servers=array();

/**

* 构造函数

*

* @param boolean $isUseCluster 是否采用 M/S 方案

*/

/*

* 初始化

*/

public function init()

{

$this->keyPrefix = "";

parent::init();

if(is_array($this->_servers)){

foreach($this->_servers as $servers){

if($servers->master){

$this->_isUseCluster = true;//如果设置了主服务器那么就是1主多从

$this->connect($servers,true);

}else{

$this->connect($servers);

}

}

}

}

/**

* @return array list of memcache server configurations. Each element is a {@link CMemCacheServerConfiguration}.

*/

public function getServers()

{

return $this->_servers;

}

/**

* @param array $config list of memcache server configurations. Each element must be an array

* with the following keys: host, port, persistent, weight, timeout, retryInterval, status.

* @see http://www.php.net/manual/en/function.Memcache-addServer.php

*/

public function setServers($config)

{

foreach($config as $c)

$this->_servers[]=new CRedisServerConfiguration($c);

}

/**

* 连接服务器,注意:这里使用长连接,提高效率,但不会自动关闭

*

* @param array $config Redis服务器配置

* @param boolean $isMaster 当前添加的服务器是否为 Master 服务器

* @return boolean

*/

public function connect($config, $isMaster=false){

// default port

if(!isset($config->port)){

$config->port = 6379;

}

// 设置 Master 连接

if($isMaster){

$this->_linkHandle['master'] = new Redis();

$ret = $this->_linkHandle['master']->pconnect($config->host,$config->port);

}else{

// 多个 Slave 连接

$this->_linkHandle['slave'][$this->_sn] = new Redis();

$ret = $this->_linkHandle['slave'][$this->_sn]->pconnect($config->host,$config->port);

++$this->_sn;

}

return $ret;

}

/**

* 关闭连接

*

* @param int $flag 关闭选择 0:关闭 Master 1:关闭 Slave 2:关闭所有

* @return boolean

*/

public function close($flag=2){

switch($flag){

// 关闭 Master

case 0:

$this->getRedis()->close();

break;

// 关闭 Slave

case 1:

for($i=0; $i_sn; ++$i){

$this->_linkHandle['slave'][$i]->close();

}

break;

// 关闭所有

case 2:

if(!empty( $this->_linkHandle['master'])){

$this->_linkHandle['master']->close();

}

for($i=0; $i_sn; ++$i){

$this->_linkHandle['slave'][$i]->close();

}

break;

}

return true;

}

/**

* 得到 Redis 原始对象可以有更多的操作

*

* @param boolean $isMaster 返回服务器的类型 true:返回Master false:返回Slave

* @param boolean $slaveOne 返回的Slave选择 true:负载均衡随机返回一个Slave选择 false:返回所有的Slave选择

* @return redis object

*/

public function getRedis($isMaster=true,$slaveOne=true){

// 只返回 Master

if($isMaster){

return $this->_linkHandle['master'];

}else{

return $slaveOne ? $this->_getSlaveRedis() : $this->_linkHandle['slave'];

}

}

/**

* 写缓存

*

* @param string $key 组存KEY

* @param string $value 缓存值

* @param int $expire 过期时间, 0:表示无过期时间

*/

public function setValue($key, $value, $expire=0){

// 永不超时

if($expire == 0){

if($this->_isUseCluster){

$ret = $this->getRedis()->set($key, $value);

}else{

$ret = $this->getRedis(false)->set($key, $value);

}

}else{

if($this->_isUseCluster){

$ret = $this->getRedis()->setex($key, $expire, $value);

}else{

$ret = $this->getRedis(false)->setex($key, $expire, $value);

}

}

return $ret;

}

/**

* 读缓存

*

* @param string $key 缓存KEY,支持一次取多个 $key = array('key1','key2')

* @return string || boolean 失败返回 false, 成功返回字符串

*/

public function getValue($key){

// 是否一次取多个值

$func = is_array($key) ? 'mGet' : 'get';

// 使用了 M/S

return $this->_getSlaveRedis()->{$func}($key);

}

/**

* 条件形式设置缓存,如果 key 不存时就设置,存在时设置失败

*

* @param string $key 缓存KEY

* @param string $value 缓存值

* @return boolean

*/

public function setnx($key, $value){

if($this->_isUseCluster){

return $this->getRedis()->setnx($key, $value);

}else{

return $this->getRedis(false)->setnx($key, $value);

}

}

/**

* 删除缓存

*

* @param string || array $key 缓存KEY,支持单个健:"key1" 或多个健:array('key1','key2')

* @return int 删除的健的数量

*/

public function remove($key){

if($this->_isUseCluster){

return $this->getRedis()->delete($key);

}else{

return $this->getRedis(false)->delete($key);

}

}

/* (non-PHPdoc)

* @see BaseCache::delete()

*/

public function deleteValue($key){

if($this->_isUseCluster){

return $this->getRedis()->delete($key);

}else{

return $this->getRedis(false)->delete($key);

}

}

/**

* 值加加操作,类似 ++$i ,如果 key 不存在时自动设置为 0 后进行加加操作

*

* @param string $key 缓存KEY

* @param int $default 操作时的默认值

* @return int 操作后的值

*/

public function incr($key,$default=1){

if($default == 1){

return $this->getRedis()->incr($key);

}else{

return $this->getRedis()->incrBy($key, $default);

}

}

/**

* 值减减操作,类似 --$i ,如果 key 不存在时自动设置为 0 后进行减减操作

*

* @param string $key 缓存KEY

* @param int $default 操作时的默认值

* @return int 操作后的值

*/

public function decr($key,$default=1){

if($default == 1){

return $this->getRedis()->decr($key);

}else{

return $this->getRedis()->decrBy($key, $default);

}

}

/**

* 添空当前数据库

*

* @return boolean

*/

public function clear(){

if(!empty( $this->_linkHandle['master'])){

$this->_linkHandle['master']->flushDB();

}

for($i=0; $i_sn; ++$i){

$this->_linkHandle['slave'][$i]->flushDB();

}

return true;

}

/* =================== 以下私有方法 =================== */

/**

* 随机 HASH 得到 Redis Slave 服务器句柄

*

* @return redis object

*/

private function _getSlaveRedis(){

// 就一台 Slave 机直接返回

if($this->_sn <= 1){

return $this->_linkHandle['slave'][0];

}

// 随机 Hash 得到 Slave 的句柄

$hash = $this->_hashId(mt_rand(), $this->_sn);

return $this->_linkHandle['slave'][$hash];

}

/**

* 根据ID得到 hash 后 0~m-1 之间的值

*

* @param string $id

* @param int $m

* @return int

*/

private function _hashId($id,$m=10)

{

//把字符串K转换为 0~m-1 之间的一个值作为对应记录的散列地址

$k = md5($id);

$l = strlen($k);

$b = bin2hex($k);

$h = 0;

for($i=0;$i$value)

$this->$key=$value;

if($this->host===null)

throw new CException(Yii::t('yii','CMemCache server configuration must have "host" value.'));

}

else

throw new CException(Yii::t('yii','CMemCache server configuration must be an array.'));

}

}

总结

以上是生活随笔为你收集整理的php redis 读写分离类,yii实现redis读写分离的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。