Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API to explain why a shard is or isn't assigned #17305

Merged
merged 1 commit into from Mar 28, 2016

Conversation

Projects
None yet
6 participants
@dakrone
Copy link
Member

commented Mar 23, 2016

This adds a new /_cluster/allocation/explain API that explains why a
shard can or cannot be allocated to nodes in the cluster. Additionally,
it will show where the master desires to put the shard, according to
the ShardsAllocator.

It looks like this:

GET /_cluster/allocation/explain?pretty
{
  "index": "only-foo",
  "shard": 0,
  "primary": false
}

Though, you can optionally send an empty body, which means "explain the
allocation for the first unassigned shard you find".

The output when a shard is unassigned looks like this:

{
  "shard" : {
    "index" : "only-foo",
    "index_uuid" : "KnW0-zELRs6PK84l0r38ZA",
    "id" : 0,
    "primary" : false
  },
  "assigned" : false,
  "unassigned_info" : {
    "reason" : "INDEX_CREATED",
    "at" : "2016-03-22T20:04:23.620Z"
  },
  "nodes" : {
    "V-Spi0AyRZ6ZvKbaI3691w" : {
      "node_name" : "Susan Storm",
      "node_attributes" : {
        "bar" : "baz"
      },
      "final_decision" : "NO",
      "weight" : 0.06666675,
      "decisions" : [ {
        "decider" : "filter",
        "decision" : "NO",
        "explanation" : "node does not match index include filters [foo:\"bar\"]"
      } ]
    },
    "Qc6VL8c5RWaw1qXZ0Rg57g" : {
      "node_name" : "Slipstream",
      "node_attributes" : {
        "bar" : "baz",
        "foo" : "bar"
      },
      "final_decision" : "NO",
      "weight" : -1.3833332,
      "decisions" : [ {
        "decider" : "same_shard",
        "decision" : "NO",
        "explanation" : "the shard cannot be allocated on the same node id [Qc6VL8c5RWaw1qXZ0Rg57g] on which it already exists"
      } ]
    },
    "PzdyMZGXQdGhqTJHF_hGgA" : {
      "node_name" : "The Symbiote",
      "node_attributes" : { },
      "final_decision" : "NO",
      "weight" : 2.3166666,
      "decisions" : [ {
        "decider" : "filter",
        "decision" : "NO",
        "explanation" : "node does not match index include filters [foo:\"bar\"]"
      } ]
    }
  }
}

And when the shard is assigned, the output looks like:

{
  "shard" : {
    "index" : "only-foo",
    "index_uuid" : "KnW0-zELRs6PK84l0r38ZA",
    "id" : 0,
    "primary" : true
  },
  "assigned" : true,
  "assigned_node_id" : "Qc6VL8c5RWaw1qXZ0Rg57g",
  "nodes" : {
    "V-Spi0AyRZ6ZvKbaI3691w" : {
      "node_name" : "Susan Storm",
      "node_attributes" : {
        "bar" : "baz"
      },
      "final_decision" : "NO",
      "weight" : 1.4499999,
      "decisions" : [ {
        "decider" : "filter",
        "decision" : "NO",
        "explanation" : "node does not match index include filters [foo:\"bar\"]"
      } ]
    },
    "Qc6VL8c5RWaw1qXZ0Rg57g" : {
      "node_name" : "Slipstream",
      "node_attributes" : {
        "bar" : "baz",
        "foo" : "bar"
      },
      "final_decision" : "CURRENTLY_ASSIGNED",
      "weight" : 0.0,
      "decisions" : [ {
        "decider" : "same_shard",
        "decision" : "NO",
        "explanation" : "the shard cannot be allocated on the same node id [Qc6VL8c5RWaw1qXZ0Rg57g] on which it already exists"
      } ]
    },
    "PzdyMZGXQdGhqTJHF_hGgA" : {
      "node_name" : "The Symbiote",
      "node_attributes" : { },
      "final_decision" : "NO",
      "weight" : 3.6999998,
      "decisions" : [ {
        "decider" : "filter",
        "decision" : "NO",
        "explanation" : "node does not match index include filters [foo:\"bar\"]"
      } ]
    }
  }
}

Only "NO" decisions are returned by default, but all decisions can be
shown by specifying the ?include_yes_decisions=true parameter in the
request.

Resolves #14593

@nik9000

This comment has been minimized.

Copy link
Contributor

commented Mar 23, 2016

   "explanation" : "the shard cannot be allocated on the same node id [Qc6VL8c5RWaw1qXZ0Rg57g] on which it already exists"

Maybe reword this somehow - "there is already a copy of this shard assigned to this node" or something like that.

