PHP Redis 集群封装类
<?php /** * Redis 操作,支持 Master/Slave 的负载集群 * * @author V哥 */class RedisCluster{ // 是否使用 M/S 的读写集群方案 // 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);PHP Redis 集群封装类的更多相关文章
- Redis集群案例与场景分析
1.背景 Redis的出现确实大大地提高系统大并发能力支撑的可能性,转眼间Redis的最新版本已经是3.X版本了,但我们的系统依然继续跑着2.8,并很好地支撑着我们当前每天5亿访问量的应用系统.想当年 ...
- Java Spring mvc 操作 Redis 及 Redis 集群
本文原创,转载请注明:http://www.cnblogs.com/fengzheng/p/5941953.html 关于 Redis 集群搭建可以参考我的另一篇文章 Redis集群搭建与简单使用 R ...
- Redis集群搭建与简单使用
介绍安装环境与版本 用两台虚拟机模拟6个节点,一台机器3个节点,创建出3 master.3 salve 环境. redis 采用 redis-3.2.4 版本. 两台虚拟机都是 CentOS ,一台 ...
- window下使用Redis Cluster部署Redis集群
日常的项目很多时候都需要用到缓存.redis算是一个比较好的选择.一般情况下做一个主从就可以满足一些比较小的项目需要.在一些并发量比较大的项目可能就需要用到集群了,redis在Windows下做集群可 ...
- Redis集群~windows下搭建Sentinel环境及它对主从模式的实际意义
回到目录 关于redis-sentinel出现的原因 Redis集群的主从模式有个最大的弊端,就是当主master挂了之前,它的slave从服务器无法提升为主,而在redis-sentinel出现之后 ...
- [个人翻译]Redis 集群教程(中)
上一篇:http://www.cnblogs.com/li-peng/p/6143709.html 官方原文地址:https://redis.io/topics/cluster-tutorial 水 ...
- [个人翻译]Redis 集群教程(上)
官方原文地址:https://redis.io/topics/cluster-tutorial 水平有限,如果您在阅读过程中发现有翻译的不合理的地方,请留言,我会尽快修改,谢谢. 这是 ...
- Redis集群(九):Redis Sharding集群Redis节点主从切换后客户端自动重新连接
上文介绍了Redis Sharding集群的使用,点击阅读 本文介绍当某个Redis节点的Master节点发生问题,发生主从切换时,Jedis怎样自动重连新的Master节点 一.步骤如下: 1.配 ...
- Redis集群(八):Redis Sharding集群
一.Redis目前的集群方案主要有两种:Redis Sharding和Redis Cluster 1.Redis Sharding:3.0以前基本上使用分片实现集群,目前主流方案,客户端实现 2.Re ...
随机推荐
- 【Python】 最简单的web服务
python -m SimpleHTTPServer 8321 1.python 没有指定目录的参数 想启动目录 就cd到该目录下 2.在目录下创建一个index.html 3.启动web服务,(端 ...
- CHROME下去掉保存密码后输入框变成黄色背景样式
之前没遇到过这种情况,现在打开这个页面后,手机号和密码都已经输入了,而且还显示的是黄色背景,清了下cookie,没有解决问题.请教了下大神,先把方法整理到这儿. 用代码审查看了input样式有如下样式 ...
- android 设置半透明
对于Button和ImageButton 还有一些View 设置半透明或者透明都是通过 android:background="#b0000000" 这是就是半透明 android ...
- 学习Linux第一天
1.简介: 记住这个名字:Linus Torvals 系统组成:Linux内核,Shell, 文件系统,实时程序 Tips:在系统启动过程中,使用Alt+F2组合键,可以查看Ubuntu启动的详细过程 ...
- Ext学习-布局介绍
1.目标 了解ExtJS中的关于布局和组建的相关原理,并学习相关的布局方式 2.内容 1.布局和组件的相关原理 2.常见的布局方式 3.学习流程 1.首先应该学习一下布局和组件的相 ...
- intellij idea 14 ULTIMATE 注册码
Name:happy KEY:63763-YCO0I-QR4TV-G4I3E-4XGK9-GQSQ3
- JAVA数据源连接方式汇总
最近在研究JAVA的数据源连接方式,学习的时候发现了一位同行写的文章,转载过来,留作记录! 一.问题引入 在java程序中,需要访问数据库,做增删改查等相关操作.如何访问数据库,做数据库的相关操作呢? ...
- 微信变声器(WeChat Voice)会是营销新利器吗
微信变声器(WeChat Voice)2.0 Android版开始内测了,时间从2015年5月20日 - 2015年6月20日,使用微信变声器改变你的声音,并分享给好友! 无论你是想装可爱还是恶搞,微 ...
- 解决ubuntu中zip解压的中文乱码问题
转自解决ubuntu中zip解压的中文乱码问题 在我的ubuntu12.10中,发现显示中文基本都是正常的,只有在解压windows传过来的zip文件时,才会出现乱码.所以,我用另一个方法解决中文乱码 ...
- log4j记录exception异常有价值信息及log4j级别
try{ }catch(Exception e){ e.printStackTrace(); log.error("配件导出excel错误:", e.fillInStackTrac ...