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

 

  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 }

 

转载于:https://www.cnblogs.com/iyoule/p/5036456.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373999.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我今天对JavaFX的了解

如果您没有听说过&#xff0c;JavaFX 2是Java的新Desktop / web / client框架。 自JavaFX 1以来&#xff0c;它已经进行了相当大的改动&#xff08;坦率地说&#xff0c;效果并不那么令人印象深刻&#xff09;。 自定义脚本语言已经淘汰了&#xff0c;您可以使用标准Java和基于…

怎么解决xp系统不能安装NET Framework4.0?

.net 4.0安装不上解决方法&#xff1a; 引用 9 楼 MoreQuestion 的回复: 全部都不行&#xff01;就是用360软件管家安装那个就可以了。用了楼主的方法&#xff0c;果然可行啊 1.先安装wic。 2.用360安装.net40 本帖最后由 不懂 于 2014-6-6 00:56 编辑Windows Server 2003 如何…

C++内联(inline)函数

内联函数 内联函数是一种特殊类型的函数&#xff0c;内联函数在定义或声明时前面加上“inline”关键字。比如&#xff1a; inline int max(int a,int b) { return (a>b)?a:b; } 内联&#xff08;inline&#xff09;是内联扩展&#xff08;inline expansion&#xff09;的简…

我的python学习笔记全集_记录我的Python学习笔记

不想再像以前那样&#xff0c;什么都从头开始学习语法、总结语法&#xff0c;这样反而会过分纠结于语法&#xff0c;耽误了开发&#xff0c;毕竟语言的主要属性是工具&#xff0c;次要的属性是语言本身。所以还是先熟练使用语言去进行开发&#xff0c;等足够熟悉了&#xff0c;…

HDU 5794:A Simple Chess(Lucas + DP)

题目链接&#xff1a;http://acm.split.hdu.edu.cn/showproblem.php?pid5794 题意&#xff1a;让一个棋子从&#xff08;1,1&#xff09;走到&#xff08;n&#xff0c;m&#xff09;&#xff0c;要求像马一样走日字型并只能往右下角走。里面还有r个障碍点不能经过或者到达&am…

php源码分析之PHPAPI宏的作用

在PHP源码中&#xff0c;我们经常会看到很多函数前面有个PHPAPI&#xff0c;但这是什么呢&#xff1f; 于是我在php源码/main/php.h中找到了它的定义 #ifdef PHP_WIN32 # include "tsrm_win32.h" # include "win95nt.h" # ifdef PHP_EXPORTS # …

15分钟内开始使用Amazon Web Services和全自动资源调配

在等待一个新项目时&#xff0c;我想学习一些有用的东西。 而且由于在许多项目中我们需要评估和测试正在开发的应用程序的性能&#xff0c;而很少有足够的硬件来生成实际负载&#xff0c;因此我决定学习更多有关按需在云中按需配置虚拟机的知识&#xff0c;即Amazon Web Servic…

解析JVM内存区域组成

在方法&#xff08;代码块&#xff09;中定义一个变量时&#xff0c;java就在栈中为这个变量分配JVM内存空间&#xff0c;当超过变量的作用域后&#xff0c;java会自动释放掉为该变量所分配的JVM内存空间&#xff1b;而在堆中分配的JVM内存由java虚拟机的自动垃圾回收器来管理。…

python打开浏览器后带cookie_Python爬虫使用浏览器的cookies:browsercookie

很多用Python的人可能都写过网络爬虫&#xff0c;自动化获取网络数据确实是一件令人愉悦的事情&#xff0c;而Python很好的帮助我们达到这种愉悦。然而&#xff0c;爬虫经常要碰到各种登录、验证的阻挠&#xff0c;让人灰心丧气(网站&#xff1a;天天碰到各种各样的爬虫抓我们网…

VS插件开发

