转http://www.cnblogs.com/jackluo/p/3410192.html

<?php

/**
* RedisCluster 群redius操作类
*
* //创建连接
* $rc = new RedisCluster();
* $rc->connect(array("host" => "127.0.0.1", "port" => 6379)); //php客户端设置的ip及端口
* //存储值
* $rc->set($key,$value);
* $rc->set($array);
* $rc->setnx($key,$value);//只创不更
* $rc->setnx($array);//只创不更
* //获取值
* $rc->get($key);
* $rc->get($array);
* //删除
* $rc->delete($key);
* $rc->delete($array);
* //删除所有
* $rc->deleteAll();
* //+1或者其他
* $rc->incr($key[,$othervar]);
* //-1或者其他
* $rc->decr($key[,$othervar]);
* //关闭连接 0.主服务器,1.从服务器,2.全部
* $rc->close(2);
*
* hujiande 297538600@qq.com
* @date 2014.8.15
*/
class RedisCluster extends NoRewindIterator { // 是否使用 M/S 的读写集群方案
private $_isUseCluster = false;
// Slave 句柄标记
private $_sn = 0;
// 服务器连接句柄
private $_linkHandle = array(
'master' => null, // 只支持一台 Master
'slave' => array(), // 可以有多台 Slave
); /**
* 构造函数
*
* @access $rc = new RedisCluster($isUseCluster=false);
* @param boolean $isUseCluster 是否采用 M/S 方案
*/
public function __construct($isUseCluster = false) {
$this->_isUseCluster = $isUseCluster;
} /**
* 连接服务器,注意:这里使用长连接,提高效率,但不会自动关闭
*
* @access $rc->connect($config=array('host'=>'127.0.0.1','port'=>6379), $isMaster=true);
* @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;
} /**
* 关闭连接
*
* @access $rc->connect($flag=2);
* @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 原始对象
*
* @access $rc->getRedis(true, true);
* @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'];
}
} /**
* 写缓存
*
* @access $rc->set($key, $value, $expire);//存储单个键值
* @access $rc->set($array, $expire);//存储多个键值
* @param string $key 组存KEY
* @param string $value 缓存值
* @param int $expire 过期时间,0:表示无过期时间 单位m秒
* @param boolean $is_nx 是否只创建不更新
*/
public function set($key, $value = '', $expire = 0) {
//存储多个键值
if (is_array($key)) {
$array = $key;
$expire = (int) $value; // 永不超时
if ($expire == 0) {
$ret = $this->getRedis()->mset($array);
}
else {
$ret = true; foreach ($array as $key1 => $value1) {
$ret = $this->set($key1, $value1, $expire, $is_nx) && $ret;
} } }
//存储单个键值
else {
// 永不超时
if ($expire == 0) {
$ret = $this->getRedis()->set($key, $value);
}
else {
$ret = $this->getRedis()->setex($key, $expire, $value);
} } return $ret;
} /**
* 只创建$key的值,不更新已存在的$key值
*
* @access $rc->setnx($not_exist_key, $value);//不更新已存在的$key值
* @access $rc->setnx($array);//不更新已存在的$key值
* @param string $not_exist_key 缓存KEY
* @param string $value 缓存值
* @return boolean
*/
public function setnx($not_exist_key, $value = '') { if (is_array($not_exist_key)) { return $this->getRedis()->msetnx($not_exist_key);
} else { return $this->getRedis()->setnx($not_exist_key, $value);
} } /**
* 读缓存
*
* @access $rc->get($key);
* @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);
} /**
* 删除缓存
*
* @access $rc->delete($key);
* @param string || array $key 缓存KEY,支持单个健:"key1" 或多个健:array('key1','key2')
* @return int 删除的健的数量
*/
public function delete($key) {
return $this->getRedis()->delete($key);
} /**
* 清空当前数据库
*
* @access $rc->deleteAll();
* @return boolean
*/
public function deleteAll() {
return $this->getRedis()->flushDB();
} /**
* 值加加操作,类似 ++$i ,如果 key 不存在时自动设置为 0 后进行加加操作
*
* @access $rc->incr($key, $default=1);
* @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 后进行减减操作
*
* @access $rc->decr($key, $default=1);
* @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);
}
} /* =================== 以下私有方法 =================== */ /**
* 随机 HASH 得到 Redis Slave 服务器句柄
* @access $this->_getSlaveRedis();
* @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 之间的值
* @access $this->_hashId($id, $m=10);
* @param string $id
* @param int $m
* @return int
*/
private function _hashId($id, $m = 10) {
//把字符串K转换为 0~m-1 之间的一个值作为对应记录的散列地址
$k = md5($id);
$md5_len = 32;
$b = bin2hex($k);
$h = 0;
for ($i = 0; $i < $md5_len; $i++) {
//相加模式HASH
$h += substr($b, $i * 2, 2);
}
$hash = ($h * 1) % $m;
return $hash;
} }

  

