Blog

2017.01.25 - 번역 - RED Elasticsearch Cluster? Panic no longer ...

drscg 2019. 1. 7. 10:53

Beep… beep… beep…  It’s PagerDuty telling you that a node has gone down, or a rack has gone down, or your whole cluster has just rebooted.  Either way, your cluster is RED: some shards are not assigned, which means that your data is not fully available.

bepp... bepp... bepp... 호출기가 울린다. node 혹은 rack에 장애가 발생했다. 또는 전체 cluster가 reboot 되었다. 어느 쪽이든 cluster가 RED(일부 shard가 할당되지 않았다. 즉, data를 완전히 사용할 수 없다.

Pop quiz hot shot: What do you do?  What do you do?!

Pop quiz hot shot: 어떻게 해야 할까?

In earlier versions of Elasticsearch, figuring out why shards are not being allocated required the analytical skills of a bomb defusion expert.  You’d look through the cluster state API, the cat-shards API, the cat-allocation API, the cat-indices API, the indices-recovery API, the indices-shard-stores API… and wonder what it all means.

Elasticsearch 초기 버전에서는, shard가 할당되지 않은 이유를 알아내기 위해서는 전문가의 분석 기술이 필요했다. cluster state API, cat-shards API, cat-allocation API, cat-indices API, indices-recovery API, indices-shard-stores API 등을 살펴보면, 그 의미가 궁금할 것이다.

Now, we have added the cluster-allocation-explain API: your one stop shop for understanding shard allocation. 

이제, shard allocation을 이해하기 위한, cluster-allocation-explain API 를 추가했다.

The cluster allocation explain API (henceforth referred to as the explain API) was introduced as an experimental API in v5.0 and reworked into its current form in v5.2.  The explain API was designed to answer two fundamental questions:

cluster allocation explain API(이후에는 explain API라고 함)는 v5.0 에서 실험적으로 도입되었고, v5.2 에서 현재 형식으로 다시 작성되었다, explain API는 다음과 같은 2가지 기본 질문에 답하도록 설계되었다.

  1. For unassigned shards: “Why are my shards unassigned?”
    할당되지 않은 shard에 대해 : “shard가 할당되지 않은 이유는?”
  2. For assigned shards: “Why are my shards assigned to this particular node?”
    할당된 shard에 대해 : “이 특정 node애 shard가 할당된 이유는?”

It should be noted that shard allocation problems should be a rare event in the cluster and typically are the result of node and/or cluster configuration problems (e.g. incorrectly setting up filter allocation settings), all nodes holding a valid shard copy having disconnected from the cluster, disk problems, and the like.  But when these problems do occur, a cluster administrator needs the right tools to identify the problem and nurture the cluster back to good health, and that is what the explain API is for.

shard allocation 문제는 잘 일어나지 않는 event이며, 일반적으로 node 또는 cluster 설정 문제(예: filter allocation settings의 잘못된 설정), 유효한 shard 복사본을 가진 node가 cluster에서 완전히 분리되는 경우, disk 문제 등으로 발생한다. 그러나, 이런 문제가 발생하는 경우, cluster 관리자는 문제점을 알아내고, cluster를 정상적인 상태로 되돌릴 수 있는 올바른 tool이 필요한데, 이것이 바로 explain API이다.

The goal of this blog post is to highlight the power of the explain API by going through some examples of how to use it to diagnose shard allocation problems.

이 게시물의 목적은 shard allocation 문제를 진단하는 방법의 몇 가지 예를 통해 explain API 성능을 알아보는 것이다.

What is shard allocation?

Shard allocation is the process of assigning a shard to a node in the cluster.  In order to scale to huge document sets and provide high availability in the face of node failure, Elasticsearch splits an index’s documents into shards, each shard residing on a node in the cluster.  If a primary shard cannot be allocated, the index will be missing data and/or no new documents can be written to the index.  If replica shards cannot be allocated, the cluster is at risk of losing data in the case of permanent failure (e.g. corrupt disks) of the node holding the primary shard.  If shards are allocated but to slower-than-desired nodes, then the shards of high traffic indices will suffer from being located on slower machines and the performance of the cluster will degrade.  Therefore, allocating shards and assigning them to the best node possible is of fundamental importance within Elasticsearch.

shard allocation은 cluster의 node에 shard를 할당하는 process이다. 대용량 document 집합으로 확장하고, node 장애에 대한 고 가용성을 제공하기 위하여, Elasticsearch는 index의 document를 shard로 분할하는데, 각 shard는 cluster의 특정 node에 존재한다. primary shard를 할당할 수 없으면, index는 data가 누락되거나 index에 새로운 document를 쓸 수 없다. replica shard를 할당할 수 없으면, cluster는 primary shard를 가지고 있는 node의 영구적 장애(disk 손상 등)시 data 손실 위험이 있다. shard가 할당되었으나 느린 node에 할당되면, 높은 traffic을 가진 index의 shard가 느린 machine에 위치하게 되어, cluster의 성능이 저하된다. 따라서, shard를 할당하고, 가능한 한 최상의 node에 할당하는 것은 Elasticsearch에 있어 매우 중요하다.

The shard allocation process differs for newly created indices and existing indices.  In both cases, Elasticsearch has two main components at work: allocators and deciders.  Allocators try to find the best (defined below) nodes to hold the shard, and deciders make the decision if allocating to a node is allowed.

shard allocation process는 새로 생성되는 index냐, 기존의 index냐에 따라 다르다. 양쪽 모두, Elasticsearch는 allocator와 decider라는 2가지 핵심적인 요소가 있다. allocator는 shard를 가질 수 있는 최상의 node(아래에 정의된)를 찾고, decider는 node에 할당할 수 있는지를 결정한다.

For newly created indices, the allocator looks for the nodes with the least amount of shards on them and returns a list of nodes sorted by shard weight, with those having the least shard weight appearing first.  Thus, the allocator’s goal for a newly created index is to assign the index’s shards to nodes in a manner that would result in the most balanced cluster.  The deciders then take each node in order and decide if the shard is allowed to be allocated to that node.  For example, if filter allocation rules are set up to prevent node <code>A</code> from holding any shards of index <code>idx</code>, then the <code>filter</code> decider will prevent allocation of <code>idx</code>’s shards to node A, even though it may be ranked first by the allocator as the best node from a cluster balancing perspective.  Note that the allocators only take into account the number of shards per node, not the size of each shard.  It is the job of one of the deciders to prevent allocation to nodes that exceed a certain disk occupancy threshold.

새로 생성된 index의 경우, allocator는 가장 작은 수의 shard를 가진 ndoe를 찾고, shard 비중(가장 작은 shard 비중을 가진 node가 먼저 나오는)으로 정렬된 node의 목록을 반환한다. 따라서, 새로 생성되는 index에 대한 allocator의 목적은 가장 균형잡힌 cluster가 되는 방식으로 node에 index의 shard를 할당하는 것이다. 그런 다음 decider는 각 node를 순서대로 가져와 shard를 해당 node에 할당할 수 있는 여부를 결정한다. 예를 들어, node A 가 index idx 의 shard를 가질 수 없도록 filter allocation rule을 설정한 경우, fil decider는 cluster의 균형 관점에서 최상의 node로 판단되더라도, node A 에 idx 의 shard를 할당하지 못한다. allocator는 각 shard의 크기가 아니라, node당 shard의 수만을 고려한다는 점을 기억하자. 특정 disk 점유 임계치를 초과하는 node에 대한 할당을 방지하는 것이 decider의 역활 중 하나이다.

For existing indices, we must further distinguish between primary and replica shards.  For a primary shard, the allocator will *only* allow allocation to a node that already holds a known good copy of the shard.  If the allocator did not take such a step, then allocating a primary shard to a node that does not already have an up-to-date copy of the shard will result in data loss!  In the case of replica shards, the allocator first looks to see if there are already copies of the shard (even stale copies) on other nodes.  If so, the allocator will prioritize assigning the shard to one of the nodes holding a copy, because the replica needs to get in-sync with the primary once it is allocated, and the fact that a node already has some of the shard data means (hopefully) a lot less data has to be copied over to the replica from the primary.  This can speed up the recovery process for the replica shard significantly.

기존 index의 경우, primary와 replica shard를 추가로 구분해야 한다. primary shard의 경우, allocator는 이미 정상적인 shard 복사본을 가진 node에만 할당할 수 있다. allocator가 이런 단계를 거치지 않고, shard의 최신 복사본을 아직 가지지 않은 node에 primary shard를 할당하면, data의 손실로 이어진다. replica shard의 경우, allocator는 다른 node에 shard의 복사본(오래된 복사본이라도)이 이미 있는지를 확인한다. 있다면,  allocator는 복사본을 가지고 있는 node 중 하나에 shard를 우선적으로 할당한다. 왜냐하면, replica는 할당되자 마자 primary와 동기화를 해야 하고, node가 shard data의 일부를 이미 가지고 있다는 사실은 primary에서 replica로 복사할 data의 양이 훨씬 적기(운이 좋다면) 때문이다. 이렇게 하면 replica shard에 대한 recovery process 가 상당히 빨라질 수 있다.

Diagnosing Unassigned Primary Shards

Having an unassigned primary shard is about the worst thing that can happen in a cluster.  If the unassigned primary is on a newly created index, no documents can be written to that index.  If the unassigned primary is on an existing index, then not only can the index not be written to, but all data previously indexed is unavailable for searching!

할당되지 않은 primary shard가 있다는 것은 cluster에서 발생할 수 있는 최악의 상황이다. 할당되지 않은 primary가 새로 생성된 index에 존재하는 경우, document는 해당 index에 쓸 수 없다. 할당되지 않은 primary가 기존 index에 존재하는 경우, index에 쓸 수 없을뿐 아니라 이전에 index된 모든 data를 search할 수 없다.

Let’s start by creating a new index named test_idx, with 1 shard and 0 replicas per shard, in a two-node cluster (with node names A and B), but assigning filter allocation rules at index creation time so that shards for the index cannot be assigned to nodes A and B.  The following curl command accomplishes this:

2개의 node(node name A 와 B)를 가지는 cluster에 shard별로 1개의 shard와 replica가 없는 test_idx 라는 새로운 index를 생성해 보자. index 생성 시에 filter allocation rule을 할당하여, index에 대한 shard가 node A 와 B 에 할당되지 않도록 하자. 다음 command를 실행하면 된다.

PUT /test_idx?wait_for_active_shards=0 
{ 
   "settings": 
   { 
      "number_of_shards": 1, 
      "number_of_replicas": 0,
      "index.routing.allocation.exclude._name": "A,B" 
   } 
}

Due to the filter allocation rules, the index will be created but none of its shards can be allocated due to the index’s settings prevent allocation to the only two nodes in the cluster.  While this example is contrived and may sound unrealistic, the possibility does exist that due to misconfiguration of the filter settings (perhaps by misspelling the node names), the shards in the index remain unassigned.

filter allocation rule에 따라, index는 생성되지만 index의 설정이 cluster의 2개의 node에만 할당을 막고 있기 때문에 index의 shard는 할당될 수 없다. 이 예제는 부자연스럽고 비현실적이지만, filter 설정이 잘못(아마도 node name의 오타로)되어, index의 shard가 할당되지 않은 채로 남아 있을 가능성이 있다.

At this point, our cluster is in the RED state.  We can get an explanation for the first unassigned shard found in the cluster (in this case, there is only one shard in the cluster which is unassigned) by invoking the explain API with an empty request body:

이 시점에, cluster는 RED state이다. request body가 없는 explain API를 실행해, cluster에서 발견된 첫번째로 할당되지 않은 shard에 대한 설명을 볼 수 있다. 이 경우, cluster에는 할당되지 않은 shard는 하나만 있다.

GET /_cluster/allocation/explain

Which produces the following output:

다음과 같은 출력을 볼 수 있다.

{
  "index" : "test_idx",
  "shard" : 0,
  "primary" : true,
  "current_state" : "unassigned",
  "unassigned_info" : {
    "reason" : "INDEX_CREATED", 
    "at" : "2017-01-16T18:12:39.401Z",
    "last_allocation_status" : "no"
  },
  "can_allocate" : "no",
  "allocate_explanation" : "cannot allocate because allocation is not permitted to any of the nodes",   
  "node_allocation_decisions" : [ 
    {
      "node_id" : "tn3qdPdnQWuumLxVVjJJYQ",
      "node_name" : "A", 
      "transport_address" : "127.0.0.1:9300",
      "node_decision" : "no",
      "weight_ranking" : 1,
      "deciders" : [
        {
          "decider" : "filter",  
          "decision" : "NO", 
          "explanation" : "node matches index setting [index.routing.allocation.exclude.] filters [_name:\"A OR B\"]" 
        }
      ]
    },
    {
      "node_id" : "qNgMCvaCSPi3th0mTcyvKQ",
      "node_name" : "B", 
      "transport_address" : "127.0.0.1:9301",
      "node_decision" : "no",
      "weight_ranking" : 2,
      "deciders" : [
        {
          "decider" : "filter",
          "decision" : "NO",
          "explanation" : "node matches index setting [index.routing.allocation.exclude.] filters [_name:\"A OR B\"]"
        }
      ]
    }
  ]
}
Read Less

The explain API found the primary shard 0 of test_idx to explain, which is in the unassigned state (see "current_state") due to the index having just been created (see "unassigned_info").  The shard cannot be allocated (see "can_allocate") due to none of the nodes permitting allocation of the shard (see "allocate_explanation").  When drilling down to each node’s decision (see "node_allocation_decisions"), we observe that node A received a decision not to allocate (see "node_decision") due to the filter decider (see "decider") preventing allocation with the reason that the filter allocation settings excluded nodes A and B from holding a copy of the shard (see "explanation" inside the "deciders" section).  The explanation also contains the exact setting to change to allow the shard to be allocated in the cluster.

explain API는 test_idx 의 primary shard 0 이 index가 방금 생성("unassigned_info" 참조)되었는데 할당되지 않은 상태("current_state" 참조)라고 설명하고 있다. 모든 node가 할당을 허용하지 않기("can_allocate" 참조) 때문에, shard가 할당될 수 없다. 각 node의 decision 부분("node_allocation_decisions" 참조)을 보면, filter allocation 설정이 node A 와 B 가 shard 복사본을 가지지 못하도록("deciders" 내부의 "explanation" 참조) 하고 있어, filter decider("decider" 참조)가 할당을 막고 있기 때문에, node A 는 할당하지 말라("node_decision" 참조)는 decision을 받았다. 또한, explanation에는 cluster에 shard가 할당되도록 하는 정확한 설정이 포함되어 있다.

Updating the filter allocation settings via:

filter allocation 설정을 다음과 같이 update해 보자.

PUT /test_idx/_settings 
{ 
   "index.routing.allocation.exclude._name": null 
}

And re-running the explain API results in an error message saying

그리고, explain API를 실행해 보면, 다음과 같은 error message가 나온다.

   unable to find any unassigned shards to explain

This is because the only shard for test_idx has now been assigned!  Running the explain API on the primary shard:

이는 test_idx 에 대한 shard가 할당되었기 때문이다. primary shard에 대해 explain API를 실행해 보면

GET /_cluster/allocation/explain 
{ 
   "index": "test_idx", 
   "shard": 0, 
   "primary": true
}

Allows us to see which node the shard was assigned to (output abbreviated):

shard가 할당된 node를 확인할 수 있다.

{
  "index" : "test_idx",
  "shard" : 0,
  "primary" : true,
  "current_state" : "started",
  "current_node" : {
    "id" : "tn3qdPdnQWuumLxVVjJJYQ",
    "name" : "A",
    "transport_address" : "127.0.0.1:9300",
    "weight_ranking" : 1
  },
  …
}

We can see that the shard is now in the started state and assigned to node A (the node that the shard is assigned to may differ when you run it).

이제 shard가 started 상태이고, node A 에 할당되었음을 알 수 있다. (shard가 할당된 node는 실행할 때마다 다를 수 있다.)

Now, let’s index some data into test_index.  After indexing some data, our primary shard has documents in it that we would never want to lose (at least, not without explicitly deleting them).  Next, we will stop node A so that the primary shard is no longer in the cluster.  Since there are no replica copies at the moment, the shard will remain unassigned and the cluster health will be RED.   Rerunning the above explain API command on primary shard 0 will return:

이제, 약간의 data를 test_idx 에 index해 보자. 약간의 data를 index한 후, primary shard는 그 안에 결코 손실되지 않아야 하는 document를 가지고 있다.(최소한 명시적으로 삭제하지 않는다면) 그 다음에는 primary shard가 cluster에 더 이상 남아있지 않도록 node A 를 중지하자. 현재 replica 복사본이 없으므로, shard는 할당되지 않은 채로 유지되고, cluster health는 RED가 될 것이다. primary shard 0 에서 위의 explain API를 다시 실행해 보자.

{
  "index" : "test_idx",
  "shard" : 0,
  "primary" : true,
  "current_state" : "unassigned",
  "unassigned_info" : {             
    "reason" : "NODE_LEFT",    
    "at" : "2017-01-16T17:24:21.157Z",
    "details" : "node_left[qU98BvbtQu2crqXF2ATFdA]",
    "last_allocation_status" : "no_valid_shard_copy"
  },
  "can_allocate" : "no_valid_shard_copy", 
  "allocate_explanation" : "cannot allocate because a previous copy of the primary shard existed but can no longer be found on the nodes in the cluster" 
}

The output tells us that the primary shard is currently unassigned (see "current_state") because the node holding the primary left the cluster (see "unassigned_info").  The reason given to us by the explain API for why the shard cannot be allocated is that there is no longer any valid copy for shard 0 of test_idx in the cluster (see "can_allocate") along with the explanation of why the shard cannot be allocated (see "allocate_explanation").

primary shard를 가진 node가 cluster에 남아있지 않기("unassigned_info" 참조) 때문에, 현재 primary shard는 할당되지 않았음을 출력은 보여준다. shard가 할당될 수 없는 이유는 cluster에 test_idx 의 shard 0 에 대한 유효한 복사본이 없기("can_allocate" 참조) 때문이라고 shard가 할당될 수 없는 이유에 대한 explanation("allocate_explanation" 참조)과 함께 explain API는 보여준다.

By the explain API telling us that there is no longer a valid shard copy for our primary shard, we know we have lost all of the nodes that held a valid shard copy.  At this point, the only recourse is to wait for those nodes to come back to life and rejoin the cluster.  In the odd event that all nodes holding copies of this particular shard are all permanently dead, the only recourse is to use the reroute commands to allocate an empty/stale primary shard and accept the fact that data has been lost.

primary shard에 대한 유효한 shard 복사본이 더 이상 없다는 explain API를 통해, 유효한 shard 복사본을 가진 모든 node가 손실되었음을 알 수 있다. 이 시좀에서 유일한 방법은 해당 node가 다시 작동할 때까지 기다린 후 cluster에 다시 연결되는 것이다. 이 특정 shard의 복사본을 가지고 있는 모든 node가 영구적으로 모두 비활성 상태인 경우, 유일한 방법은 비어있거나 오래된 primary shard를 할당하도록 reroute commands 를 사용하거나 data 손실을 받아들이는 것이다.

Diagnosing Unassigned Replica Shards

Let’s take our existing test_idx and increase the number of replicas to 1:

기존 test_idx 에서 replica의 수를 1로 늘리자.

PUT /test_idx/_settings 
{ 
   "number_of_replicas": 1 
}

This will give us a total of 2 shards for test_idx - the primary for shard 0 and the replica for shard 0.  Since node A already holds the primary, the replica should be allocated to node B, to form a balanced cluster (plus, node Aalready has a copy of the shard).  Running the explain API on the replica shard confirms this:

이렇게 하면 test_idx 에는 shard 0에 대한 primary/replica, 모두 2개의 shard가 존재하게 된다. node A 는 이미 primary를 가지고 있으므로, cluster의 균형(node A 는 이미 shard의 복사본을 가지고 있다)을 이루기 위해서는 replica는 node B 에 할당되어야 한다. replica shard에서 explain API를 실행해 이를 확인해 보자.

GET /_cluster/allocation/explain 
{ 
   "index": "test_idx", 
   "shard": 0, 
   "primary": false 
}

Results in the response:

response는 다름과 같다.

{
  "index" : "test_idx",
  "shard" : 0,
  "primary" : false,
  "current_state" : "started",
  "current_node" : {
    "id" : "qNgMCvaCSPi3th0mTcyvKQ",
    "name" : "B",
    "transport_address" : "127.0.0.1:9301",
    "weight_ranking" : 1
  },
  …
}

The output shows that the shard is in the started state and assigned to node B.

shard는 started 상태이고, node B 에 항당되었다고 보여준다.

Next, we will again set the filter allocation settings on the index, but this time, we will only prevent shard allocation to node B:

그런 다음, index에 filter allocation 설정을 다시 설정하자. 그러나 이번에는, node B 만 shard allocation을 하지 말자.

PUT /test_idx/_settings
{ 
   "index.routing.allocation.exclude._name": "B" 
}

Now, restart node B and re-run the explain API command for the replica shard:

이제, node B 를 다시 시작하고, replica shard에 대해 explain API를 다시 실행하자.

{
  "index" : "test_idx",
  "shard" : 0,
  "primary" : false,
  "current_state" : "unassigned",
  "unassigned_info" : {
    "reason" : "NODE_LEFT",
    "at" : "2017-01-16T19:10:34.478Z",
    "details" : "node_left[qNgMCvaCSPi3th0mTcyvKQ]",
    "last_allocation_status" : "no_attempt"
  },
  "can_allocate" : "no", 
  "allocate_explanation" : "cannot allocate because allocation is not permitted to any of the nodes",
  "node_allocation_decisions" : [
    {
      "node_id" : "qNgMCvaCSPi3th0mTcyvKQ",
      "node_name" : "B",
      "transport_address" : "127.0.0.1:9301",
      "node_decision" : "no",
      "deciders" : [
        {
          "decider" : "filter",  
          "decision" : "NO",
          "explanation" : "node matches index setting [index.routing.allocation.exclude.] filters [_name:\"B\"]" 
        }
      ]
    },
    {
      "node_id" : "tn3qdPdnQWuumLxVVjJJYQ",
      "node_name" : "A",
      "transport_address" : "127.0.0.1:9300",
      "node_decision" : "no",
      "deciders" : [
        {
          "decider" : "same_shard",  
          "decision" : "NO",
          "explanation" : "the shard cannot be allocated to the same node on which a copy of the shard already exists [[test_idx][0], node[tn3qdPdnQWuumLxVVjJJYQ], [P], s[STARTED], a[id=JNODiTgYTrSp8N2s0Q7MrQ]]" 
        }
      ]
    }
  ]
}
Read Less

We learn from this output that the replica shard cannot be allocated (see "can_allocate") because for node B, the filter allocation rules prevented allocation to it (see "explanation" for the filter decider).  Since node A already holds the primary shard, another copy of the shard cannot be assigned to it (see "explanation" for the same shard decider) - Elasticsearch prevents this because there is no point in having two copies of the same data live on the same machine.

node B 의 경우, filter allocation rule이 allocation을 막았기 때문에, replica shard를 할당할 수 없음(filter decider에 대한 "explanation" 참조)을 출력에서 알 수 있다. node A는 이미 primary shard를 가지고 있기 때문에, shard의 또 다른 복사본을 node A에 할당할 수 없다(동일한 shard decider에 대한 "explanation" 참조). Elasticsearch에서는 동일한 machine에 동일한 data에 대한 2개의 복사본이 존재하는 것이 의미가 없으므로, 이를 방지한다.

Diagnosing Assigned Shards

If a shard is assigned, why might you care about its allocation explanation?  One common reason would be that a shard (primary or replica) of an index is allocated to a node, and you just set up filtering rules to move the shard from its current node to another node (perhaps you are trying to make use of the “hot-warm” architecture) but for some reason, the shard remains on its current node.  This is another situation where the explain API can shed light on the shard allocation process.

shard가 할당된 경우, 왜 allocation explanation에 신경을 써야 하는가? 한 가지 일반적인 이유는 index에 shard(primary 또는 replica)가 node에 할당된 후, 그것을 그것의 현재 node에서 다른 node로 옮기기(“hot-warm” architecture를 사용하려는 것일지도) 위해서는 단지 filtering rule만 설정하면 되기 때문이다. 그런데, 어떤 이유로 인해, shard가 그것의 현재 node에 남아 있다. 이것이 explain API가 shard allocation process를 조명할 수 있는 또 다른 상황이다.

Let’s again clear the filter allocation rules so that both primary and replica in our test_idx are assigned:

test_idx 에 primary와 replica가 모두 할당되도록, filter allocation rule을 다시 정리해보자.

PUT /test_idx/_settings 
{ 
    "index.routing.allocation.exclude._name": null 
}

Now, let’s set the filter allocation rules so that the primary shard cannot remain on its current node (in my case, node A):

이제, primary shard가 그것의 현재 node(지금은 node A)에 남아 있을 수 없도록 filter allocation rule을 설정하자.

PUT /test_idx/_settings 
{ 
    "index.routing.allocation.exclude._name": "A"  
}

One might expect at this point that the filter allocation rules will cause the primary to move away from its current node to another node, but in fact it does not.  We can run the explain API on the primary shard to see why:

이 때, filter allocation rule로 인해 primary가 그것의 현재 node에서 다른 node로 이동할 것이라고 예상하겠지만, 실제로는 그렇지 않다. primary shard에서 explain API를 실행해 그 이유를 확인할 수 있다.

GET /_cluster/allocation/explain 
{ 
    "index": "test_idx", 
    "shard": 0, 
    "primary": true 
}

Which results in the response:

response는 다음과 같다.

{
  "index" : "test_idx",
  "shard" : 0,
  "primary" : true,
  "current_state" : "started",
  "current_node" : {
    "id" : "tn3qdPdnQWuumLxVVjJJYQ",
    "name" : "A",  
    "transport_address" : "127.0.0.1:9300"
  },
  "can_remain_on_current_node" : "no", 
  "can_remain_decisions" : [   
    {
      "decider" : "filter",
      "decision" : "NO",
      "explanation" : "node matches index setting [index.routing.allocation.exclude.] filters [_name:\"A\"]"   
    }
  ],
  "can_move_to_other_node" : "no", 
  "move_explanation" : "cannot move shard to another node, even though it is not allowed to remain on its current node",
  "node_allocation_decisions" : [
    {
      "node_id" : "qNgMCvaCSPi3th0mTcyvKQ",
      "node_name" : "B",
      "transport_address" : "127.0.0.1:9301",
      "node_decision" : "no",
      "weight_ranking" : 1,
      "deciders" : [
        {
          "decider" : "same_shard", 
          "decision" : "NO",
          "explanation" : "the shard cannot be allocated to the same node on which a copy of the shard already exists [[test_idx][0], node[qNgMCvaCSPi3th0mTcyvKQ], [R], s[STARTED], a[id=dNgHLTKwRH-Dp-rIX4Hkqg]]" 
        }
      ]
    }
  ]
}
Read Less

Examining the output, we can see that the primary shard is still assigned to node A (see "current_node").  The cluster correctly acknowledges that the shard can no longer remain on its current node (see "can_remain_on_current_node"), with the reason given that the current node matches the filter allocation exclude rules (see "can_remain_decisions").  Despite not being allowed to remain on its current node, the explain API tells us that the shard cannot be allocated to a different node (see "can_move_to_other_node") because, for the only other node in the cluster (node B), that node already contains an active shard copy, and the same shard copy cannot be allocated to the same node more than once (see the explanation for the same shard decider in "node_allocation_decisions").

출력을 살펴보면, primary shard는 여전히 node A 에 할당되어 있음을 알 수 있다("current_node" 참조). 현재 node가 filter allocation exclude rule과 일치한다("can_remain_decisions" 참조)는 이유와 함께 shard가 그것의 현재 node에 더 이상 남아 있을 수 없음("can_remain_on_current_node" 참조)을 cluster는 올바르게 알고 있다. shard의 현재 node에 남아 있을 수는 없지만, cluster의 유일한 다른 node(node B)에 대하여, 해당 node는 이미 활성화된 shard  복사본을 가지고 있고, 동일한 shard 복사본은 동일한 node에 하나 이상 할당될 수 없으므로("node_allocation_decisions"에서 동일한 shard decider에 대한 explanation 참조), shard를 다른 node에 할당할 수 없다("can_move_to_other_node" 참조)고 explain API는 설명하고 있다.

Conclusion

In this blog post, we’ve tried to highlight some of the scenarios where the cluster allocation explain API is very useful at helping an administrator understand the shard allocation process in an Elasticsearch cluster.  There are numerous scenarios that the explain API covers, including showing the node weights to explain why an assigned shard remains on its current node instead of rebalancing to another node.  The explain API is an invaluable tool in diagnosing issues with one’s cluster, and we have already seen big benefits and time savings in using it internally during development as well as diagnosing cluster instabilities for our customers.

이 게시물에서, Elasticsearch cluster에서 cluster allocation explain API가 shard allocation process를 관리자가 이해하는데 매우 유용한 몇 가지 시나리오를 강조하고 싶었다. 다른 node에 균형을 유지하는 대신 할당된 shard를 그것의 현재 node에 남겨두는 이유를 설명하기 위해 node의 가중치를 보여주는 것을 포함해, explain API가 다루는 수많은 시나리오가 있다. explain API는 cluster의 문제점을 진단하는 데 있어 매우 중요한 tool이며, cluster 불안정성 뿐만 아니라 이미 개발 중에도 내부적으로 그것을 사용하여 커다란 이점과 시간을 절약하였다.

원문 : Red Elasticsearch cluster? Panic no longer