zoukankan      html  css  js  c++  java
  • redis哨兵模式下主从切换后,php实现自动切换

      redis的哨兵模式,在主服务器挂掉后,会通过选举将对应的从服务器切换为主服务器,以此来达到服务的高可用性。

      在业务层面如果主从做了切换可能相对应的服务器IP地址会发生改变,这样会带来程序的的正常运行。为了不影响其业务,会考虑使用VIP去实现IP的飘逸,但是在部分情况下,虚拟机并不支持VIP,这样就无法保证业务的正常运行。索引在此情况下,通过业务本身来实现连接新的主的IP。本文主要以PHP为例,相关代码如下

    <?php
    
    class SRedis
    {
    
        /**
         * 哨兵地址,支持多哨兵地址
         * @var array
         * eg:  [ [ 'host' => '127.0.0.1' , 'port' => 26379 ] ]
         */
        private $_sentinelAddr = [];
    
        private $_sentinelConn = null;
    
        private $_timeout = 10; //超时时间
    
        private $_masterName = 'mymaster'; //主节点名称
    
        private static $_handle = []; //存放redis连接实例
    
        public function __construct(array $iplist, string $masterName = null)
        {
            $this->_sentinelAddr = $iplist;
            $masterName !== null && $this->_masterName = $masterName;
            $this->_getSentinelConn();
        }
    
        /**
         * 获取redis主节点的实例
         * @return bool|Redis
         * @throws Exception
         */
        public function getInstansOf()
        {
            $masterInfo = $this->getMasterInfo();
            if ($masterInfo) {
                $instansof = $this->_connection($masterInfo[0], $masterInfo[1], $this->_timeout);
                return $instansof;
            }
            return false;
        }
    
        /**
         * 获取主节点的ip地址
         * @return array
         */
        public function getMasterInfo()
        {
            $masterInfo = [];
            if ($this->_sentinelConn != null) {
                $masterInfo = $this->_sentinelConn->rawcommand("sentinel", 'get-master-addr-by-name', $this->_masterName);
            }
            return $masterInfo;
    
        }
    
        /**
         * 设置哨兵连接句柄
         */
        private function _getSentinelConn()
        {
            if (is_array($this->_sentinelAddr) && $this->_sentinelAddr) {
                $this->_sentinelConn = $this->_RConnect($this->_sentinelAddr);
            }
        }
    
        /**
         * 获取redis句柄(如果是多主机,保证连接的是可用的哨兵服务器)
         * @param array $hosts
         * @return null|Redis
         */
        private function _RConnect(array $hosts)
        {
            $count = count($hosts);
            $redis = null;
            if ($count == 1) {
                $this->_connection($hosts[0]['host'], $hosts[0]['port'], $this->_timeout);
            } else {
                $i = 0;
                while ($redis == null && $i < $count) {
                    $redis = $this->_connection($hosts[$i]['host'], $hosts[$i]['port'], $this->_timeout);
                    $i++;
                }
            }
            return $redis;
        }
    
        /**
         * redis 连接句柄
         * @param string $host
         * @param int $port
         * @param int $timeout
         * @return null|Redis
         */
        private function _connection(string $host, int $port, int $timeout)
        {
            if (isset(self::$_handle[$host . ':' . $port])) {
                return self::$_handle[$host . ':' . $port];
            }
            try {
                $redis = new Redis();
                $redis->connect($host, $port, $timeout);
                self::$_handle[$host . ':' . $port] = $redis;
            } catch (Exception $e) {
                $redis = null;
            }
            return $redis;
        }
    }
    $hosts = [
        [
            'host' => '127.0.0.1',
            'port' => 26381
        ],
        [
            'host' => '127.0.0.1',
            'port' => 26380
        ]
    ];
    $masterName = 'mymaster';
    $sredis = new SRedis($hosts, $masterName);
    $masterRedis = $sredis->getInstansOf();
    if ($masterRedis) {
        print_r($masterRedis->hgetall("iplist"));
    } else {
        echo "redis 服务器连接失败";
    }
    
    
    
     
  • 相关阅读:
    linux添加超级用户
    MongDB配置方法
    【bzoj5174】[Jsoi2013]哈利波特与死亡圣器 二分+树形dp
    【bzoj3560】DZY Loves Math V 欧拉函数
    【bzoj5157】[Tjoi2014]上升子序列 树状数组
    【uoj#317】[NOI2017]游戏 2-SAT
    【bzoj5146】有趣的概率 微积分
    【bzoj4695】最假女选手 线段树区间最值操作
    【bzoj4355】Play with sequence 线段树区间最值操作
    【loj2319】[NOIP2017]列队 Splay(卡过)
  • 原文地址:https://www.cnblogs.com/tm2015/p/11313434.html
Copyright © 2011-2022 走看看