PHP Redis 集群封装类
生活随笔
收集整理的這篇文章主要介紹了
PHP Redis 集群封装类
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
<?php /** ?* Redis 操作,支持 Master/Slave 的負載集群 ?* ?* @author V哥 ?*/ class RedisCluster{ ?? ? ? // 是否使用 M/S 的讀寫集群方案 ? ? private $_iSUSECluster = false; ?? ? ? // Slave 句柄標記 ? ? private $_sn = 0; ?? ? ? // 服務器連接句柄 ? ? private $_linkHandle = array( ? ? ? ? 'master'=>null,// 只支持一臺 Master ? ? ? ? 'slave'=>array(),// 可以有多臺 Slave ? ? ); ?? ? ? /** ? ? ?* 構造函數 ? ? ?* ? ? ?* @param boolean $isUseCluster 是否采用 M/S 方案 ? ? ?*/ ? ? public function __construct($isUseCluster=false){ ? ? ? ? $this->_isUseCluster = $isUseCluster; ? ? } ?? ? ? /** ? ? ?* 連接服務器,注意:這里使用長連接,提高效率,但不會自動關閉 ? ? ?* ? ? ?* @param array $config Redis服務器配置 ? ? ?* @param boolean $isMaster 當前添加的服務器是否為 Master 服務器 ? ? ?* @return boolean ? ? ?*/ ? ? public function connect($config=array('host'=>'127.0.0.1','port'=>6379), $isMaster=true){ ? ? ? ? // 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<$this->_sn; ++$i){ ? ? ? ? ? ? ? ? ? ? $this->_linkHandle['slave'][$i]->close(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? break; ? ? ? ? ? ? // 關閉所有 ? ? ? ? ? ? case 1: ? ? ? ? ? ? ? ? $this->getRedis()->close(); ? ? ? ? ? ? ? ? for($i=0; $i<$this->_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 set($key, $value, $expire=0){ ? ? ? ? // 永不超時 ? ? ? ? if($expire == 0){ ? ? ? ? ? ? $ret = $this->getRedis()->set($key, $value); ? ? ? ? }else{ ? ? ? ? ? ? $ret = $this->getRedis()->setex($key, $expire, $value); ? ? ? ? } ? ? ? ? return $ret; ? ? } ?? ? ? /** ? ? ?* 讀緩存 ? ? ?* ? ? ?* @param string $key 緩存KEY,支持一次取多個 $key = array('key1','key2') ? ? ?* @return string || boolean? 失敗返回 false, 成功返回字符串 ? ? ?*/ ? ? public function get($key){ ? ? ? ? // 是否一次取多個值 ? ? ? ? $func = is_array($key) ? 'mGet' : 'get'; ? ? ? ? // 沒有使用M/S ? ? ? ? if(! $this->_isUseCluster){ ? ? ? ? ? ? return $this->getRedis()->{$func}($key); ? ? ? ? } ? ? ? ? // 使用了 M/S ? ? ? ? return $this->_getSlaveRedis()->{$func}($key); ? ? } ?? ? ? /** ? ? ?* 條件形式設置緩存,如果 key 不存時就設置,存在時設置失敗 ? ? ?* ? ? ?* @param string $key 緩存KEY ? ? ?* @param string $value 緩存值 ? ? ?* @return boolean ? ? ?*/ ? ? public function setnx($key, $value){ ? ? ? ? return $this->getRedis()->setnx($key, $value); ? ? } ?? ? ? /** ? ? ?* 刪除緩存 ? ? ?* ? ? ?* @param string || array $key 緩存KEY,支持單個健:"key1" 或多個健:array('key1','key2') ? ? ?* @return int 刪除的健的數量 ? ? ?*/ ? ? public function remove($key){ ? ? ? ? // $key => "key1" || array('key1','key2') ? ? ? ? return $this->getRedis()->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(){ ? ? ? ? return $this->getRedis()->flushDB(); ? ? } ?? ? ? /* =================== 以下私有方法 =================== */ ?? ? ? /** ? ? ?* 隨機 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<$l;$i++) ? ? ? ? { ? ? ? ? ? ? //相加模式HASH ? ? ? ? ? ? $h += substr($b,$i*2,2); ? ? ? ? } ? ? ? ? $hash = ($h*1)%$m; ? ? ? ? return $hash; ? ? } ?? }// End Class ?? // ================= TEST DEMO ================= ?? // 只有一臺 Redis 的應用 $redis = new RedisCluster(); $redis->connect(array('host'=>'127.0.0.1','port'=>6379)); $redis->set('id',35); var_dump($redis->get('id')); ?? // 有一臺 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){ ? ? var_dump($redis->get('id')).PHP_EOL; } ?? // phpRedis 擴展的更多高級操作 $redis = new RedisCluster(); $redis->connect(array('host'=>'127.0.0.1','port'=>6379)); $ret = $redis->getRedis()->ping();// phpRedis 原始API var_dump($ret);
轉載于:https://www.cnblogs.com/Mwsoft/p/5175231.html
總結
以上是生活随笔為你收集整理的PHP Redis 集群封装类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx的页面中文乱码解决方法
- 下一篇: oracle11g安装成功