php操作redis哨兵模式,主从切换后自动获取master

亚瑟 等级 615 0 0

本文将介绍如何使用PHP来连接redis哨兵模式。哨兵模式:大概的原理就是监听redis主库心跳包,如果心跳断开,则枚举一个从库推举成为新的主库,防止redis宕机不能使用。为了增强redis的性能,防止其挂掉,引用redis哨兵监控redis集群是个不错的选择。下面三步简单记录php连接redis哨兵。 第一步、获取哨兵模式连接redis句柄对象

/**
 * 哨兵模式连接redis
 * @return array|Redis
 */
function im_cache_redis() {
    global $_W;
    static $im_redisobj;
    $config = $_W['config']['im']['redis'];

    //哨兵节点
    $temp_data = [
        [
            'ip' => '192.168.101.85',
            'port' => 26380
        ],
        [
            'ip' => '192.168.101.85',
            'port' => 26381
        ],
        [
            'ip' => '192.168.101.85',
            'port' => 26382
        ]
    ];

    $address = redis_nodeinfo($temp_data);
    logging_run(__METHOD__ . ':redis哨兵获取主节点地址:' . json_encode($address),LOGGING_INFO);
    $im_redisobj = new Redis();
    try {
        $im_redisobj->connect($address['ip'],intval($address['port']));
        if (!empty($config['auth'])) {
            $auth = $im_redisobj->auth($config['auth']);
        }
    } catch (Exception $e) {
        logging_run(__METHOD__ . ':redis连接失败,错误信息:' . $e->getMessage(),LOGGING_ERROR);
        return error(-1,'im redis连接失败,错误信息:'.$e->getMessage());
    }
   return $im_redisobj;
}

第二步、获取redis哨兵主节点地址

/**
 * 获取redis哨兵主节点地址
 * @param array $temp_data
 * @return array
 */
function redis_nodeinfo($temp_data = []){
    $random = [];
    $ips = [];
    //哨兵节点
    //$temp_data = [['ip'=>'101.36.149.73','port'=>263719],['ip'=>'101.36.149.41','port'=>26379],['ip'=>'101.36.149.189','port'=>26379]];
    for($count=1;$count<count($temp_data);$count++){
        $random[] =$count;
    }
    shuffle($random);
    foreach($random as $key){
        $ips[$temp_data[$key]['ip']]=['port'=>$temp_data[$key]['port']];
    }
    $sentinel = new Sentinel();
    foreach($ips as $ip=>$portinfo){
        try{
            $sentinel->connect($ip, $portinfo['port'],1);
            $address = $sentinel->getMasterAddrByName('mymaster');
            if($address){
                echo '哨兵节点:' .$ip .'正常'. '<br/>';

                return $address;
            }
        }catch(Exception $e){
            echo '哨兵节点:' .$ip .'异常 异常信息:' . $e->getMessage() . '<br/>';
        }
    }
}

第三步、封装Sentinel类

<?php

class Sentinel
{
    /**
     * @var \Redis
     */
    protected $redis;

    public function __construct()
    {
        $this->redis = new Redis();
    }

    public function __destruct()
    {
        try {
            $this->redis->close();
        } catch (\Exception $e) {
        }
    }

    /**
     * @param $host
     * @param int $port
     * @return boolean
     */
    public function connect($host, $port = 26379)
    {
        if (!$this->redis->connect($host, $port)) {
            return false;
        }
        return true;
    }

    /**
     * This command simply returns PONG.
     *
     * @return string STRING: +PONG on success. Throws a RedisException object on connectivity error.
     */
    public function ping()
    {
        return $this->redis->ping();
    }

    /**
     * Show a list of monitored masters and their state.
     *
     * @return array
     */
    public function masters()
    {
        return $this->parseArrayResult($this->redis->rawCommand('SENTINEL', 'masters'));
    }

    /**
     * parse redis response data
     *
     * @param array $data
     * @return array
     */
    private function parseArrayResult(array $data)
    {
        $result = array();
        $count = count($data);
        for ($i = 0; $i < $count;) {
            $record = $data[$i];
            if (is_array($record)) {
                $result[] = $this->parseArrayResult($record);
                $i++;
            } else {
                $result[$record] = $data[$i + 1];
                $i += 2;
            }
        }

        return $result;
    }

    /**
     * Show the state and info of the specified master.
     *
     * @param string $master_name
     * @return array
     */
    public function master($master_name)
    {
        return $this->parseArrayResult($this->redis->rawCommand('SENTINEL', 'master', $master_name));
    }

    /**
     * Show a list of slaves for this master, and their state.
     *
     * @param string $master_name
     * @return array
     */
    public function slaves($master_name)
    {
        return $this->parseArrayResult($this->redis->rawCommand('SENTINEL', 'slaves', $master_name));
    }

    /**
     * Show a list of sentinel instances for this master, and their state.
     *
     * @param string $master_name
     * @return array
     */
    public function sentinels($master_name)
    {
        return $this->parseArrayResult($this->redis->rawCommand('SENTINEL', 'sentinels', $master_name));
    }