参考资料: VS插件开发 - 个性化VS IDE编辑器 自己动手编写一个VS插件&#xff08;一&#xff09; VS Addin插件基本开发入门 VS Addin插件配置、部署 转载于:https://www.cnblogs.com/wangwangfei/p/5830081.html

使用AspectJ,Javassist和Java Proxy进行代码注入的实用介绍

静态地或在运行时将代码片段注入已编译的类和方法中的功能可能会很有帮助。 这尤其适用于在没有源代码的第三方库中或在无法使用调试器或探查器的环境中对问题进行故障排除。 代码注入对于处理涉及整个应用程序的问题&#xff08;例如性能监视&#xff09;也很有用。 以这种方式…

Java中的变量

java类的成员变量有两种&#xff1a;一种是被static关键字修饰的变量&#xff0c;叫类变量或者静态变量&#xff1b;另一种没有static修饰&#xff0c;为实例变量。 在语法定义上的区别&#xff1a;静态变量前要加static关键字&#xff0c;而实例变量前则不加。 在程序运行时的…

无限漫游

一、FAT AP架构下&#xff0c;AP设备不做认证时&#xff1a; (1) AP1&#xff0c;AP2正常工作&#xff0c;发送Beacon帧&#xff0c;向STA通告支持的无线服务&#xff1b; (2) STA搜索到AP1的信号&#xff0c;向AP1发Probe Request,请求获取AP1所提供的无线服务&#xff1b;AP…

uni-app内置地图轨迹_MIUI11 新增亲情守护,支持安全围栏、运动轨迹功能

点击右上角关注我们&#xff0c;每天给您带来最新最潮的科技资讯&#xff0c;让您足不出户也知道科技圈大事&#xff01;日前&#xff0c;小米 MIUI 体验总负责人 MIUI小凡 在微博上为大家预告了 MIUI11 的新特性「亲情守护」&#xff0c;并表示「在亲情守护中&#xff0c;我们…

:before与:after伪类的应用

1.小三角样式 .tip{ position:relative; display:inline-block; width:100px; margin:100px; padding:30px 20px; color:#fff; border:1px solid #666; border-radius:5px; background-color:rgba(0,153,51,1);}.tip:before{ content:; posit…

小心重载API方法

重载方法是API设计中的重要概念&#xff0c;尤其是当您的API是流利的API或DSL&#xff08; 特定于域的语言 &#xff09;时。 对于jOOQ就是这种情况&#xff0c;在这种情况下&#xff0c;您经常想使用与完全相同的方法名称来与库进行各种交互。 示例&#xff1a;jOOQ条件 pac…

phpcms 下载模型列表页直接点击下载

下载模型设置本地下载 列表页模板直接调用 <article class"prjDown"><p class"prjDownTitle">方案下载</p><nav class"prjDownNav"><ul>{pc:content action"lists" catid"$catid" num"3…

为什么Java中类方法不能访问实例方法

我们已经知道类体中的方法分为实例方法和类方法两种&#xff0c;用static修饰的是类方法。二者有什么区别呢&#xff1f;当一个类创建了一个对象后&#xff0c;这个对象就可以调用该类的方法。 当类的字节码文件被加载到内存时&#xff0c;类的实例方法不会被分配入口地址&…

python展开 c函数中的宏预处理_C中的预处理宏

C中的预处理宏宏定义就属于预处理命令的一种。那么&#xff0c;什么是宏呢&#xff1f;宏&#xff1a;c语言标准允许在程序中用一个标识符来表示一个字符串。标识符就是宏名。宏替换&#xff1a;宏替换就是宏定义。在编译预处理中&#xff0c;将程序中所有的宏名用相应的字符串…

(转) 中断处理程序中断服务例程

关于中断处理程序和中断服务例程ISR的区别及联系&#xff0c;之前一直搞混&#xff0c;今天抽时间将两者关系弄弄清楚。ok,下面进入主题。首先中断处理程序(Interrupt Handler)和中断服务例程ISR(Inerrupt Service Routine)是两个不同的概念.简单来说就是&#xff0c;一条中断线…