优化过的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 ...
随机推荐
- java.util Pattern 和 Mathcer
1.测试给定的正则表达式是否匹配输入的字符串,这里该正则表达式只使用一次 private String regex ; private String input; @Before public voi ...
- IOS webView快照
这个功能就是对网页的存储,存储成png格式的图片 且不失真 很棒的一个小方法.具体实现如下: - (void)webViewDidFinishLoad:(UIWebView *)webView1 { ...
- [WinForm] VS2010发布、打包安装程序(超全超详细)
1. 在vs2010 选择“新建项目”→“ 其他项目类型”→“ Visual Studio Installer→“安装项目”: 命名为:Setup1 . 这是在VS2010中将有三个文件夹, 1.“应 ...
- Android中Handler作用
在Android的UI开发中,我们经常会使用Handler来控制主UI程序的界面变化.有关Handler的作用,我们总结为:与其他线程协同工作,接收其他线程的消息并通过接收到的消息更新主UI线程的内容 ...
- 重构15-Remove Duplication(删除重复)
这大概是处理一个方法在多处使用时最常见的重构.如果不加以注意的话,你会慢慢地养成重复的习惯.开发者常常由于懒惰或者在想要尽快生成尽可能多的代码时,向代码中添加很多重复的内容.我想也没必要过多解释了吧, ...
- java jdbc连接mysql
JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口 ...
- 搭建第一个web项目:jasperReports+ireport制作pdf报表
一:jasperReports介绍: 在web应用中,必须面临大量的报表问题,即将数据库中的数据形成报表并进行打印.传统开发只能使用html页面设计报表,效率低且不支持别的格式.所以jasperRep ...
- SLR,语法分析表的构建
太累了,感觉不会再爱了.执行了跟编译原理上的一模一样的例子,输出了正确结果 #include <stdio.h> #include <malloc.h> #include &l ...
- Kafka删除逻辑
Kafka的删除逻辑请参见:http://www.cnblogs.com/gaopeng527/p/4950956.html
- Jquery图片轮播和CSS图片轮播
学习Jquery以后,很多时候觉得比写源生代码要简单一点.我们用JQuery做了一个图片轮播的动画,感觉比写CSS要简单一些.下面我来具体讲一下是怎么用JQuery来写. <body> & ...