$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中读取.从而实现读写分离
 <?php

 /**
* redis负载均衡
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* $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中读取.从而实现读写分离
*
*
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 如果本类报找不到方法.但是redis中存在改方法.请在列成员$methodMap中加入对应的方法.如果是缓存数据.设置为true,读取数据.设置为false
*
*
*
* Class RedisServer
* @author 136045277#qq.com
*/
class RedisServer
{
private static $masterServers = array();
private static $slaveServers = array(); private static $masterLength = 0;
private static $slaveLength = 0; private static $serverConfigs = array();
private static $dbIndex = null;
private static $instance = null; private static $prohibitMap = array(
'slaveof', 'config'
); private static $methodMap = array (
'del' => true,
'set' => true,
'get' => false,
'ttl' => false,
'hget' => false,
'incr' => true,
'lpop' => true,
'rpop' => true,
'spop' => true,
'decr' => true,
'ping' => true,
'info' => false,
'type' => false,
'hlen' => false,
'sadd' => true,
'keys' => false,
'mset' => true,
'exec' => true,
'hdel' => true,
'auth' => true,
'srem' => true,
'hset' => true,
'zrem' => true,
'scan' => false,
'dump' => false,
'zset' => true,
'move' => true,
'save' => true,
'lrem' => true,
'lset' => true,
'lget' => false,
'sort' => false,
'hmget' => false,
'ltrim' => true,
'hvals' => false,
'hkeys' => false,
'brpop' => true,
'lpush' => true,
'rpush' => true,
'smove' => true,
'setex' => true,
'watch' => true,
'multi' => true,
'bitop' => true,
'setnx' => true,
'zrank' => false,
'sscan' => false,
'hscan' => false,
'scard' => false,
'hmset' => true,
'zsize' => false,
'ssize' => false,
'lsize' => false,
'zscan' => false,
'blpop' => true,
'sdiff' => false,
'zcard' => false,
'exists' => false,
'zrange' => false,
'lindex' => false,
'getbit' => false,
'sunion' => false,
'sinter' => false,
'strlen' => false,
'decrby' => true,
'object' => false,
'incrby' => true,
'zinter' => true,
'getset' => true,
'lrange' => true,
'append' => true,
'lpushx' => true,
'zscore' => false,
'dbsize' => false,
'zcount' => false,
'zunion' => true,
'expire' => true,
'config' => true,
'rename' => true,
'setbit' => true,
'delete' => true,
'zincrby' => true,
'lremove' => true,
'sremove' => true,
'linsert' => true,
'hincrby' => true,
'flushdb' => true,
'migrate' => true,
'hgetall' => false,
'unwatch' => true,
'hexists' => false,
'zdelete' => false,
'discard' => true,
'getkeys' => false,
'persist' => true,
'setrange' => true,
'renamenx' => true,
'getrange' => false,
'bitcount' => false,
'smembers' => true,
'expireat' => true,
'lastsave' => true,
'listtrim' => true,
'flushall' => true,
'zrevrank' => false,
'sismember' => false,
'zrevrange' => false,
'randomkey' => false,
'rpoplpush' => true,
'scontains' => false,
'lgetrange' => false,
'renamekey' => true,
'sdiffstore' => true,
'settimeout' => true,
'sgetmembers' => true,
'sinterstore' => true,
'srandmember' => false,
'sunionstore' => true,
'getmultiple' => false,
'bgrewriteaof' => true,
'zrangebyscore' => false,
'zrevrangebyscore' => false,
'zremrangebyscore' => true,
'zdeleterangebyscore' => true,
); private function __construct()
{
} /**
* redis初始化
* 配置
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* $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);
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*
*
* @param array $configs
* @return null|RedisServer
*/
public static function instance(array $configs)
{
if (self::$instance === null) {
self::$instance = new self();
foreach ($configs['master'] as $master) {
$connect = self::$instance->parseStr($master);
self::$instance->addMaster($connect[0], $connect[1], $connect[2]);
}
foreach ($configs['slave'] as $master) {
$connect = self::$instance->parseStr($master);
self::$instance->addSlave($connect[0], $connect[1], $connect[2]);
}
}
return self::$instance;
} private function parseStr($string)
{
$urls = parse_url($string);
$array[] = $urls['host'];
$array[] = isset($urls['port']) ? $urls['port'] : 6379;
$array[] = 1;
return $array;
} public function addMaster($host, $port = 6379, $timeout = 0.0)
{
self::$masterLength++;
self::$serverConfigs['master'][] = [$host, $port, $timeout];
} public function addSlave($host, $port = 6379, $timeout = 0.0)
{
self::$slaveLength++;
self::$serverConfigs['slave'][] = [$host, $port, $timeout];
} /**
* @param null $key
* @param bool|true $isMaster
* @return \Redis
*/
protected function getRedis($key = null, $isMaster = true)
{
empty($key) && $key = uniqid(true);
list($length, $server) = $isMaster ? [self::$masterLength, &self::$masterServers] : [self::$slaveLength, &self::$slaveServers];
$index = $this->getHostByHash($key, $length);
if (!isset($server[$index])) {
$connect = $isMaster ? self::$serverConfigs['master'][$index] : self::$serverConfigs['slave'][$index];
$server[$index] = new \Redis();
$server[$index]->connect($connect[0], $connect[1], $connect[2]);
if (self::$dbIndex !== null) {
$server[$index]->select($index);
}
/*if (!$isMaster) {
$server[$index]->slaveof(self::$serverConfigs['master'][0][0], self::$serverConfigs['master'][0][1]);
}*/
}
return $server[$index];
} private function getHostByHash($key, $n)
{
if ($n < 2) return 0;
$id = sprintf("%u", crc32($key));
$m = base_convert(intval(fmod($id, $n)), 10, $n);
return $m{0};
} public function __call($method, $args)
{
if (in_array(strtolower($method), self::$prohibitMap)) {
$this->prohibit($method);
} elseif (isset(self::$methodMap[strtolower($method)])) {
return call_user_func_array(array($this->getRedis(null, self::$methodMap[strtolower($method)]), $method), $args);
}
trigger_error("Call to undefined method " . __CLASS__ . "::{$method}() ", E_USER_ERROR);
} /**
* 禁用slaveof方法
*/
private function prohibit($method)
{
trigger_error("Call to prohibit access method " . __CLASS__ . "::{$method}() ", E_USER_ERROR);
} public function select($dbIndex)
{
foreach (self::$masterServers as &$master) {
$master->select($dbIndex);
}
unset($master);
foreach (self::$slaveServers as &$slave) {
$slave->select($dbIndex);
}
self::$dbIndex = $dbIndex;
unset($slave);
} }

