PHP Redis 集群封装类
<?php
/**
* Redis 操作,支持 Master/Slave 的负载集群
*
* @author V哥
*/
class
RedisCluster{
// 是否使用 M/S 的读写集群方案
private
$_iSUSECluster
= false;
// 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
);
转载于:https://www.cnblogs.com/Mwsoft/p/5175231.html
PHP Redis 集群封装类相关推荐
- docker 实现redis集群搭建
摘要:接触docker以来,似乎养成了一种习惯,安装什么应用软件都想往docker方向做,今天就想来尝试下使用docker搭建redis集群. 首先,我们需要理论知识:Redis Cluster是Re ...
- Redis 集群部署及踩过的坑
本文目标 要在单台机器上搭建Redis集群,方式是通过不同的TCP端口启动多个实例,然后组成集群,同时记录在搭建过程中踩过的坑. 安装准备 centos版本:6.7 redis版本:3.2.3 安装方 ...
- windows下配置redis集群,启动节点报错:createing server TCP listening socket *:7000:listen:Unknown error...
windows下配置redis集群,启动节点报错:createing server TCP listening socket *:7000:listen:Unknown error 学习了:https ...
- Redlock——Redis集群分布式锁
欢迎关注方志朋的博客,回复"666"获面试宝典 前言 分布式锁是一种非常有用的技术手段.实现高效的分布式锁有三个属性需要考虑: 安全属性:互斥,不管什么时候,只有一个客户端持有锁 ...
- Redis数据库搭建集群(集群概念、redis集群、搭建集群(配置机器1、2、创建集群、数据操作验证)、Python与redis集群交互)
1. 集群的概念 集群是一组相互独立的.通过高速网络互联的计算机,它们构成了一个组,并以单一系统的模式加以管理.一个客户与集群相互作用时,集群像是一个独立的服务器.集群配置是用于提高可用性和可缩放性. ...
- Redis 集群方案
根据一些测试整理出来的一份方案: 1. Redis 性能 对于redis 的一些简单测试,仅供参考: 测试环境:Redhat6.2 , Xeon E5520(4核)*2/8G,1000M网卡 Redi ...
- 如何从0到1构建一个稳定、高性能的Redis集群?(附16张图解)
阅读本文大约需要 13 分钟. 大家好,我是 Kaito. 这篇文章我想和你聊一聊 Redis 的架构演化之路. 现如今 Redis 变得越来越流行,几乎在很多项目中都要被用到,不知道你在使用 Red ...
- 天天用着Redis集群,主从同步该知道吧?集群工作原理是否需要了解下?
作者:z小赵 ★ 一枚用心坚持写原创的"无趣"程序猿,在自身受益的同时也让朋友们在技术上有所提升. 前言 插播一个小插曲,本来文章已经写好准备发布了,手贱清理了缓存导致文本内容全部 ...
- 那些年用过的Redis集群架构(含面试解析)
作者:孤独烟,平安银行资深后端工程师一枚! 引言 今天是2019年2月13号,也就是大年初九,我接到了高中同学刘有码面试失利的消息. 他面试的时候,身份是某知名公司的小码农一枚,却因为不懂自己生产上R ...
最新文章
- python 程序打包成 exe 文件
- ubuntu系统在vmware中无法联网问题解决
- oracle入门很简单豆瓣,Oracle入门经典
- C基础(36——40)
- 算法基础部分1-递归
- 友元函数类图_要达到形式的公平,需要具备的前提条件是()。
- 机器学习知识地图 —— 概述
- 沧小海笔记之PCIE协议解析——第三章 PCIE的数据链路层
- AmapUtil--高德地图工具类
- 为什么计算机起始时间、为什么Java时间戳、是1970年1月1日?
- STK中设置卫星的多波束模型
- java向上转型与向下转型
- StudyJams-第01课_初识Android的View(TextView、ImageView、Button)
- 微信小程序开发笔记 进阶篇③——onfire.js事件订阅和发布在微信小程序中的使用
- 网络安全一哥的流量分析服务非常好
- 毕马威中国:证券基金经营机构信息技术审计项目发现洞察
- 利用AudioContext来实现网易云音乐的鲸鱼音效
- 用5G“点亮”智慧灯杆!FCU2302赋予智慧城市更多可能
- 自定义iOS导航栏背景,标题和返回按钮文字颜色-----转载自gyz413977349
- eas-bos工作流的几张表
热门文章
- 24继承父类并实现多个接口
- 西北工业大学 计算机学院王云岚,王云岚
- python中常见的运行时错误_17个常见的Python运行时错误
- 安装 |GitBash闪退问题解决方案及Git安装教程( win10系统安装Git后)
- 男高音,女高音,男中音,女中音,男低音,女低音
- 用电梯服务器怎样解电梯显示E34,默纳克品牌电梯故障代码e41怎么处理
- android webview 报错,Android WebView 5.x 系统下 Resources$NotFoundException异常处理
- Java基础day10
- erlang精要(4)-列表及运算
- 【深度学习】在PyTorch中使用 LSTM 自动编码器进行时间序列异常检测