You example of when the shard is assigned still contains a NO decision which confused me. Can you explain?

@@ -326,17 +326,6 @@
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]cluster[/\\]routing[/\\]allocation[/\\]command[/\\]CancelAllocationCommand.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]cluster[/\\]routing[/\\]allocation[/\\]command[/\\]MoveAllocationCommand.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]cluster[/\\]routing[/\\]allocation[/\\]decider[/\\]AllocationDeciders.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]cluster[/\\]routing[/\\]allocation[/\\]decider[/\\]AwarenessAllocationDecider.java" checks="LineLength" />

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 23, 2016

Contributor

Hurray!

@nik9000

View changes

.../java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequest.java Outdated
this.primary = null;
}

public ClusterAllocationExplainRequest(String index, int shard, boolean primary) {

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 23, 2016

Contributor

Setting primary to false here will just explain the first unassigned non-primary shard, right? Or, er, something like that. Maybe this method deserves some javadoc just to explain that.

This comment has been minimized.

Copy link
@dakrone

dakrone Mar 23, 2016

Author Member

Yes that's correct, if there are multiple replicas, we pick the unassigned one to explain if any are unassigned, otherwise we pick the first assigned replica. I'll add javadoc for this though to clarify that.

@nik9000

View changes

.../java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequest.java Outdated
return this.index;
}

public ClusterAllocationExplainRequest shard(Integer shard) {

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 23, 2016

Contributor

I think we've started to use setShard style here? I'm not totally sure.

@dakrone

This comment has been minimized.

Copy link
Member Author

commented Mar 23, 2016

Maybe reword this somehow - "there is already a copy of this shard assigned to this node" or something like that.

I'd rather leave the wording as-is for now until we determine the right thing to do in #11490, since the criteria for "same node" is likely to be changed/configurable.

You example of when the shard is assigned still contains a NO decision which confused me. Can you explain?

Technically, the shard cannot be assigned to the node it already exists on, because it already exists there (from the allocator point of view). I thought about suppressing "NO" decisions, but decided against it because if cluster.routing.allocation.same_shard.host is configured, it's possible the decision may still be "YES". I opted to change the final_decision to CURRENTLY_ASSIGNED to indicate this.

Integer shard = null;
Boolean primary = null;
XContentParser.Token token;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 23, 2016

Contributor

Maybe use ObjectParser?

This comment has been minimized.

Copy link
@dakrone

dakrone Mar 23, 2016

Author Member

Sure, changed this to use ObjectParser

This comment has been minimized.

Copy link
@dakrone

dakrone Mar 23, 2016

Author Member

Actually, had to revert that as ObjectParser doesn't correctly handle empty objects the way I want it to.

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 23, 2016

Contributor

Sad! Maybe fix it? Or we can split that to another PR if it is scary or
complicated.
On Mar 23, 2016 7:13 PM, "Lee Hinman" notifications@github.com wrote:

In
core/src/main/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequest.java
#17305 (comment)
:

  •    } else {
    
  •        sb.append("index=").append(index);
    
  •        sb.append(",shard=").append(shard);
    
  •        sb.append(",primary?=").append(primary);
    
  •    }
    
  •    sb.append(",includeYesDecisions?=").append(includeYesDecisions);
    
  •    return sb.toString();
    
  • }
  • public static ClusterAllocationExplainRequest parse(XContentParser parser) throws IOException {
  •    String currentFieldName = null;
    
  •    String index = null;
    
  •    Integer shard = null;
    
  •    Boolean primary = null;
    
  •    XContentParser.Token token;
    
  •    while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
    

Actually, had to revert that as ObjectParser doesn't correctly handle
empty objects the way I want it to.


You are receiving this because you commented.
Reply to this email directly or view it on GitHub
https://github.com/elastic/elasticsearch/pull/17305/files/a5ac64ad0be0e841ba2d14689a9aad43c4e66e6b#r57253131

This comment has been minimized.

Copy link
@dakrone

dakrone Mar 24, 2016

Author Member

Yeah I'd prefer to handle it in a separate PR, the code in ObjectParser looks scary at first glance!

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

Fine by me! Can you make an issue explaining it so we don't forget totally? I'd do it but I don't know the problem well enough.

This comment has been minimized.

Copy link
@bleskes

bleskes Mar 24, 2016

Member

the code in ObjectParser looks scary at first glance!

That's no good. Can you please keep notes as to what made you feel that way? it should be the go to place of "no problem, I can parse json settings in a breeze and with confidence"

@nik9000

View changes

...rg/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainRequestBuilder.java Outdated
}