    /**
     * Return the ip and port number of the master with that name.
     * If a failover is in progress or terminated successfully
     * for this master it returns the address and port of the promoted slave.
     *
     * @param string $master_name
     * @return array
     */
    public function getMasterAddrByName($master_name)
    {
        $data = $this->redis->rawCommand('SENTINEL', 'get-master-addr-by-name', $master_name);
        return array(
            'ip' => $data[0],
            'port' => $data[1]
        );
    }

    /**
     * This command will reset all the masters with matching name.
     * The pattern argument is a glob-style pattern.
     * The reset process clears any previous state in a master
     * (including a failover in progress), and removes every slave
     * and sentinel already discovered and associated with the master.
     *
     * @param string $pattern
     * @return int
     */
    public function reset($pattern)
    {
        return $this->redis->rawCommand('SENTINEL', 'reset', $pattern);
    }

    /**
     * Force a failover as if the master was not reachable,
     * and without asking for agreement to other Sentinels
     * (however a new version of the configuration will be published
     * so that the other Sentinels will update their configurations).
     *
     * @param string $master_name
     * @return boolean
     */
    public function failOver($master_name)
    {
        return $this->redis->rawCommand('SENTINEL', 'failover', $master_name) === 'OK';
    }

    /**
     * @param string $master_name
     * @return boolean
     */
    public function ckquorum($master_name)
    {
        return $this->checkQuorum($master_name);
    }

    /**
     * Check if the current Sentinel configuration is able to
     * reach the quorum needed to failover a master, and the majority
     * needed to authorize the failover. This command should be
     * used in monitoring systems to check if a Sentinel deployment is ok.
     *
     * @param string $master_name
     * @return boolean
     */
    public function checkQuorum($master_name)
    {
        return $this->redis->rawCommand('SENTINEL', 'ckquorum', $master_name);
    }

    /**
     * Force Sentinel to rewrite its configuration on disk,
     * including the current Sentinel state. Normally Sentinel rewrites
     * the configuration every time something changes in its state
     * (in the context of the subset of the state which is persisted on disk across restart).
     * However sometimes it is possible that the configuration file is lost because of
     * operation errors, disk failures, package upgrade scripts or configuration managers.
     * In those cases a way to to force Sentinel to rewrite the configuration file is handy.
     * This command works even if the previous configuration file is completely missing.
     *
     * @return boolean
     */
    public function flushConfig()
    {
        return $this->redis->rawCommand('SENTINEL', 'flushconfig');
    }

    /**
     * This command tells the Sentinel to start monitoring a new master with the specified name,
     * ip, port, and quorum. It is identical to the sentinel monitor configuration directive
     * in sentinel.conf configuration file, with the difference that you can't use an hostname in as ip,
     * but you need to provide an IPv4 or IPv6 address.
     *
     * @param $master_name
     * @param $ip
     * @param $port
     * @param $quorum
     * @return boolean
     */
    public function monitor($master_name, $ip, $port, $quorum)
    {
        return $this->redis->rawCommand('SENTINEL', 'monitor', $master_name, $ip, $port, $quorum);
    }

    /**
     * is used in order to remove the specified master: the master will no longer be monitored,
     * and will totally be removed from the internal state of the Sentinel,
     * so it will no longer listed by SENTINEL masters and so forth.
     *
     * @param $master_name
     * @return boolean
     */
    public function remove($master_name)
    {
        return $this->redis->rawCommand('SENTINEL', 'remove', $master_name);
    }

    /**
     * The SET command is very similar to the CONFIG SET command of Redis,
     * and is used in order to change configuration parameters of a specific master.
     * Multiple option / value pairs can be specified (or none at all).
     * All the configuration parameters that can be configured via sentinel.conf
     * are also configurable using the SET command.
     *
     * @param $master_name
     * @param $option
     * @param $value
     * @return boolean
     */
    public function set($master_name, $option, $value)
    {
        return $this->redis->rawCommand('SENTINEL', 'set', $master_name, $option, $value);
    }

    /**
     * get last error
     *
     * @return string
     */
    public function getLastError()
    {
        return $this->redis->getLastError();
    }

    /**
     * clear last error
     *
     * @return boolean
     */
    public function clearLastError()
    {
        return $this->redis->clearLastError();
    }

    /**
     * sentinel server info
     *
     * @return string
     */
    public function info()
    {
        return $this->redis->info();
    }

} 

本文转自 https://www.100txy.com/article/261,如有侵权,请联系删除。

收藏
评论区

相关推荐

