redis哨兵模式配置,java 哨兵

  redis哨兵模式配置,java 哨兵

  00-1010本文将以文字代码的形式讲解Sentinel在redis版本中的实现。所有代码都将写在一个类中,每个属性和方法都将用文本解释。

  00-1010 1.不定时监控redis节点是否运行良好,如果节点不可达,则注销。

  2.如果识别出的主节点是从节点,sentinel将选举一个redis从节点成为新的主节点,继续对外提供读写服务,实现自动故障转移,保证系统的高可用性。

  3.redis的主、从节点切换后,主配置文件master_redis.conf和从配置文件slave_redis.conf都会发生变化。

  

前言:

Redis集群推荐一主两从,共三个节点。Jedis-2.9.0.jar客户端框架

1. 哨兵(Sentinel)主要功能如下:

JavaSentinel.java

 

  打包com . middleware . redis . sentinels;导入redis . clients . jedis . jedis;导入redis . clients . jedis . jedis pool;导入redis . clients . jedis . jedispoolconfig;导入Java . util . *;/* * * Java Sentry * * @ author 93733 * */Public Class Java Sentry {//Port 127 . 0 . 0 . 1:6379 Static String Master Address= 127 . 0 . 0 . 133606379 主节点;//All slave static final vector string slave servers=new vector string();//broken instance static final vector string badredisservers=new vector string();//连接池对象静态JedisPool jedisPool//连接池配置信息对象private static jedis pool config=new jedis pool config();/* * *配置连接池信息* @return */static {//最大连接数为10 config . setmaxtotal(10);//最大空闲连接数5 config . setmaxidle(5);}/* * * Get jedis实例* @ param * @ return */public jedis new jedis实例(){ return jedis pool . Get resource();} volatile static Java sentinel Java sentinel;/* * *创建一个JavaSentinel对象* @param isOpenSentinel。哨兵是否开启为真,假不开启* @return * * 1)如果哨兵开启,我们创建一个定时任务,延时1秒,每3秒执行一次* 2)每次,任务如下:*//检查主是否能*检查主();*//更新从列表* Update slaves();*//检查中断的实例是否恢复正常* checkBadServer();* * 3)初始化jedisPool对象和javaSentinel对象* */public static synchronized Java sentinel getinstance(boolean为Open sentinel){//Open Java sentinel if(iso pensentinel){//Timer task new Timer()。schedule(newtimertask(){ @ override public void run(){//Check master是否可以Check master();//更新从列表更新

  Slaves();                    // 检测坏掉的实例是否恢复正常                    checkBadServer();                }            }, 1000, 3000);        }        if(null == javaSentinel){            /**             * 初始化redis连接池对象             */            String[] serverInfo = masterAddress.split(":");            String masterHost = serverInfo[0] ;            int masterPort = Integer.parseInt(serverInfo[1]) ;            jedisPool = new JedisPool(config, masterHost, masterPort, 100000);            //初始化当前类对象            javaSentinel = new JavaSentinel();        }        return javaSentinel;    }    /**     * 该方法通过ping 方式, 检验当前redis主节点是否在线     *     * 如若发生异常, 则主节点挂掉, 需要做如下两步:     * 1)如果捕获到了异常证明:  redis节点挂掉, 我们需要将当前主节点address保存到badRedisServers集合中     * 2)调用changeMaster() 方法,选举从节点作为新的主     */    private static void checkMaster() {        // 主从切换        // 检查状态        System.out.println("检查master状态:" + masterAddress);        String masterHost = masterAddress.split(":")[0];        int masterPort = Integer.parseInt(masterAddress.split(":")[1]);        try {            Jedis jedis = new Jedis(masterHost, masterPort);            jedis.ping();            jedis.close();        } catch (Exception e) {            // master挂掉啦            badRedisServers.add(masterAddress);            // 切换master            changeMaster();        }    }    /**     * 切换master     *     * 1) 从slaveRedisServers集合中, 获取一个从节点地址     * 2)通过地址创建jedis对象尝试ping动作,验证器是否在线     * 3)没发生异常,证明在线,我们需要禁用它从死掉master继续同步数据     * 4)修改属性masterAddress 为新选举出来的slave地址     * 5)如果发生异常,则将当前slave存放在badRedisServers集合中, 进入下一次循环重试1-4 动作     * 6)选举成功后,将当前slave从 slaveRedisServers集合中移除掉     *     * 7)遍历slaveRedisServers集合,将其他从节点 主从复制配置更新到刚刚选举出来的新主节点身上     */    private static void changeMaster() {        Iterator<String> iterator = slaveRedisServers.iterator();        while (iterator.hasNext()) {            String slaveAddress = iterator.next();            try {                String slaveHost = slaveAddress.split(":")[0];                int slavePort = Integer.parseInt(slaveAddress.split(":")[1]);                Jedis jedis = new Jedis(slaveHost, slavePort);                /*确保当前从节点在线*/                jedis.ping();                /*禁用当前从节点同步复制*/                jedis.slaveofNoOne();                jedis.close();                masterAddress = slaveAddress;                System.out.println("产生新的master:" + masterAddress);                break;            } catch (Exception e) {                badRedisServers.add(slaveAddress);            } finally {                iterator.remove();            }        }        // 所有slave切到新的master        for (String slave : slaveRedisServers) {            String slaveHost = slave.split(":")[0];            int slavePort = Integer.parseInt(slave.split(":")[1]);            Jedis jedis = new Jedis(slaveHost, slavePort);            jedis.slaveof(masterAddress.split(":")[0], Integer.parseInt(masterAddress.split(":")[1]));            jedis.close();        }    }    /**     * 更新当前所有从节点到 slaveRedisServers中     *     * 1)根据masterAddress 创建主节点Jedis对象     * 2)获取主节点replication配置信息jedis.info("replication");     * 3)根据配置信息, 获取到当前主节点从节点个数     * 4)循环遍历从节点个数, 如果个数大于0, 则清空当前 slaveRedisServers集合     * 5)从配置信息中截取出所有从节点的ip:端口后,放入到 slaveRedisServers集合中     *     */    private static void updateSlaves() {        // 获取所有slave        try {            String masterHost = masterAddress.split(":")[0];            int masterPort = Integer.parseInt(masterAddress.split(":")[1]);            Jedis jedis = new Jedis(masterHost, masterPort);            String info_replication = jedis.info("replication");            // 解析info replication            String[] lines = info_replication.split("rn");            int slaveCount = Integer.parseInt(lines[2].split(":")[1]);            if (slaveCount > 0) {                slaveRedisServers.clear();                for (int i = 0; i < slaveCount; i++) {                    String host = lines[3 + i].split(",")[0].split("=")[1];                    String port = lines[3 + i].split(",")[1].split("=")[1];                    slaveRedisServers.add(host + ":" + port);                }            }            System.out.println("更新slave列表:" + Arrays.toString(slaveRedisServers.toArray(new String[] {})));            jedis.close();        } catch (Exception e) {            e.printStackTrace();            System.out.println("更新slave失败:" + e.getMessage());        }    }    /**     * 检测坏掉的实例是否恢复正常     * 1)如果调用 pint() 没有发生异常, 证明恢复正常     * 2)恢复正常后,先将当前节点主从复制的配置通过slaveof() 挂载当前节点上     * 3)将当前节点地址从 badRedisServers集合中remove()掉, 并添加到 slaveRedisServers集合中。     *      */    private static void checkBadServer() {        // 获取所有slave        Iterator<String> iterator = badRedisServers.iterator();        while (iterator.hasNext()) {            String bad = iterator.next();            try {                String badHost = bad.split(":")[0];                int badPort = Integer.parseInt(bad.split(":")[1]);                Jedis badServer = new Jedis(badHost, badPort);                badServer.ping();                // 如果ping没有问题,则挂在当前的master                badServer.slaveof(masterAddress.split(":")[0], Integer.parseInt(masterAddress.split(":")[1]));                badServer.close();                slaveRedisServers.add(bad);                iterator.remove();                System.out.println(bad + " 恢复正常,当前master:" + masterAddress);            } catch (Exception e) {            }        }    }}到此这篇关于Java实现Redis哨兵的示例代码的文章就介绍到这了,更多相关Java Redis哨兵内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • 关于redis数据库入门详细介绍图片,redis数据库的使用,关于Redis数据库入门详细介绍
  • redis队列操作命令,redis 循环队列
  • redis队列操作命令,redis 循环队列,redis实现简单队列
  • redis部署应用服务器上,redis如何启动服务器
  • redis部署应用服务器上,redis如何启动服务器,搭建Redis服务器步骤详细介绍
  • redis缓存穿透和击穿解决方案,redis缓存穿透,缓存雪崩解决
  • redis缓存穿透和击穿解决方案,redis缓存穿透,缓存雪崩解决,redis缓存穿透解决方法
  • Redis缓存,redis和缓存
  • Redis缓存,redis和缓存,Redis缓存详解
  • redis的配置,启动,操作和关闭方法有哪些,关闭redis的命令,Redis的配置、启动、操作和关闭方法
  • redis的主从配置方法详解图,Redis主从配置
  • redis的主从配置方法详解图,Redis主从配置,redis的主从配置方法详解
  • redis界面工具,mac安装redis可视化工具
  • redis界面工具,mac安装redis可视化工具,推荐几款 Redis 可视化工具(太厉害了)
  • redis正确使用的十个技巧是什么,redis正确使用的十个技巧有哪些
  • 留言与评论(共有 条评论)
       
    验证码: