优化过的redis封装类
转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封装类的更多相关文章
- redis优化配置和redis.conf说明
1. redis.conf 配置參数: #是否作为守护进程执行 daemonize yes #如以后台进程执行,则需指定一个pid,默觉得/var/run/redis.pid pidfile redi ...
- 写一个Redis封装类
打算自己封装一个Redis操作类,方便使用,且有一定log记录.Redis的封装思路:基于Redis类进一步封装 一般属性 单例 (配置参数从配置文件中读取还是写死?考虑多配置之间切换) 常规操作根据 ...
- redis优化配置和redis.conf说明(转)
1. redis.conf 配置参数: #是否作为守护进程运行 daemonize yes #如以后台进程运行,则需指定一个pid,默认为/var/run/redis.pid pidfile redi ...
- asp.net性能优化之使用Redis缓存(入门)
1:使用Redis缓存的优化思路 redis的使用场景很多,仅说下本人所用的一个场景: 1.1对于大量的数据读取,为了缓解数据库的压力将一些不经常变化的而又读取频繁的数据存入redis缓存 大致思路如 ...
- 详谈redis优化配置和redis.conf
1. Redis.conf 配置参数: #是否作为守护进程运行 daemonize yes #如以后台进程运行,则需指定一个pid,默认为/var/run/redis.pid pidfile redi ...
- 【转载】redis优化配置和redis.conf说明
转载地址:http://blog.csdn.net/luozhonghua2014/article/details/40568707?utm_source=tuicool&utm_medium ...
- 业务层面和运维层面优化你的Redis
业务层面 key的长度尽量要短,在数据量非常大时,过长的key名会占用更多的内存; 一定避免存储过大的数据(大value),过大的数据在分配内存和释放内存时耗时严重,会阻塞主线程; Redis 4.0 ...
- StackExchange.Redis 封装类
using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using ...
- Redis高级实践之————Redis短连接性能优化
摘要: 对于Redis服务,通常我们推荐用户使用长连接来访问Redis,但是由于某些用户在连接池失效的时候还是会建立大量的短连接或者用户由于客户端限制还是只能使用短连接来访问Redis,而原生的Red ...
随机推荐
- IOS 开发过程中的 消息通知 小红点
大致分为两种方法:系统方法和自定义方法 系统方法: 系统自带的方法可以显示具体的消息数量,这个就是苹果设备常见的小红点.实现思路如下: NSArray *tabBarItems = self.navi ...
- C#之结构化异常处理
1.异常处理4要素 一个表示异常详细信息的类类型: 一个向调用者引发异常类实例的成员: 调用者的一段调用异常成员的代码块: 调用者的一段处理将要发生异常的代码块:
- Linux系统cpu 100%修复案例
Linux系统cpu 100%修复案例 阿里云技术支持团队:完颜镇江 案例背景: Linux主机连续三天CPU% 处理思路: 1. 登录服务器查看/var/log/messages+/var/lo ...
- Oracle基础 事务
一.事务 事务就是业务上的一个逻辑单元,它能够保证其中对数据所有的操作,要么全部成功,要么全部失败. 二.事务的特性: 1.原子性:事务是SQL中的最小执行单位,不能再进行分割.要么全部执行,要么全部 ...
- web前端开发(5)
CSS的一些问题: 一般情况下,尽量使用class选择器 解决点击超链接后hover 样式不出现多次问题:a:visited a:hover 的顺序是问题所在,记住 love hate L(lin ...
- vb.net中的SqlHelper
1.定义: SqlHelper是一个基于·NET Framework的数据库操作组件.组件中包含数据库操作方法.SqlHelper用于简化你重复的去写那些数据库连接(SqlConnection),Sq ...
- 《UNIX环境高级编程》学习心得 三
输入和输出 1.文件描述符 文件描述符(file descriptor)可以理解为内核在某个进程中访问一个文件时,内核向进程返回的一个非负整数.在内核使用open或creat打开一个现有文件或者创建一 ...
- IE浏览器部分版本不支持background-siza属性问题
background-size是CSS3新增的属性,但是IE8以下还是不支持,可以通过滤镜来实现这样的一个效果 background-size:contain; // 缩小图片来适应元素的尺寸(保持像 ...
- a标签中使用img后的高度多了4px
前两天,在做一个网站的时候,发现a标签中使用img后的高度多了4px,各种纠结. 最后,仔细分析,终于找到原因了,因为img是行内元素,默认display: inline; 它与文本的默认行为类似,下 ...
- 第一个项目--用bootstrap实现美工设计的首页
主要介绍在首页实现中用到bootstrap实现效果的地方. 实现如下的效果: <li> <div role="group" style="padding ...