近期公司所用项目的缓存想要由memcache迁移到redis,运维给配置的redis使用模式是sentinel(即哨兵模式的),这种模式之前没用过,在此记录一下。
简单介绍下Redis-sentinel:
Redis-sentinel是Redis实例的监控管理、通知和实例失效备援服务,是Redis集群的管理工具。在一般的分布式中心节点数据库中,Redis-sentinel的作用是中心节点的工作,监控各个其他节点的工作情况并且进行故障恢复,来提高集群的高可用性
(简介来自http://www.searchdatabase.com…)
我自己的理解就是,假如有a,b,c 3台可用的redis服务器,其中a为主服务器,b,c为从服务器。
在sentinel模式下如果a出现问题,可以自动将a服务器拿掉或者降级为从服务器,然后从b和c中根据一定策略选择一台升级为主服务器,之后a恢复后作为从服务器使用,避免了了由于某台服务器出现问题时影响整个redis服务。
redis-sentinel模式对redis服务无疑是一个很好的支持,但是在开发人员使用时会稍微麻烦一些。因为可能更常用的模式就是直接在程序中写好一个配置文件,redis主从库都是确定的,程序读取配置文件进行redis操作。假如主库出现问题,必须手动修改配置文件才能继续正常使用。而如果发现的比较晚可能会造成不必要的损失。
而在sentinel模式下需要程序动态获取主从库的ip,即使某台redis服务出现问题,也不会影响到程序,这样就避免了手动修改配置的问题。而关键问题其实就是动态获取主从库的ip,端口等信息了。
在网上查相关资料,大部分都是讲解如何配置sentinel服务,而php对应使用方法不太多。看了官方redis-sentinel文档后了解到获取sentinel信息是有对应API的,只不过是一些原生命令。
而php-redis库是有支持原生命令的方法的,如下:
/*
* Send arbitrary things to the redis server.
* @param string $command Required command to send to the server.
* @param mixed ...$arguments Optional variable amount of arguments to send to the server.
* @return mixed
* @example
* <pre>
* $redis->rawCommand('SET', 'key', 'value'); // bool(true)
* $redis->rawCommand('GET", 'key'); // string(5) "value"
* </pre>
*/
public function rawCommand( $command, $arguments ) {}
而在开发使用大致过程如下
1、根据运维给的sentinel配置信息连接sentinel,获得需要的信息(注意:此处是sentinel服务的配置信息,和redis的并不一致)。配置信息(IP,PORT)会有多个,每个sentinel返回的redis主从配置信息是一致的,所以进行操作时使用其中一台服务返回的信息即可。
//初始化redis对象
$redis = new Redis();
//连接sentinel服务 host为ip,port为端口
$redis->connect($host, $port);
//可能用到的部分命令,其他可以去官方文档查看
//获取主库列表及其状态信息
$result = $redis->rawCommand('SENTINEL', 'masters');
//根据所配置的主库redis名称获取对应的信息
//master_name应该由运维告知(也可以由上一步的信息中获取)
$result = $redis->rawCommand('SENTINEL', 'master', $master_name);
//根据所配置的主库redis名称获取其对应从库列表及其信息
$result = redis->rawCommand('SENTINEL', 'slaves', $master_name);
//获取特定名称的redis主库地址
$result = $redis->rawCommand('SENTINEL', 'get-master-addr-by-name', $master_name)
//这个方法可以将以上sentinel返回的信息解析为数组
function parseArrayResult(array $data)
{
$result = array();
$count = count($data);
for ($i = 0; $i < $count;) {
$record = $data[$i];
if (is_array($record)) {
$result[] = parseArrayResult($record);
$i++;
} else {
$result[$record] = $data[$i + 1];
$i += 2;
}
}
return $result;
}
2、通过以上操作已经可以获取到redis主从库的信息,redis密码是固定的,自己写好就OK。之后就可以按照单例模式去使用redis了,注意操作时主从分离。
以上只是一个大体的使用过程,不同情况可能有所调整。
已上只是简单说了下php程序如何去使用这种模式,具体工作原理和配置请移步
https://segmentfault.com/a/11…
https://segmentfault.com/a/11…