/** The index name to use when finding the shard to explain */
public ClusterAllocationExplainRequestBuilder index(String index) {

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 23, 2016

Contributor

This to maybe is supposed to be setIndex now?

This comment has been minimized.

Copy link
@dakrone

dakrone Mar 23, 2016

Author Member

I changed the settings to be setNNN style

@nik9000

View changes

...ain/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplanation.java Outdated
* A {@code ClusterAllocationExplanation} is an explanation of why a shard may or may not be allocated to nodes. It also includes weights
* for where the shard is likely to be assigned. It is an immutable class
*/
public final class ClusterAllocationExplanation implements ToXContent {

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 23, 2016

Contributor

Maybe implement Writeable and a reading constructor? That seems to be the way we're doing things more and more.

This comment has been minimized.

Copy link
@dakrone

dakrone Mar 23, 2016

Author Member

Sure, changed this.

}

public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(); {

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 23, 2016

Contributor

I like this style. I think I'm going to steal it.

@nik9000

This comment has been minimized.

Copy link
Contributor

commented Mar 23, 2016

Technically, the shard cannot be assigned to the node it already exists on, because it already exists there (from the allocator point of view). I thought about suppressing "NO" decisions, but decided against it because if cluster.routing.allocation.same_shard.host is configured, it's possible the decision may still be "YES". I opted to change the final_decision to CURRENTLY_ASSIGNED to indicate this.

OK - I'm glad it is genuinely confusing not just confusing me. I'll think on it some more and review the rest later.

@nik9000

View changes

...ain/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplanation.java Outdated

/** Return the assigned node id or null if not assigned */
@Nullable
public String assignedNodeId() {

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

Probably should also be getAssignedNodeId.

This comment has been minimized.

Copy link
@dakrone

dakrone Mar 28, 2016

Author Member

Changed this

@nik9000

View changes

...ain/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplanation.java Outdated
}
// If we have unassigned info, show that
if (unassignedInfo != null) {
builder.value(unassignedInfo);

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

It feels weird to have a call to .value at the same level as all the calls to .field. I presume this works because UnassignedInfo writes its field name. Maybe call unassignedInfo.toXContent then? You are more of an expert on this stuff than I am though.

This comment has been minimized.

Copy link
@dakrone

dakrone Mar 28, 2016

Author Member

the .value ends up calling .toXContent, so I don't think there's too much difference anyway? I will change it to be .toXContent though

@nik9000

View changes

...ain/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplanation.java Outdated
this.getShard().writeTo(out);
out.writeBoolean(this.isPrimary());
out.writeOptionalString(this.assignedNodeId());
UnassignedInfo ui = this.getUnassignedInfo();

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

Can probably be writeOptionalWriteable or something like that.

This comment has been minimized.

Copy link
@dakrone

dakrone Mar 28, 2016

Author Member

Sure, changed

@nik9000

View changes

...in/java/org/elasticsearch/cluster/routing/allocation/decider/AwarenessAllocationDecider.java Outdated
"too many shards on node for attribute: [%s], required per attribute: [%d], node count: [%d], leftover: [%d]",
awarenessAttribute, requiredCountPerAttribute, currentNodeCount, leftoverPerAttribute);
"there are too many shards on the node for attribute [%s], there are [%d] total shards for the index " +
" and [%d] total attributes values, expected the node count [%d] to be lower or equal to the required " +

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

Probably should remove the leading space here.

@@ -63,12 +64,16 @@ private void setClusterConcurrentRebalance(int concurrentRebalance) {
@Override
public Decision canRebalance(ShardRouting shardRouting, RoutingAllocation allocation) {
if (clusterConcurrentRebalance == -1) {
return allocation.decision(Decision.YES, NAME, "all concurrent rebalances are allowed");
return allocation.decision(Decision.YES, NAME, "unlimited concurrent rebalances are allowed");

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

++

}
if (freeBytes < freeBytesThresholdHigh.bytes()) {
if (logger.isDebugEnabled()) {
logger.debug("less than the required {} free bytes threshold ({} bytes free) on node {}, shard cannot remain",
freeBytesThresholdHigh, freeBytes, node.nodeId());
}
return allocation.decision(Decision.NO, NAME, "after allocation less than required [%s] free on node, free: [%s]",
return allocation.decision(Decision.NO, NAME,
"after allocating this shard this node would be above the high watermark " +

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

These are all so nice!

@nik9000

View changes

...src/main/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDecider.java Outdated
@@ -600,7 +631,7 @@ private Decision earlyTerminate(RoutingAllocation allocation, ImmutableOpenMap<S
if (logger.isTraceEnabled()) {
logger.trace("cluster info unavailable for disk threshold decider, allowing allocation.");
}
return allocation.decision(Decision.YES, NAME, "cluster info unavailable");
return allocation.decision(Decision.YES, NAME, "the cluster info unavailable");

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

info *is* unavailable I think.

@nik9000

View changes

...g/elasticsearch/rest/action/admin/cluster/allocation/RestClusterAllocationExplainAction.java Outdated

@Override
public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) {
ClusterAllocationExplainRequest req = null;

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

Null initialization feels wrong here because you will always set it. Not initializing req feels more right.

@nik9000

View changes

...g/elasticsearch/rest/action/admin/cluster/allocation/RestClusterAllocationExplainAction.java Outdated
req = ClusterAllocationExplainRequest.parse(parser);
} catch (Exception e) {
logger.error("failed to parse allocation explain request", e);
channel.sendResponse(new BytesRestResponse(ExceptionsHelper.status(e)));

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

I think that you can get away with just letting the exception bubble up and RestController will send it to the user. You won't get the error log but I'm not sure logging an error on 400 level parse errors is a good thing in the long run anyway. I try to usually run requests with error_trace on them so we don't eat the stack trace....

@nik9000

View changes

...est/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDeciderTests.java Outdated
@@ -794,7 +794,9 @@ public void addListener(Listener listener) {
fail("should not have been able to reroute the shard");
} catch (IllegalArgumentException e) {
assertThat("can't allocated because there isn't enough room: " + e.getMessage(),
e.getMessage().contains("more than allowed [70.0%] used disk on node, free: [26.0%]"), equalTo(true));
e.getMessage()

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

Can you change this to assert e.getMessage(), contains(the text) while you are here? That'd make the error message so much more useful.

This comment has been minimized.

Copy link
@dakrone

dakrone Mar 28, 2016

Author Member

Sure, changed this

@nik9000

View changes

rest-api-spec/src/main/resources/rest-api-spec/test/cluster.allocation_explain/10_basic.yaml Outdated
# there aren't any unassigned shards to explain
catch: request
cluster.allocation_explain: {}

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

I'd probably add --- here and make a test case. These are difficult to debug so I take any opportunity I can to split them into smaller and smaller chunks. Totally up to you though.

indices.create:
index: test

- do:

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

Maybe add a comment about how this relies on there only being a single node in the cluster. That is the case for the tests now but if someone tries to run them against a multi node cluster and doesn't understand what the API does they are going to be scratching their heads for a while.

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

Actually this one doesn't require an unassigned shard. So I take that back.

This comment has been minimized.

Copy link
@nik9000

nik9000 Mar 24, 2016

Contributor

Either way these are super sensitive to the cluster layout so maybe just a single comment about that is plenty.

This comment has been minimized.

Copy link
@dakrone

dakrone Mar 28, 2016

Author Member

I added a comment to these tests

@nik9000

This comment has been minimized.

Copy link
Contributor

commented Mar 24, 2016

Left some pretty innocuous questions/notes. If you want to address them and merge on your own time then LGTM.

@ywelsch

This comment has been minimized.

Copy link
Contributor

commented Mar 25, 2016

Good work on this @dakrone (I just quickly glanced at the code, no formal review). As follow-up I would like to see an integration with PrimaryShardAllocator and ReplicaShardAllocator. This would provide insight into the following highly important scenarios (and possibly more):

  • primary shard is unassigned as only stale shard copies available (allocation ids don't match)
  • replica shard unassigned due to delayed shard allocation (node_left.delayed_timeout)
  • primary or replica shard unassigned as shard fetching is still going on (i.e. not all data available yet to decide where to place the shard)
  • replica unassigned as primary is not yet assigned

@dakrone dakrone force-pushed the dakrone:allocation-explain branch Mar 28, 2016

@dakrone dakrone force-pushed the dakrone:allocation-explain branch Mar 28, 2016

@dakrone

This comment has been minimized.

Copy link
Member Author

commented Mar 28, 2016

Good work on this @dakrone

Thanks!

As follow-up I would like to see an integration with PrimaryShardAllocator and ReplicaShardAllocator. This would provide insight into the following highly important scenarios (and possibly more):
primary shard is unassigned as only stale shard copies available (allocation ids don't match)
replica shard unassigned due to delayed shard allocation (node_left.delayed_timeout)
primary or replica shard unassigned as shard fetching is still going on (i.e. not all data available yet to decide where to place the shard)

Definitely! I will open up a followup to work on integrating these things!

replica unassigned as primary is not yet assigned

This is handled by an AllocationDecider and thus is already captured by this work :)

@dakrone dakrone force-pushed the dakrone:allocation-explain branch Mar 28, 2016

Add API to explain why a shard is or isn't assigned
This adds a new `/_cluster/allocation/explain` API that explains why a
shard can or cannot be allocated to nodes in the cluster. Additionally,
it will show where the master *desires* to put the shard, according to
the `ShardsAllocator`.

It looks like this:

```
GET /_cluster/allocation/explain?pretty
{
  "index": "only-foo",
  "shard": 0,
  "primary": false
}
```

Though, you can optionally send an empty body, which means "explain the
allocation for the first unassigned shard you find".

The output when a shard is unassigned looks like this:

```
{
  "shard" : {
    "index" : "only-foo",
    "index_uuid" : "KnW0-zELRs6PK84l0r38ZA",
    "id" : 0,
    "primary" : false
  },
  "assigned" : false,
  "unassigned_info" : {
    "reason" : "INDEX_CREATED",
    "at" : "2016-03-22T20:04:23.620Z"
  },
  "nodes" : {
    "V-Spi0AyRZ6ZvKbaI3691w" : {
      "node_name" : "Susan Storm",
      "node_attributes" : {
        "bar" : "baz"
      },
      "final_decision" : "NO",
      "weight" : 0.06666675,
      "decisions" : [ {
        "decider" : "filter",
        "decision" : "NO",
        "explanation" : "node does not match index include filters [foo:\"bar\"]"
      } ]
    },
    "Qc6VL8c5RWaw1qXZ0Rg57g" : {
      "node_name" : "Slipstream",
      "node_attributes" : {
        "bar" : "baz",
        "foo" : "bar"
      },
      "final_decision" : "NO",
      "weight" : -1.3833332,
      "decisions" : [ {
        "decider" : "same_shard",
        "decision" : "NO",
        "explanation" : "the shard cannot be allocated on the same node id [Qc6VL8c5RWaw1qXZ0Rg57g] on which it already exists"
      } ]
    },
    "PzdyMZGXQdGhqTJHF_hGgA" : {
      "node_name" : "The Symbiote",
      "node_attributes" : { },
      "final_decision" : "NO",
      "weight" : 2.3166666,
      "decisions" : [ {
        "decider" : "filter",
        "decision" : "NO",
        "explanation" : "node does not match index include filters [foo:\"bar\"]"
      } ]
    }
  }
}
```

And when the shard *is* assigned, the output looks like:

```
{
  "shard" : {
    "index" : "only-foo",
    "index_uuid" : "KnW0-zELRs6PK84l0r38ZA",
    "id" : 0,
    "primary" : true
  },
  "assigned" : true,
  "assigned_node_id" : "Qc6VL8c5RWaw1qXZ0Rg57g",
  "nodes" : {
    "V-Spi0AyRZ6ZvKbaI3691w" : {
      "node_name" : "Susan Storm",
      "node_attributes" : {
        "bar" : "baz"
      },
      "final_decision" : "NO",
      "weight" : 1.4499999,
      "decisions" : [ {
        "decider" : "filter",
        "decision" : "NO",
        "explanation" : "node does not match index include filters [foo:\"bar\"]"
      } ]
    },
    "Qc6VL8c5RWaw1qXZ0Rg57g" : {
      "node_name" : "Slipstream",
      "node_attributes" : {
        "bar" : "baz",
        "foo" : "bar"
      },
      "final_decision" : "CURRENTLY_ASSIGNED",
      "weight" : 0.0,
      "decisions" : [ {
        "decider" : "same_shard",
        "decision" : "NO",
        "explanation" : "the shard cannot be allocated on the same node id [Qc6VL8c5RWaw1qXZ0Rg57g] on which it already exists"
      } ]
    },
    "PzdyMZGXQdGhqTJHF_hGgA" : {
      "node_name" : "The Symbiote",
      "node_attributes" : { },
      "final_decision" : "NO",
      "weight" : 3.6999998,
      "decisions" : [ {
        "decider" : "filter",
        "decision" : "NO",
        "explanation" : "node does not match index include filters [foo:\"bar\"]"
      } ]
    }
  }
}
```

Only "NO" decisions are returned by default, but all decisions can be
shown by specifying the `?include_yes_decisions=true` parameter in the
request.

Resolves #14593

@dakrone dakrone force-pushed the dakrone:allocation-explain branch to 80ab366 Mar 28, 2016

@dakrone dakrone merged commit 80ab366 into elastic:master Mar 28, 2016

1 check passed

CLA Commit author has signed the CLA
Details

dakrone added a commit to dakrone/elasticsearch that referenced this pull request Mar 31, 2016

@dakrone dakrone deleted the dakrone:allocation-explain branch May 13, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.