3

近期公司所用项目的缓存想要由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...


light
54 声望1 粉丝