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.pswp.cn/news/373999.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373999.shtml
英文地址,請注明出處:http://en.pswp.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;一條中斷線…