PHP 在redis-sentinel模式下的使用總結

近期公司所用項目的緩存想要由memcache遷移到redis,運維給配置的redis使用模式是sentinel(即哨兵模式的),這種模式以前沒用過,在此記錄一下。php

簡單介紹下Redis-sentinel:
Redis-sentinel是Redis實例的監控管理、通知和實例失效備援服務,是Redis集羣的管理工具。在通常的分佈式中心節點數據庫中,Redis-sentinel的做用是中心節點的工做,監控各個其餘節點的工做狀況而且進行故障恢復,來提升集羣的高可用性
(簡介來自http://www.searchdatabase.com...redis

我本身的理解就是,假若有a,b,c 3臺可用的redis服務器,其中a爲主服務器,b,c爲從服務器。
在sentinel模式下若是a出現問題,能夠自動將a服務器拿掉或者降級爲從服務器,而後從b和c中根據必定策略選擇一臺升級爲主服務器,以後a恢復後做爲從服務器使用,避免了了因爲某臺服務器出現問題時影響整個redis服務。數據庫

redis-sentinel模式對redis服務無疑是一個很好的支持,可是在開發人員使用時會稍微麻煩一些。由於可能更經常使用的模式就是直接在程序中寫好一個配置文件,redis主從庫都是肯定的,程序讀取配置文件進行redis操做。假如主庫出現問題,必須手動修改配置文件才能繼續正常使用。而若是發現的比較晚可能會形成沒必要要的損失。segmentfault

而在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 ) {}

而在開發使用大體過程以下
一、根據運維給的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;
}

二、經過以上操做已經能夠獲取到redis主從庫的信息,redis密碼是固定的,本身寫好就OK。以後就能夠按照單例模式去使用redis了,注意操做時主從分離。運維

以上只是一個大致的使用過程,不一樣狀況可能有所調整。分佈式

已上只是簡單說了下php程序如何去使用這種模式,具體工做原理和配置請移步
https://segmentfault.com/a/11...
https://segmentfault.com/a/11...工具

相關文章
相關標籤/搜索