/**

* 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读写分离相关推荐

  1. 分享一个nodejs中koa操作redis的工具类 基于 ioredis

    分享一个node 操作redis的工具类 基于ioredis redis.js const config = require(':config/server.base.config'); const ...

  2. Redis学习笔记~是时候为Redis实现一个仓储了,RedisRepository来了

    回到目录 之前写了不少关于仓储的文章,所以,自己习惯把自己叫仓储大叔,上次写的XMLRepository得到了大家的好评,也有不少朋友给我发email,进行一些知识的探讨,今天主要来实现一个Redis ...

  3. Linux企业运维 6.6 -- Redis部署及主从切换、Redis+Mysql读写分离

    目录 Redis简介 redis的编译.安装 1.server1的redis配置 2.server2的redis安装 3.server3配置redis 三.redis主从复制 四.Sentine主从自 ...

  4. MySQL与Redis数据库结合——redis作为mysql的缓存服务器,实现读写分离(nginx+php+redis+mysql)

    文章目录 一.读写分离的背景 二.搭建nginx+php+redis+mysql 实验环境 实验 1.在server1上安装nginx+php 建立php和redis,mysql的连接 2.在serv ...

  5. 存算分离架构的高斯Redis,用强一致提供可靠保障

    摘要:其实开源Redis的弱一致性已经不满足很多应用场景的诉求.怎么,不信? 本文分享自华为云社区<华为云企业级Redis揭秘第15期:Redis为什么需要强一致?>,作者: GaussD ...

  6. C#中Redis封装的类

    强烈推荐一个大神的人工智能的教程:http://www.captainbed.net/zhanghan [前言] 上两篇博文为大家分享<SCPPO:Redis简介>和<SCPPO:W ...

  7. Redis基础(思维导图)附Redis工具类

    Redis 1.什么是Redis NoSql数据库 分布式缓存中间件 key-value存储 提供海量数据存储访问 数据存储在内存里,读取更快 2.缓存方案对比 缓存方案 优点 缺点 Ehcache ...

  8. SpringBoot中操作spring redis的工具类

    场景 SpringBoot+Vue+Redis实现前后端分离的字典缓存机制: https://blog.csdn.net/badao_liumang_qizhi/article/details/108 ...

  9. java redis remove_最全的Java操作Redis的工具类

    RedisUtil 当前版本:1.1 增加更全的方法,对以前的部分方法进行了规范命名,请放心替换成新版本. 介绍 最全的Java操作Redis的工具类,使用StringRedisTemplate实现, ...

最新文章

  1. 未来科技 HoloLens演示3D地理信息系统
  2. github 创建新项目
  3. Database之SQLSever:SQL命令实现查询之多表查询、嵌套查询、分页复杂查询,删除表内重复记录数据、连接(join、left join和right join简介及其区别)等案例之详细攻略
  4. 网络安全-配置dns服务器
  5. 微信浏览器的html5页面显示配置等问题汇集 1,禁止微信浏览器分享页面链接 (定点更新)...
  6. mysql32位主从复制安装包,MySQL安装-主从复制(5)
  7. WPF 实现水纹效果
  8. LeetCode 1429. 第一个唯一数字(map+queue)
  9. TCP协议以及三次握手
  10. php h5读写数据库,H5学习_番外篇_PHP数据库操作
  11. 01.Elasticsearch安装
  12. 磁盘类型 GetDriveType
  13. 结构体中的LNode与*LinkList
  14. iOS可持续化集成: Jenkins + bundler + cocoapods + shenzhen + fastlane + pgyer
  15. Android应用内存管理机制
  16. ViewportWidth,Width,MeasuredWidth
  17. MISC解题思路总结(一)XCTF平台
  18. Godaddy子域名转向外部IP地址设置
  19. 华唯鑫能油的推荐每日一练|你知道的液体燃料有哪些?
  20. 模电笔记二(第一章第二小节)

热门文章

  1. 一份我们团队Java开发的开发规范,参考了阿里巴巴Java开发手册终极版v1.3.0
  2. SAP CRM Cross Component级别的跳转如果出了问题,该如何调试
  3. SpringBoot启动时就会自动去连接mongdo DB指向的url
  4. 从SAP Leonardo到SAP Data Intelligence
  5. SAP Hybris和Netweaver的租户隔离(Tenant isolation)机制设计
  6. 推荐一个能监控安卓手机上应用使用情况的应用,名叫ActionDash
  7. 如何使用SAP UI5 Web Component for React的padding功能
  8. SAP CRM WebClient UI的on_new_focus应该怎么理解
  9. Text store debug FM CRM_TEXT_MAINTAIN_OW
  10. 阮一峰react demo代码研究的学习笔记 - how is h1 got parsed - not answer