优化过的redis封装类的更多相关文章

  1. redis优化配置和redis.conf说明

    1. redis.conf 配置參数: #是否作为守护进程执行 daemonize yes #如以后台进程执行,则需指定一个pid,默觉得/var/run/redis.pid pidfile redi ...

  2. 写一个Redis封装类

    打算自己封装一个Redis操作类,方便使用,且有一定log记录.Redis的封装思路:基于Redis类进一步封装 一般属性 单例 (配置参数从配置文件中读取还是写死?考虑多配置之间切换) 常规操作根据 ...

  3. redis优化配置和redis.conf说明(转)

    1. redis.conf 配置参数: #是否作为守护进程运行 daemonize yes #如以后台进程运行,则需指定一个pid,默认为/var/run/redis.pid pidfile redi ...

  4. asp.net性能优化之使用Redis缓存(入门)

    1:使用Redis缓存的优化思路 redis的使用场景很多,仅说下本人所用的一个场景: 1.1对于大量的数据读取,为了缓解数据库的压力将一些不经常变化的而又读取频繁的数据存入redis缓存 大致思路如 ...

  5. 详谈redis优化配置和redis.conf

    1. Redis.conf 配置参数: #是否作为守护进程运行 daemonize yes #如以后台进程运行,则需指定一个pid,默认为/var/run/redis.pid pidfile redi ...

  6. 【转载】redis优化配置和redis.conf说明

    转载地址:http://blog.csdn.net/luozhonghua2014/article/details/40568707?utm_source=tuicool&utm_medium ...

  7. 业务层面和运维层面优化你的Redis

    业务层面 key的长度尽量要短,在数据量非常大时,过长的key名会占用更多的内存; 一定避免存储过大的数据(大value),过大的数据在分配内存和释放内存时耗时严重,会阻塞主线程; Redis 4.0 ...

  8. StackExchange.Redis 封装类

    using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using ...

  9. Redis高级实践之————Redis短连接性能优化

    摘要: 对于Redis服务,通常我们推荐用户使用长连接来访问Redis,但是由于某些用户在连接池失效的时候还是会建立大量的短连接或者用户由于客户端限制还是只能使用短连接来访问Redis,而原生的Red ...

随机推荐

  1. spark1.2.0编译

    spark 有三种编译方式:SBT.MAVEN.make-distribution.sh.SBT.MAVEN两种方式打出来的包比较大,不适合部署使用.因此我们通常使用第三种方式打包. ./make-d ...

  2. T-SQL 之 多表联合更新

    1. sqlite 多表更新方法 UPDATE tA SET col1=tB.col1 FROM tableA tA INNER JOIN tableB tB ON tA.col2=tB.col2 这 ...

  3. mysql前n条查询

    可以利用——LIMIT——来完成这项功能. LIMIT可以实现top N查询,也可以实现M至N(某一段)的记录查询,具体语法如下: SELECT * FROM MYTABLE ORDER BY AFI ...

  4. 【Python千问 1】Python核心编程(第二版)导读

    第一章 欢迎来到Python世界 什么是Python Python的起源 Python的特点 下载Python 安装Python 运行Python Python文档 比较Python(与其它语言的比较 ...

  5. Http StatuCode说明

    HTTP 200 - 文件被正常的访问 HTTP 302 - 临时重定向 HTTP 400 - 请求无效 HTTP 401.1 - 未授权:登录失败 HTTP 401.2 - 未授权:服务器配置问题导 ...

  6. 关于Navicat Premium导入xlsx的问题

    这段时间由于工作需要,频繁通过Oracle导入/导出大量数据,测试了很多软件,都不理想.PL/SQL Developer导入.导出都卡死:Oracle SQL Developer也是导入.导出都卡的半 ...

  7. JavaScript break和continue 跳出循环

    在JavaScript中,使用 break 和 continue 语句跳出循环: break语句的作用是立即跳出循环,即不再执行后面的所有循环: continue语句的作用是停止正在执行的循环,直接进 ...

  8. [wordpress]wp-api-jwt-auth 尝试添加运行在多站点中 need change

    Hi,Thank you this plugin,because i use this plugin on Wordpress one Network,so the request other api ...

  9. LINUX下查看php运行的用户

    <?php echo shell_exec("id -a"); ?> 打开网页,显示 uid=2(daemon) gid=2(daemon) groups=2(daem ...

  10. Hadoop集群“WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable”解决办法

    Hadoop集群部署完成后,经常会提示 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platfo ...