1 null,// 只支持一台 Master 18 'slave'=>array(),// 可以有多台 Slave 19 ); 20 21 /** 22 * 构造函数 23 * 24 * @param boolean $isUseCluster 是否采用 M/S 方案 25 */ 26 public function __construct($isUseCluster=false){ 27 $this->_isUseCluster = $isUseCluster; 28 } 29 30 /** 31 * 连接服务器,注意:这里使用长连接,提高效率,但不会自动关闭 32 * 33 * @param array $config Redis服务器配置 34 * @param boolean $isMaster 当前添加的服务器是否为 Master 服务器 35 * @return boolean 36 */ 37 public function connect($config=array('host'=>'127.0.0.1','port'=>6379), $isMaster=true){ 38 // default port 39 if(!isset($config['port'])){ 40 $config['port'] = 6379; 41 } 42 // 设置 Master 连接 43 if($isMaster){ 44 $this->_linkHandle['master'] = new Redis(); 45 $ret = $this->_linkHandle['master']->pconnect($config['host'],$config['port']); 46 }else{ 47 // 多个 Slave 连接 48 $this->_linkHandle['slave'][$this->_sn] = new Redis(); 49 $ret = $this->_linkHandle['slave'][$this->_sn]->pconnect($config['host'],$config['port']); 50 ++$this->_sn; 51 } 52 return $ret; 53 } 54 55 /** 56 * 关闭连接 57 * 58 * @param int $flag 关闭选择 0:关闭 Master 1:关闭 Slave 2:关闭所有 59 * @return boolean 60 */ 61 public function close($flag=2){ 62 switch($flag){ 63 // 关闭 Master 64 case 0: 65 $this->getRedis()->close(); 66 break; 67 // 关闭 Slave 68 case 1: 69 for($i=0; $i<$this->_sn; ++$i){ 70 $this->_linkHandle['slave'][$i]->close(); 71 } 72 break; 73 // 关闭所有 74 case 2: 75 $this->getRedis()->close(); 76 for($i=0; $i<$this->_sn; ++$i){ 77 $this->_linkHandle['slave'][$i]->close(); 78 } 79 break; 80 } 81 return true; 82 } 83 84 /** 85 * 得到 Redis 原始对象可以有更多的操作 86 * 87 * @param boolean $isMaster 返回服务器的类型 true:返回Master false:返回Slave 88 * @param boolean $slaveOne 返回的Slave选择 true:负载均衡随机返回一个Slave选择 false:返回所有的Slave选择 89 * @return redis object 90 */ 91 public function getRedis($isMaster=true,$slaveOne=true){ 92 // 只返回 Master 93 if($isMaster){ 94 return $this->_linkHandle['master']; 95 }else{ 96 return $slaveOne ? $this->_getSlaveRedis() : $this->_linkHandle['slave']; 97 } 98 } 99 100 /**101 * 写缓存102 *103 * @param string $key 组存KEY104 * @param string $value 缓存值105 * @param int $expire 过期时间, 0:表示无过期时间106 */ 107 public function set($key, $value, $expire=0){108 // 永不超时 109 if($expire == 0){110 $ret = $this->getRedis()->set($key, $value);111 }else{112 $ret = $this->getRedis()->setex($key, $expire, $value);113 }114 return $ret;115 }116 117 /**118 * 读缓存119 *120 * @param string $key 缓存KEY,支持一次取多个 $key = array('key1','key2')121 * @return string || boolean 失败返回 false, 成功返回字符串122 */ 123 public function get($key){124 // 是否一次取多个值 125 $func = is_array($key) ? 'mGet' : 'get';126 // 没有使用M/S 127 if(! $this->_isUseCluster){128 return $this->getRedis()->{ $func}($key);129 }130 // 使用了 M/S 131 return $this->_getSlaveRedis()->{ $func}($key);132 }133 134 /**135 * 条件形式设置缓存,如果 key 不存时就设置,存在时设置失败136 *137 * @param string $key 缓存KEY138 * @param string $value 缓存值139 * @return boolean140 */ 141 public function setnx($key, $value){142 return $this->getRedis()->setnx($key, $value);143 }144 145 /**146 * 删除缓存147 *148 * @param string || array $key 缓存KEY,支持单个健:"key1" 或多个健:array('key1','key2')149 * @return int 删除的健的数量150 */ 151 public function remove($key){152 // $key => "key1" || array('key1','key2') 153 return $this->getRedis()->delete($key);154 }155 156 /**157 * 值加加操作,类似 ++$i ,如果 key 不存在时自动设置为 0 后进行加加操作158 *159 * @param string $key 缓存KEY160 * @param int $default 操作时的默认值161 * @return int 操作后的值162 */ 163 public function incr($key,$default=1){164 if($default == 1){165 return $this->getRedis()->incr($key);166 }else{167 return $this->getRedis()->incrBy($key, $default);168 }169 }170 171 /**172 * 值减减操作,类似 --$i ,如果 key 不存在时自动设置为 0 后进行减减操作173 *174 * @param string $key 缓存KEY175 * @param int $default 操作时的默认值176 * @return int 操作后的值177 */ 178 public function decr($key,$default=1){179 if($default == 1){180 return $this->getRedis()->decr($key);181 }else{182 return $this->getRedis()->decrBy($key, $default);183 }184 }185 186 /**187 * 添空当前数据库188 *189 * @return boolean190 */ 191 public function clear(){192 return $this->getRedis()->flushDB();193 }194 195 /* =================== 以下私有方法 =================== */ 196 /**197 * 随机 HASH 得到 Redis Slave 服务器句柄198 *199 * @return redis object200 */ 201 private function _getSlaveRedis(){202 // 就一台 Slave 机直接返回 203 if($this->_sn <= 1){204 return $this->_linkHandle['slave'][0];205 }206 // 随机 Hash 得到 Slave 的句柄 207 $hash = $this->_hashId(mt_rand(), $this->_sn);208 return $this->_linkHandle['slave'][$hash];209 }210 211 /**212 * 根据ID得到 hash 后 0~m-1 之间的值213 *214 * @param string $id215 * @param int $m216 * @return int217 */ 218 private function _hashId($id,$m=10)219 {220 //把字符串K转换为 0~m-1 之间的一个值作为对应记录的散列地址 221 $k = md5($id);222 $l = strlen($k);223 $b = bin2hex($k);224 $h = 0;225 for($i=0;$i<$l;$i++)226 {227 //相加模式HASH 228 $h += substr($b,$i*2,2);229 }230 $hash = ($h*1)%$m;231 return $hash;232 }233 234 }// End Class235 236 // ================= TEST DEMO =================237 238 // 只有一台 Redis 的应用$redis = new RedisCluster();$redis->connect(array('host'=>'127.0.0.1','port'=>6379));$redis->set('id',35);var_dump($redis->get('id'));239 240 // 有一台 Master 和 多台Slave 的集群应用$redis = new RedisCluster(true);$redis->connect(array('host'=>'127.0.0.1','port'=>6379), true);// master$redis->connect(array('host'=>'127.0.0.1','port'=>63791), false);// slave 1$redis->connect(array('host'=>'127.0.0.1','port'=>63792), false);// slave 2$redis->set('id',100);for($i=1; $i<=100; ++$i){ 241 var_dump($redis->get('id')).PHP_EOL;242 }243 // phpRedis 扩展的更多高级操作$redis = new RedisCluster();$redis->connect(array('host'=>'127.0.0.1','port'=>6379));$ret = $redis->getRedis()->ping();// phpRedis 原始APIvar_dump($ret);