瀏覽代碼

Speedup computing cluster health (#78969)

In cases the status is not GREEN.

Instead of building a list of all shard routings and
then counting the total and active number of shards,
use the RoutingNodes (which should already be built)
that can compute these numbers almost for free.

Relates to #77466
Martijn van Groningen 4 年之前
父節點
當前提交
79542a924c

+ 4 - 9
server/src/main/java/org/elasticsearch/cluster/health/ClusterStateHealth.java

@@ -10,7 +10,7 @@ package org.elasticsearch.cluster.health;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.routing.IndexRoutingTable;
 import org.elasticsearch.cluster.routing.IndexRoutingTable;
-import org.elasticsearch.cluster.routing.ShardRouting;
+import org.elasticsearch.cluster.routing.RoutingNodes;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.io.stream.Writeable;
 import org.elasticsearch.common.io.stream.Writeable;
@@ -20,7 +20,6 @@ import java.io.IOException;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Objects;
 
 
@@ -104,13 +103,9 @@ public final class ClusterStateHealth implements Iterable<ClusterIndexHealth>, W
         if (computeStatus.equals(ClusterHealthStatus.GREEN)) {
         if (computeStatus.equals(ClusterHealthStatus.GREEN)) {
             this.activeShardsPercent = 100;
             this.activeShardsPercent = 100;
         } else {
         } else {
-            List<ShardRouting> shardRoutings = clusterState.getRoutingTable().allShards();
-            int activeShardCount = 0;
-            int totalShardCount = 0;
-            for (ShardRouting shardRouting : shardRoutings) {
-                if (shardRouting.active()) activeShardCount++;
-                totalShardCount++;
-            }
+            RoutingNodes routingNodes = clusterState.getRoutingNodes();
+            int activeShardCount = routingNodes.getActiveShardCount();
+            int totalShardCount = routingNodes.getTotalShardCount();
             this.activeShardsPercent = (((double) activeShardCount) / totalShardCount) * 100;
             this.activeShardsPercent = (((double) activeShardCount) / totalShardCount) * 100;
         }
         }
     }
     }

+ 16 - 0
server/src/main/java/org/elasticsearch/cluster/routing/RoutingNodes.java

@@ -72,6 +72,10 @@ public class RoutingNodes implements Iterable<RoutingNode> {
 
 
     private int relocatingShards = 0;
     private int relocatingShards = 0;
 
 
+    private int activeShardCount = 0;
+
+    private int totalShardCount = 0;
+
     private final Map<String, Set<String>> attributeValuesByAttribute = new HashMap<>();
     private final Map<String, Set<String>> attributeValuesByAttribute = new HashMap<>();
     private final Map<String, Recoveries> recoveriesPerNode = new HashMap<>();
     private final Map<String, Recoveries> recoveriesPerNode = new HashMap<>();
 
 
@@ -95,6 +99,7 @@ public class RoutingNodes implements Iterable<RoutingNode> {
             for (IndexShardRoutingTable indexShard : indexRoutingTable) {
             for (IndexShardRoutingTable indexShard : indexRoutingTable) {
                 assert indexShard.primary != null;
                 assert indexShard.primary != null;
                 for (ShardRouting shard : indexShard) {
                 for (ShardRouting shard : indexShard) {
+                    totalShardCount++;
                     // to get all the shards belonging to an index, including the replicas,
                     // to get all the shards belonging to an index, including the replicas,
                     // we define a replica set and keep track of it. A replica set is identified
                     // we define a replica set and keep track of it. A replica set is identified
                     // by the ShardId, as this is common for primary and replicas.
                     // by the ShardId, as this is common for primary and replicas.
@@ -107,6 +112,9 @@ public class RoutingNodes implements Iterable<RoutingNode> {
                             throw new IllegalArgumentException("Cannot have two different shards with same shard id on same node");
                             throw new IllegalArgumentException("Cannot have two different shards with same shard id on same node");
                         }
                         }
                         assignedShardsAdd(shard);
                         assignedShardsAdd(shard);
+                        if (shard.active()) {
+                            activeShardCount++;
+                        }
                         if (shard.relocating()) {
                         if (shard.relocating()) {
                             relocatingShards++;
                             relocatingShards++;
                             // LinkedHashMap to preserve order.
                             // LinkedHashMap to preserve order.
@@ -273,6 +281,14 @@ public class RoutingNodes implements Iterable<RoutingNode> {
         return relocatingShards;
         return relocatingShards;
     }
     }
 
 
+    public int getActiveShardCount() {
+        return activeShardCount;
+    }
+
+    public int getTotalShardCount() {
+        return totalShardCount;
+    }
+
     /**
     /**
      * Returns all shards that are not in the state UNASSIGNED with the same shard
      * Returns all shards that are not in the state UNASSIGNED with the same shard
      * ID as the given shard.
      * ID as the given shard.