php指的是什么?
PHP(全称:Hypertext Preprocessor,即“PHP:超文本预处理器”)是一种开源的通用计算机脚本语言,尤其适用于网络开发并可嵌入H
使用PHP生成网站Sitemap,Laravel风格
PHP生成网站Sitemap,包含默认、分类、文章、标签、profile等 <?php namespace AppLibs; use AppS
2017最新PHP经典面试题目汇总(上篇)
2017最新PHP经典面试题目汇总(上篇) 2017最新PHP经典面试题目汇总(上篇) 本文章将持续更新,希望能在评论区发表自己的见解和认为比较经典的题目,后续笔者会在适当的节点对本文章进行分类和层次
Go-连接Redis-学习go-redis包
Redis介绍 Redis是一个开源的内存数据结构存储,常用作数据库、缓存和消息代理。目前它支持的数据结构有诸如string、hash、list、set、zset、bitmap、hyperloglog、geospatial index和stream。Redis内置了复制、Lua脚本、LRU清除、事务和不同级别的磁盘持久性,并通过Redis Sentinel
nginx安全配置
安全是一个重要的问题,必须引起注意。 1. nginx介绍 nginx本身不能处理PHP(http://www.ttlsa.com/php/ "php"),它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端。nginx一般是把请求发fastcgi管理进程处理,fastcgi管理进程选择cgi子
php操作redis哨兵模式,主从切换后自动获取master
本文将介绍如何使用PHP来连接redis哨兵模式。哨兵模式:大概的原理就是监听redis主库心跳包,如果心跳断开,则枚举一个从库推举成为新的主库,防止redis宕机不能使用。为了增强redis的性能,防止其挂掉,引用redis哨兵监控redis集群是个不错的选择。下面三步简单记录php连接redis哨兵。 第一步、获取哨兵模式连接redis句柄对象/
为什么单线程的Redis能支持高并发?
一、Redis为什么是单线程注意:redis 单线程指的是网络请求模块使用了一个线程,即一个线程处理所有网络请求,其他模块仍用了多个线程。因为CPU不是Redis的瓶颈。Redis的瓶颈最有可能是机器内存或者网络带宽,既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。关于redis的性能,官方网站也有,普通笔记本轻松处理每秒几十万
Windows 下编译 PHP Redis 扩展并支持 Igbinary 序列器
这是 PHP 下扩展的下载地址:当然,通过这个地址我们能够轻松的获取到 Redis 和 Igbinary 扩展并启用,但是,我们可以在页面上打开 phpinfo() 瞧瞧上方截图为重编译的 Redis 扩展,默认情况下通过上方网站下载的 Redis 扩展在 Available serializers 中只有 php 一项。目前仅编译了
Redis集群详解
Redis集群详解Redis有三种集群模式,分别是: 主从模式 Sentinel模式 Cluster模式 三种集群模式各有特点,关于Redis介绍可以参考这里:Redis官网:https://redis.io/ ,最新版本5.0.4 主从模式 主从模式介绍主从模式是三种模式中最简单的,在主从复制中,数据库分为两类:主数据库(master)和从数据库(sl
凉凉!面试阿里我被Redis技术专题给搞的昏倒在地~
凉凉!面试阿里我被Redis技术专题给弄死了📚我本以为我可以像是别的博主一样去阿里面试随随便便,因为Redis,我直接被阿里大佬淦翻在地上好了不装了 没过没关系 我总结了一些这些最难的知识点!!!!然后自己总结归类再去百度查询了一些 最终得出这份Redis技术专题 题目开淦 Redis集群的主从复制模型是怎样的?为了是在部分节点失败或者大部分节点无法通信的情
springBoot集成redis
Redis作为一个Java后端面试中的一个常问考点,并且在项目中越来越常用,所以自己动手搭建了一个基于springboot集成redis做为数据缓存的demo(springboot集成mybatis、redis,并具有增删改查询接口)。关注微信公众号【菜鸟阿都】并回复:redis,可获得源码。后面也会继续深入研究redis相关知识,期待与大家一起学习交流。r
给dubbo贡献源码,做梦都在修bug
本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star。 一在之前的文章《redis在微服务领域的贡献》中,从一次面试经历中了解了redis可以在微服务中玩的这么溜,同时也从源码角度分析了dubbo的redis注册中心。最后得出了dubbo的redis注册中心不能用于生产的结论,其中原因有如下两点: 使用了ke
dubbo网关演进之路
本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star。 背景随着公司业务的飞速发展,基于php的模块化架构难以支持未来业务的发展: php模块化架远远落后于行业主流架构(微服务–云原生),而php生态的服务治理开源组件匮乏,研发投入过大 杭州php人才匮乏,导致新鲜血液招聘困难 基于php的多进程架构难以支撑
运维大佬嘲笑我,这个你都不知道?
大家好,我是阿沐,一个喜欢分享技术而且爱好写散文的程序员。今天来给大家介绍一下info命令查看redis具体的详细信息讲解!起因是:前几年我在老家郑州实习面试(那个时候还没有毕业)的时候遇到面试官提问;面试官来于百度总部的工程师6年java开发经验+3年多的PHP开发经验,我在他的面前基本就是弟弟中的弟弟,虽然勉强通过入职了,但是却被运维无情地嘲笑,就因为组
最新Java大厂高频面试题,看这一篇就够了!
常见resdis面试真题40道(含解析)1. 什么是 Redis?2. Redis 的数据类型?3. 使用 Redis 有哪些好处?4. Redis 相比 Memcached 有哪些优势?5. Memcache 与 Redis 的区别都有哪些?6. Redis 是单进程单线程的?7. 一个字符串类型的值能存储最大容量是多少?8. Redis