标签:
$array = array(
‘master‘ => array(
"redis://127.0.0.1:6379?timeout=1",
),
‘slave‘ => array(
"redis://127.0.0.1:6479?timeout=1",
"redis://127.0.0.1:6579?timeout=1",
)
);
$redis = RedisServer::instance($array);
$redis->set("aaaa","aaaa") //将会把数据缓存到.127.0.0.1:6379中
$redis->get("aaaa")//将会用127.0.0.1:6479或者127.0.0.1:6579中读取.从而实现读写分离
1 <?php 2 3 4 /** 5 * redis负载均衡 6 * 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * 9 * $array = array( 10 * ‘master‘ => array( 11 * "redis://127.0.0.1:6379?timeout=1", 12 * ), 13 * ‘slave‘ => array( 14 * "redis://127.0.0.1:6479?timeout=1", 15 * "redis://127.0.0.1:6579?timeout=1", 16 * ) 17 * ); 18 * 19 * $redis = RedisServer::instance($array); 20 * $redis->set("aaaa","aaaa") //将会把数据缓存到.127.0.0.1:6379中 21 * $redis->get("aaaa")//将会用127.0.0.1:6479或者127.0.0.1:6579中读取.从而实现读写分离 22 * 23 * 24 * 25 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 26 * 27 * 如果本类报找不到方法.但是redis中存在改方法.请在列成员$methodMap中加入对应的方法.如果是缓存数据.设置为true,读取数据.设置为false 28 * 29 * 30 * 31 * Class RedisServer 32 * @author 136045277#qq.com 33 */ 34 class RedisServer 35 { 36 private static $masterServers = array(); 37 private static $slaveServers = array(); 38 39 private static $masterLength = 0; 40 private static $slaveLength = 0; 41 42 43 private static $serverConfigs = array(); 44 private static $dbIndex = null; 45 private static $instance = null; 46 47 48 private static $prohibitMap = array( 49 ‘slaveof‘, ‘config‘ 50 ); 51 52 53 private static $methodMap = array ( 54 ‘del‘ => true, 55 ‘set‘ => true, 56 ‘get‘ => false, 57 ‘ttl‘ => false, 58 ‘hget‘ => false, 59 ‘incr‘ => true, 60 ‘lpop‘ => true, 61 ‘rpop‘ => true, 62 ‘spop‘ => true, 63 ‘decr‘ => true, 64 ‘ping‘ => true, 65 ‘info‘ => false, 66 ‘type‘ => false, 67 ‘hlen‘ => false, 68 ‘sadd‘ => true, 69 ‘keys‘ => false, 70 ‘mset‘ => true, 71 ‘exec‘ => true, 72 ‘hdel‘ => true, 73 ‘auth‘ => true, 74 ‘srem‘ => true, 75 ‘hset‘ => true, 76 ‘zrem‘ => true, 77 ‘scan‘ => false, 78 ‘dump‘ => false, 79 ‘zset‘ => true, 80 ‘move‘ => true, 81 ‘save‘ => true, 82 ‘lrem‘ => true, 83 ‘lset‘ => true, 84 ‘lget‘ => false, 85 ‘sort‘ => false, 86 ‘hmget‘ => false, 87 ‘ltrim‘ => true, 88 ‘hvals‘ => false, 89 ‘hkeys‘ => false, 90 ‘brpop‘ => true, 91 ‘lpush‘ => true, 92 ‘rpush‘ => true, 93 ‘smove‘ => true, 94 ‘setex‘ => true, 95 ‘watch‘ => true, 96 ‘multi‘ => true, 97 ‘bitop‘ => true, 98 ‘setnx‘ => true, 99 ‘zrank‘ => false, 100 ‘sscan‘ => false, 101 ‘hscan‘ => false, 102 ‘scard‘ => false, 103 ‘hmset‘ => true, 104 ‘zsize‘ => false, 105 ‘ssize‘ => false, 106 ‘lsize‘ => false, 107 ‘zscan‘ => false, 108 ‘blpop‘ => true, 109 ‘sdiff‘ => false, 110 ‘zcard‘ => false, 111 ‘exists‘ => false, 112 ‘zrange‘ => false, 113 ‘lindex‘ => false, 114 ‘getbit‘ => false, 115 ‘sunion‘ => false, 116 ‘sinter‘ => false, 117 ‘strlen‘ => false, 118 ‘decrby‘ => true, 119 ‘object‘ => false, 120 ‘incrby‘ => true, 121 ‘zinter‘ => true, 122 ‘getset‘ => true, 123 ‘lrange‘ => true, 124 ‘append‘ => true, 125 ‘lpushx‘ => true, 126 ‘zscore‘ => false, 127 ‘dbsize‘ => false, 128 ‘zcount‘ => false, 129 ‘zunion‘ => true, 130 ‘expire‘ => true, 131 ‘config‘ => true, 132 ‘rename‘ => true, 133 ‘setbit‘ => true, 134 ‘delete‘ => true, 135 ‘zincrby‘ => true, 136 ‘lremove‘ => true, 137 ‘sremove‘ => true, 138 ‘linsert‘ => true, 139 ‘hincrby‘ => true, 140 ‘flushdb‘ => true, 141 ‘migrate‘ => true, 142 ‘hgetall‘ => false, 143 ‘unwatch‘ => true, 144 ‘hexists‘ => false, 145 ‘zdelete‘ => false, 146 ‘discard‘ => true, 147 ‘getkeys‘ => false, 148 ‘persist‘ => true, 149 ‘setrange‘ => true, 150 ‘renamenx‘ => true, 151 ‘getrange‘ => false, 152 ‘bitcount‘ => false, 153 ‘smembers‘ => true, 154 ‘expireat‘ => true, 155 ‘lastsave‘ => true, 156 ‘listtrim‘ => true, 157 ‘flushall‘ => true, 158 ‘zrevrank‘ => false, 159 ‘sismember‘ => false, 160 ‘zrevrange‘ => false, 161 ‘randomkey‘ => false, 162 ‘rpoplpush‘ => true, 163 ‘scontains‘ => false, 164 ‘lgetrange‘ => false, 165 ‘renamekey‘ => true, 166 ‘sdiffstore‘ => true, 167 ‘settimeout‘ => true, 168 ‘sgetmembers‘ => true, 169 ‘sinterstore‘ => true, 170 ‘srandmember‘ => false, 171 ‘sunionstore‘ => true, 172 ‘getmultiple‘ => false, 173 ‘bgrewriteaof‘ => true, 174 ‘zrangebyscore‘ => false, 175 ‘zrevrangebyscore‘ => false, 176 ‘zremrangebyscore‘ => true, 177 ‘zdeleterangebyscore‘ => true, 178 ); 179 180 181 182 private function __construct() 183 { 184 } 185 186 /** 187 * redis初始化 188 * 配置 189 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 190 * 191 * $array = array( 192 * ‘master‘ => array( 193 * "redis://127.0.0.1:6379?timeout=1", 194 * ), 195 * ‘slave‘ => array( 196 * "redis://127.0.0.1:6479?timeout=1", 197 * "redis://127.0.0.1:6579?timeout=1", 198 * ) 199 * ); 200 * 201 * $redis = RedisServer::instance($array); 202 * 203 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 204 * 205 * 206 * 207 * @param array $configs 208 * @return null|RedisServer 209 */ 210 public static function instance(array $configs) 211 { 212 if (self::$instance === null) { 213 self::$instance = new self(); 214 foreach ($configs[‘master‘] as $master) { 215 $connect = self::$instance->parseStr($master); 216 self::$instance->addMaster($connect[0], $connect[1], $connect[2]); 217 } 218 foreach ($configs[‘slave‘] as $master) { 219 $connect = self::$instance->parseStr($master); 220 self::$instance->addSlave($connect[0], $connect[1], $connect[2]); 221 } 222 } 223 return self::$instance; 224 } 225 226 227 private function parseStr($string) 228 { 229 $urls = parse_url($string); 230 $array[] = $urls[‘host‘]; 231 $array[] = isset($urls[‘port‘]) ? $urls[‘port‘] : 6379; 232 $array[] = 1; 233 return $array; 234 } 235 236 237 public function addMaster($host, $port = 6379, $timeout = 0.0) 238 { 239 self::$masterLength++; 240 self::$serverConfigs[‘master‘][] = [$host, $port, $timeout]; 241 } 242 243 public function addSlave($host, $port = 6379, $timeout = 0.0) 244 { 245 self::$slaveLength++; 246 self::$serverConfigs[‘slave‘][] = [$host, $port, $timeout]; 247 } 248 249 250 /** 251 * @param null $key 252 * @param bool|true $isMaster 253 * @return \Redis 254 */ 255 protected function getRedis($key = null, $isMaster = true) 256 { 257 empty($key) && $key = uniqid(true); 258 list($length, $server) = $isMaster ? [self::$masterLength, &self::$masterServers] : [self::$slaveLength, &self::$slaveServers]; 259 $index = $this->getHostByHash($key, $length); 260 if (!isset($server[$index])) { 261 $connect = $isMaster ? self::$serverConfigs[‘master‘][$index] : self::$serverConfigs[‘slave‘][$index]; 262 $server[$index] = new \Redis(); 263 $server[$index]->connect($connect[0], $connect[1], $connect[2]); 264 if (self::$dbIndex !== null) { 265 $server[$index]->select($index); 266 } 267 /*if (!$isMaster) { 268 $server[$index]->slaveof(self::$serverConfigs[‘master‘][0][0], self::$serverConfigs[‘master‘][0][1]); 269 }*/ 270 } 271 return $server[$index]; 272 } 273 274 275 private function getHostByHash($key, $n) 276 { 277 if ($n < 2) return 0; 278 $id = sprintf("%u", crc32($key)); 279 $m = base_convert(intval(fmod($id, $n)), 10, $n); 280 return $m{0}; 281 } 282 283 284 public function __call($method, $args) 285 { 286 if (in_array(strtolower($method), self::$prohibitMap)) { 287 $this->prohibit($method); 288 } elseif (isset(self::$methodMap[strtolower($method)])) { 289 return call_user_func_array(array($this->getRedis(null, self::$methodMap[strtolower($method)]), $method), $args); 290 } 291 trigger_error("Call to undefined method " . __CLASS__ . "::{$method}() ", E_USER_ERROR); 292 } 293 294 295 /** 296 * 禁用slaveof方法 297 */ 298 private function prohibit($method) 299 { 300 trigger_error("Call to prohibit access method " . __CLASS__ . "::{$method}() ", E_USER_ERROR); 301 } 302 303 304 public function select($dbIndex) 305 { 306 foreach (self::$masterServers as &$master) { 307 $master->select($dbIndex); 308 } 309 unset($master); 310 foreach (self::$slaveServers as &$slave) { 311 $slave->select($dbIndex); 312 } 313 self::$dbIndex = $dbIndex; 314 unset($slave); 315 } 316 317 318 }
标签:
原文地址:http://www.cnblogs.com/iyoule/p/5036456.html