php封装redis负载均衡类的更多相关文章

  1. net core 实战之 redis 负载均衡和"高可用"实现

    net core 实战之 redis 负载均衡和"高可用"实现 1.概述 分布式系统缓存已经变得不可或缺,本文主要阐述如何实现redis主从复制集群的负载均衡,以及 redis的& ...

  2. nginx+tomcat+redis负载均衡及session共享

    概述 本文档是用来详细描述 nginx+tomcat+redis负载均衡实现session共享 所需软件及下载地址 软件名称 下载地址 功能说明 Nginx-v1.6.0 http://nginx.o ...

  3. asp.net core 实战之 redis 负载均衡和"高可用"实现

    1.概述 分布式系统缓存已经变得不可或缺,本文主要阐述如何实现redis主从复制集群的负载均衡,以及 redis的"高可用"实现, 呵呵双引号的"高可用"并不是 ...

  4. nginx之 nginx + tomcat + redis 负载均衡且session一致性

    说明: 本文描述的是 nginx + tomcat + redis 实现应用负载均衡且满足session一致性,从安装到配置的全部过程,供大家学习!nginx 代理服务器ip: 10.219.24.2 ...

  5. redis 负载均衡 集群配置

    redis 官网 http://redis.io/ 中文网站 http://redis.cn/ 谷歌代码的redis项目 https://code.google.com/p/redis/ http:/ ...

  6. PHP redis负载均衡代码

    <?php /** * This is a Redis exntend class * jay.w */ class RedisClient { public static $instance ...

  7. Spring Cloud(Dalston.SR5)--Ribbon 中间层负载均衡

    Spring Cloud 集成了 Ribbon 并结合 Eureka 可以实现客户端的负载均衡,使用 @LoadBalanced 修饰的 RestTemplate 类拥有了负载均衡功能,在 Sprin ...

  8. 学习一下 SpringCloud (三)-- 服务调用、负载均衡 Ribbon、OpenFeign

    (1) 相关博文地址: 学习一下 SpringCloud (一)-- 从单体架构到微服务架构.代码拆分(maven 聚合): https://www.cnblogs.com/l-y-h/p/14105 ...

  9. 负载均衡session共享问题

    负载均衡+session共享(memcached-session-manager实现) http://www.cnblogs.com/youzhibing/p/5094460.html http:// ...

随机推荐

  1. Spark配置&启动脚本分析

    本文档基于Spark2.0,对spark启动脚本进行分析. date:2016/8/3 author:wangxl Spark配置&启动脚本分析 我们主要关注3类文件,配置文件,启动脚本文件以 ...

  2. [C++程序设计]内置函数

    注意: 可以在声明函数和定义函数时同时写 inline,也可以只在其中一处声明inline,效果相同,都能按内置函数处理. 使用内置函数可以节省运行时间,但却增加了目标 程序的长度.因此一般只将规模很 ...

  3. sqlserver系统表操作

    查询表名中包含‘user’的方法Select * From sysobjects Where name like '%user%' 如果知道列名,想查找包含有该列的表名,可加上系统表syscolumn ...

  4. C语言经典算法100例

    [程序1] 题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. ...

  5. Mac OS X用户,使用homebrew安装,FreeBSD也可以

    qtkeychain 这是编译和运行软件必须的库.各平台都可以编译安装.对于Mac OS X用户,使用homebrew安装: brew install qt5keychain (旧版本的Mac OS ...

  6. javascript之window对象

    window :window对象是BOM中所有对象的核心,除了是BOM中所有对象的父对象外,还包含一些窗口控制函数. 1.全局的window对象 JavaScript中的任何一个全局函数或变量都是wi ...

  7. SoftLayer®凭借Flex Images™消融物理与虚拟服务器之间的界线

    网摘文档留存,日后有用; 达拉斯--(美国商业资讯)--随着SoftLayer Flex Images的推出,物理与虚拟IT资源之间的界线正在变得模糊.Flex Images让用户能够捕捉.复制并存储 ...

  8. IOS MVC

    简单的理解: V对M是不能通讯的. C对M通讯:API M对C通讯:Notification,KVO C对V通讯:Outlet V对C通讯:Target-action, Delegate,Dataso ...

  9. iOS SDK原生JSON解析

    - (IBAction)touchReadButton:(id)sender { NSData *jsonData = [[NSData alloc] initWithContentsOfFile:J ...

  10. .Net语言中关于AOP 的实现详解

    来源: IT人家  发布时间: 2011-03-22 20:28  阅读: 3546 次  推荐: 2   原文链接   [收藏] 摘要:该文章主要和大家讲解开发应用系统时在.Net语言中关于AOP ...