• jedis-sentinel原理分析


    原理

    客户端通过连接到哨兵集群,通过发送Protocol.SENTINEL_GET_MASTER_ADDR_BY_NAME 命令,从哨兵机器中

    询问master节点的信息,拿到master节点的ip和端口号以后,再到客户端发起连接。连接以后,需要在客户端建

    立监听机制,当master重新选举之后,客户端需要重新连接到新的master节点

    private HostAndPort initSentinels(Set<String> sentinels, final String masterName) {
    HostAndPort master = null;
    boolean sentinelAvailable = false;
    log.info("Trying to find master from available Sentinels...");
    // 有多个sentinels,遍历这些个sentinels
    for (String sentinel : sentinels) {
    // host:port表示的sentinel地址转化为一个HostAndPort对象。
    final HostAndPort hap = HostAndPort.parseString(sentinel);
    log.fine("Connecting to Sentinel " + hap);
    Jedis jedis = null;
    try {
    // 连接到sentinel
    jedis = new Jedis(hap.getHost(), hap.getPort());
    // 根据masterName得到master的地址,返回一个list,host= list[0], port =// list[1]
    List<String> masterAddr = jedis.sentinelGetMasterAddrByName(masterName);
    // connected to sentinel...
    sentinelAvailable = true;if (masterAddr == null || masterAddr.size() != 2) {
    log.warning("Can not get master addr, master name: " + masterName + ".
    Sentinel: " + hap
    + ".");
    continue;
    }
    // 如果在任何一个sentinel中找到了master,不再遍历sentinels
    master = toHostAndPort(masterAddr);
    log.fine("Found Redis master at " + master);
    break;
    } catch (JedisException e) {
    // resolves #1036, it should handle JedisException there's another chance
    // of raising JedisDataException
    log.warning("Cannot get master address from sentinel running @ " + hap + ".
    Reason: " + e
    + ". Trying next one.");
    } finally {
    if (jedis != null) {
    jedis.close();
    }
    }
    }
    // 到这里,如果master为null,则说明有两种情况,一种是所有的sentinels节点都down掉了,一种是master节
    点没有被存活的sentinels监控到
    if (master == null) {
    if (sentinelAvailable) {
    // can connect to sentinel, but master name seems to not
    // monitored
    throw new JedisException("Can connect to sentinel, but " + masterName
    + " seems to be not monitored...");
    } else {
    throw new JedisConnectionException("All sentinels down, cannot determine where is
    "
    + masterName + " master is running...");
    }
    }
    //如果走到这里,说明找到了master的地址
    log.info("Redis master running at " + master + ", starting Sentinel listeners...");
    //启动对每个sentinels的监听
    //为每个sentinel都启动了一个监听者MasterListener。MasterListener本身是一个线程,它会去订阅sentinel
    上关于master节点地址改变的消息。
    for (String sentinel : sentinels) {
    final HostAndPort hap = HostAndPort.parseString(sentinel);
    MasterListener masterListener = new MasterListener(masterName, hap.getHost(),
    hap.getPort());
    // whether MasterListener threads are alive or not, process can be stopped
    masterListener.setDaemon(true);
    masterListeners.add(masterListener);
    masterListener.start();
    }
    return master;
    }
    从哨兵节点获取master信息的方法

    public List<String> sentinelGetMasterAddrByName(String masterName) {

    
    

    client.sentinel(Protocol.SENTINEL_GET_MASTER_ADDR_BY_NAME, masterName);

    
    

    final List<Object> reply = client.getObjectMultiBulkReply();

    
    

    return BuilderFactory.STRING_LIST.build(reply);

    
    

    }

     
  • 相关阅读:
    访问日志不记录静态文件、访问日志切割、静态元素(文件)过期时间
    apache用户认证、域名跳转、Apache访问日志(两种格式)
    apache 和 php 整合、apache配制虚拟机
    PHP5和PHP7的安装、PHP和apache的整合!
    mariaDB的安装 apache的安装
    lamp 相关mysql的安装
    rsync命令 续集 、linux系统日志、screen工具
    rsync命令
    linux cron计划任务、chkconfig 命令、systemd命令、unit 相关、target 相关
    spark_to_es
  • 原文地址:https://www.cnblogs.com/yintingting/p/11701432.html
Copyright © 2020-2023  润新知