zoukankan      html  css  js  c++  java
  • Solr4.8.0源码分析(26)之Recovery失败造成的宕机原因分析

    最近在公司做SolrCloud的容灾测试,刚好碰到了一个比较蛋疼的问题,跟SolrCloud的Recovery和leader选举有关,正好拿出来分析下。

    现象是这样的:比如我有一台3个shard的SolrCloud,每一个shard又有一个leader和replica。由于SolrCloud的leader选举策略,造成了IP1中同时出现了shard1和shard2的leader。

    这个时候往collection update数据进去,以shard1为例,数据转发过程,IP1_leader –> IP2_replica。 在前文Recovery策略中介绍过,在这个数据转发过程中,如果IP1_leader没有收到IP2_replica的success反应,就会发送recovery命令到IP2_replica,使得IP2_replica触发recovery。那么现在我把IP2服务器关掉一会,此时数据仍然会往shard1打入,仍然会往IP1_leader update数据,但是不会往IP2_replica。过几分钟后,我重新启动IP2服务器,这个时候IP2_replica就会进行版本检查,发现跟IP1_leader commit版本不一致,随机就触发recovery。这个时候,我立马把IP1服务器关掉,即IP1_leader就是down了。此时SolrCloud会出现什么现象呢?由于IP2_replica正在进行recovery,它会从IP1_leader下载索引文件,这个时候IP1_leader处于down了,那么IP2_replica就无法获取需要recovery的索引文件了,因此在尝试多次recovery后,IP2_replica就会处于recovery_failed状态。又由于本来shard1的leader down了,会触发IP2_replica重新进行选举,但是由于IP2_replica处于recovery_failed状态而无法选举为leader,所以此时SolrCloud的shard1就会处于没有leader的,那么SolrCloud就会处于宕机状态。

      private boolean shouldIBeLeader(ZkNodeProps leaderProps, SolrCore core, boolean weAreReplacement) {
        log.info("Checking if I should try and be the leader.");
    
        if (isClosed) {
          log.info("Bailing on leader process because we have been closed");
          return false;
        }
    
        if (!weAreReplacement) {
          // we are the first node starting in the shard - there is a configurable wait
          // to make sure others participate in sync and leader election, we can be leader
          return true;
        }
    
        if (core.getCoreDescriptor().getCloudDescriptor().getLastPublished()
            .equals(ZkStateReader.ACTIVE)) {
          log.info("My last published State was Active, it's okay to be the leader.");
          return true;
        }
        log.info("My last published State was "
            + core.getCoreDescriptor().getCloudDescriptor().getLastPublished()
            + ", I won't be the leader.");
        // TODO: and if no one is a good candidate?
    
        return false;
      }

    至于解决方法,目前没想到十分有效的,我能想得是两个:

    1. 重启整个集群。

    2. 源码上修改。

    等有具体的有效的方法时候再写。

  • 相关阅读:
    行转列,列转行
    聚合函数:sum,count,max,avg
    row_number() over partition by 分组聚合
    mysql优化
    hive中not in优化
    DBCP数据库连接池的简单使用
    Eclipse或MyEclipse中给第三方jar包添加源码步骤
    Java中CountDownLatch类的使用
    PLSQL Developer安装、配置、连接oracle数据库
    oracle11g卸载(win10)
  • 原文地址:https://www.cnblogs.com/rcfeng/p/4287030.html
Copyright © 2011-2022 走看看