클러스터 할당 설명 API
클러스터 할당 설명 API (Cluster Allocation Explain API)
샤드가 왜 특정 노드에 할당됐는지, 혹은 왜 아직 할당되지 않았는지 궁금했던 적 있으신가요? 클러스터 할당 설명 API가 바로 그 이유를 자세히 알려줘요. 샤드 할당 문제를 진단하고 해결할 때 아주 유용한 도구예요.
출처: 문서
본문
1.0에서 도입
클러스터 할당 설명 API는 클러스터의 샤드 할당에 대한 상세한 설명을 제공해요. 이 API를 사용해 샤드 할당 문제를 해결하고 진단할 수 있어요.
이 API는 특히 다음 상황에서 유용해요.
- 샤드가 unassigned 상태로 남아 어떤 노드에도 할당되지 못하는 이유를 이해할 때
- 특정 샤드가 다른 노드가 아닌 그 노드에 할당된 이유를 파악할 때
- 샤드가 다른 노드로 리밸런싱되지 않고 현재 노드에 남아 있는 이유를 알 때
- 할당 설정과 필터가 의도대로 작동하는지 확인할 때
요청 본문 없이 호출하면 API가 첫 번째 unassigned 샤드를 찾아 할당되지 못하는 이유를 설명해요. 특정 샤드 정보를 지정해서 호출하면 해당 샤드의 할당 세부 정보를 제공해요.
엔드포인트
GET /_cluster/allocation/explain
POST /_cluster/allocation/explain
쿼리 파라미터
다음 표는 사용 가능한 쿼리 파라미터예요. 모든 쿼리 파라미터는 선택적이에요.
| Parameter | Data type | Description |
|---|---|---|
| include_disk_info | Boolean | true면 디스크 사용량과 샤드 크기 정보를 반환해요. (기본값: false) |
| include_yes_decisions | Boolean | true면 할당 설명에서 YES 결정도 반환해요. YES 결정은 주어진 노드에 대한 특정 샤드 할당 시도가 성공했음을 나타내요. (기본값: false) |
요청 본문 필드
설명을 생성할 인덱스, 샤드, primary 플래그예요. 이 항목을 비워 두면 첫 번째 unassigned 샤드에 대한 설명을 생성해요.
요청 본문은 선택적이며, 다음 필드를 가진 JSON 객체예요.
| Property | Data type | Description |
|---|---|---|
| current_node | String | 지정된 노드에 현재 위치한 샤드만 설명하도록 노드 ID나 노드 이름을 지정해요. |
| index | String | 설명을 생성할 샤드가 포함된 인덱스 이름이에요. |
| primary | Boolean | true면 노드 ID를 기준으로 primary 샤드에 대한 라우팅 설명을 반환해요. |
| shard | Integer | 설명을 원하는 샤드의 ID를 지정해요. |
예시 요청
GET /_cluster/allocation/explain?include_yes_decisions=true
{
"index": "movies",
"shard": 0,
"primary": true
}
예시 응답
다음 응답은 클러스터의 다른 노드에 대한 할당 결정과 함께 할당된 primary 샤드를 보여줘요.
{
"index": "movies",
"shard": 0,
"primary": true,
"current_state": "started",
"current_node": {
"id": "d8jRZcW1QmCBeVFlgOJx5A",
"name": "opensearch-node1",
"transport_address": "172.24.0.4:9300",
"weight_ranking": 1
},
"can_remain_on_current_node": "yes",
"can_rebalance_cluster": "yes",
"can_rebalance_to_other_node": "no",
"rebalance_explanation": "cannot rebalance as no target node exists that can both allocate this shard and improve the cluster balance",
"node_allocation_decisions": [{
"node_id": "vRxi4uPcRt2BtHlFoyCyTQ",
"node_name": "opensearch-node2",
"transport_address": "172.24.0.3:9300",
"node_decision": "no",
"weight_ranking": 1,
"deciders": [{
"decider": "max_retry",
"decision": "YES",
"explanation": "shard has no previous failures"
},
{
"decider": "replica_after_primary_active",
"decision": "YES",
"explanation": "shard is primary and can be allocated"
},
{
"decider": "enable",
"decision": "YES",
"explanation": "all allocations are allowed"
},
{
"decider": "node_version",
"decision": "YES",
"explanation": "can relocate primary shard from a node with version [1.0.0] to a node with equal-or-newer version [1.0.0]"
},
{
"decider": "snapshot_in_progress",
"decision": "YES",
"explanation": "no snapshots are currently running"
},
{
"decider": "restore_in_progress",
"decision": "YES",
"explanation": "ignored as shard is not being recovered from a snapshot"
},
{
"decider": "filter",
"decision": "YES",
"explanation": "node passes include/exclude/require filters"
},
{
"decider": "same_shard",
"decision": "NO",
"explanation": "a copy of this shard is already allocated to this node [[movies][0], node[vRxi4uPcRt2BtHlFoyCyTQ], [R], s[STARTED], a[id=x8w7QxWdQQa188HKGn0iMQ]]"
},
{
"decider": "disk_threshold",
"decision": "YES",
"explanation": "enough disk for shard on node, free: [35.9gb], shard size: [15.1kb], free after allocating shard: [35.9gb]"
},
{
"decider": "throttling",
"decision": "YES",
"explanation": "below shard recovery limit of outgoing: [0 < 2] incoming: [0 < 2]"
},
{
"decider": "shards_limit",
"decision": "YES",
"explanation": "total shard limits are disabled: [index: -1, cluster: -1] <= 0"
},
{
"decider": "awareness",
"decision": "YES",
"explanation": "allocation awareness is not enabled, set cluster setting [cluster.routing.allocation.awareness.attributes] to enable it"
}
]
}]
}
예시: 첫 번째 unassigned 샤드 설명하기
OpenSearch가 찾은 첫 번째 unassigned 샤드에 대한 설명을 얻으려면 빈 요청 본문을 보내요.
POST /_cluster/allocation/explain
{}
예시 응답
다음 응답은 단일 노드 클러스터의 unassigned replica 샤드를 보여줘요.
{
"index" : "research_papers",
"shard" : 0,
"primary" : false,
"current_state" : "unassigned",
"unassigned_info" : {
"reason" : "CLUSTER_RECOVERED",
"at" : "2026-02-17T16:43:13.339Z",
"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" : "KfEEGG7_SsKZVFqI4ko2FA",
"node_name" : "opensearch-node1",
"transport_address" : "172.18.0.2:9300",
"node_attributes" : {
"shard_indexing_pressure_enabled" : "true"
},
"node_decision" : "no",
"deciders" : [
{
"decider" : "same_shard",
"decision" : "NO",
"explanation" : "a copy of this shard is already allocated to this node [[research_papers][0], node[KfEEGG7_SsKZVFqI4ko2FA], [P], s[STARTED], a[id=SfxnuSLESQSI0Htcv0N3vA]]"
}
]
}
]
}
응답에는 다음 필드가 포함돼요.
current_state: 샤드가unassigned상태예요.unassigned_info.reason: 샤드가 클러스터 복구 중(CLUSTER_RECOVERED) unassigned가 됐어요.can_allocate: 사용 가능한 노드에 샤드를 할당할 수 없어no로 설정돼요.node_decision: 클러스터의 유일한 노드에 대해no로 설정돼요.decider: primary 샤드가 이미 이 노드에 있기 때문에same_shard할당자가 할당을 차단해요.
이것은 OpenSearch가 primary와 그 replica가 같은 노드에 공존하는 것을 허용하지 않기 때문에, replica 샤드를 할당할 수 없는 단일 노드 클러스터의 전형적인 상황이에요.
예시: 특정 할당된 샤드 설명하기
할당된 샤드가 왜 현재 노드에 남아 있는지 이해하려면 샤드 세부 정보를 지정해요.
POST /_cluster/allocation/explain
{
"index": "books",
"shard": 0,
"primary": true
}
예시 응답
{
"index" : "books",
"shard" : 0,
"primary" : true,
"current_state" : "started",
"current_node" : {
"id" : "KfEEGG7_SsKZVFqI4ko2FA",
"name" : "opensearch-node1",
"transport_address" : "172.18.0.2:9300",
"attributes" : {
"shard_indexing_pressure_enabled" : "true"
},
"weight_ranking" : 1
},
"can_remain_on_current_node" : "yes",
"can_rebalance_cluster" : "no",
"can_rebalance_cluster_decisions" : [
{
"decider" : "rebalance_only_when_active",
"decision" : "NO",
"explanation" : "rebalancing is not allowed until all replicas in the cluster are active"
},
{
"decider" : "cluster_rebalance",
"decision" : "NO",
"explanation" : "the cluster has unassigned shards and cluster setting [cluster.routing.allocation.allow_rebalance] is set to [indices_all_active]"
}
],
"can_rebalance_to_other_node" : "no",
"rebalance_explanation" : "rebalancing is not allowed"
}
응답에는 다음 필드가 포함돼요.
current_state: 샤드가started상태로 정상 작동 중이에요.current_node: 이 샤드를 호스팅하는 노드에 대한 세부 정보를 포함해요.can_remain_on_current_node: 샤드가 현재 노드에 남는 것을 허용하므로yes로 설정돼요.can_rebalance_cluster: 클러스터에 unassigned 샤드가 있으면 리밸런싱이 비활성화되므로no로 설정돼요.can_rebalance_cluster_decisions: 리밸런싱을 막는 decider 목록을 보여줘요.
예시: 디스크 정보 포함하기
include_disk_info 파라미터로 상세한 디스크 사용량 통계를 얻을 수 있어요.
POST /_cluster/allocation/explain?include_disk_info=true
{
"index": "books",
"shard": 0,
"primary": true
}
예시 응답
응답에 디스크 사용량과 샤드 크기 세부 정보가 있는 추가 cluster_info가 포함돼요.
{
"index" : "books",
"shard" : 0,
"primary" : true,
"current_state" : "started",
"current_node" : {
"id" : "KfEEGG7_SsKZVFqI4ko2FA",
"name" : "opensearch-node1",
"transport_address" : "172.18.0.2:9300",
"attributes" : {
"shard_indexing_pressure_enabled" : "true"
},
"weight_ranking" : 1
},
"cluster_info" : {
"nodes" : {
"KfEEGG7_SsKZVFqI4ko2FA" : {
"node_name" : "opensearch-node1",
"least_available" : {
"path" : "/usr/share/opensearch/data/nodes/0",
"total_bytes" : 62671097856,
"used_bytes" : 14324834304,
"free_bytes" : 48346263552,
"free_disk_percent" : 77.1,
"used_disk_percent" : 22.9
},
"most_available" : {
"path" : "/usr/share/opensearch/data/nodes/0",
"total_bytes" : 62671097856,
"used_bytes" : 14324834304,
"free_bytes" : 48346263552,
"free_disk_percent" : 77.1,
"used_disk_percent" : 22.9
},
"node_resource_usage_stats" : {
"KfEEGG7_SsKZVFqI4ko2FA" : {
"timestamp" : 1771438387501,
"cpu_utilization_percent" : "0.5",
"memory_utilization_percent" : "57.9",
"io_usage_stats" : {
"max_io_utilization_percent" : "0.0"
}
}
}
}
},
"shard_sizes" : {
"[books][0][p]_bytes" : 5312,
"[movies][0][p]_bytes" : 4862,
"[research_papers][0][p]_bytes" : 7367
},
"shard_paths" : {
"[books][0], node[KfEEGG7_SsKZVFqI4ko2FA], [P], s[STARTED], a[id=Vu7arTEfRrG9lnikaClzDg]" : "/usr/share/opensearch/data/nodes/0",
"[movies][0], node[KfEEGG7_SsKZVFqI4ko2FA], [P], s[STARTED], a[id=f9QNud7NSACyM0YedYGfDg]" : "/usr/share/opensearch/data/nodes/0",
"[research_papers][0], node[KfEEGG7_SsKZVFqI4ko2FA], [P], s[STARTED], a[id=SfxnuSLESQSI0Htcv0N3vA]" : "/usr/share/opensearch/data/nodes/0"
},
"reserved_sizes" : [ ]
},
"can_remain_on_current_node" : "yes",
"can_rebalance_cluster" : "no",
"can_rebalance_cluster_decisions" : [
{
"decider" : "rebalance_only_when_active",
"decision" : "NO",
"explanation" : "rebalancing is not allowed until all replicas in the cluster are active"
},
{
"decider" : "cluster_rebalance",
"decision" : "NO",
"explanation" : "the cluster has unassigned shards and cluster setting [cluster.routing.allocation.allow_rebalance] is set to [indices_all_active]"
}
],
"can_rebalance_to_other_node" : "no",
"rebalance_explanation" : "rebalancing is not allowed"
}
cluster_info 객체는 다음을 제공해요.
nodes: 각 노드의 디스크 사용량 통계(여유/사용 디스크 공간 비율, 리소스 사용률(CPU, 메모리, I/O))를 포함해요.shard_sizes: 클러스터의 각 샤드 크기를 바이트 단위로 보여줘요(응답은 샘플이며 실제 응답은 모든 샤드를 포함해요).shard_paths: 각 샤드가 노드에 저장된 파일 시스템 경로예요(응답은 샘플이며 실제 응답은 모든 샤드를 포함해요).reserved_sizes: 진행 중인 샤드 작업을 위해 예약된 디스크 공간이에요.
이 정보는 디스크 관련 할당 문제를 진단하거나 디스크 공간이 할당 결정에 미치는 영향을 이해할 때 유용해요.
예시: current_node로 노드 지정하기
current_node 파라미터로 샤드가 특정 노드에 있을 때만 설명을 얻을 수 있어요.
POST /_cluster/allocation/explain
{
"index": "books",
"shard": 0,
"primary": false,
"current_node": "opensearch-node1"
}
이 쿼리는 books 인덱스의 replica 샤드 0이 현재 opensearch-node1 노드에 있을 때만 설명을 반환해요. 샤드가 다른 노드에 있거나 unassigned 상태라면 API는 오류를 반환해요.
응답 필드
API는 샤드가 할당됐는지 여부에 따라 다른 필드를 반환해요.
공통 응답 필드
다음 표는 공통 응답 필드예요.
| Field | Description |
|---|---|
| index | 샤드가 포함된 인덱스 이름이에요. |
| shard | 인덱스 내의 샤드 ID예요. |
| primary | primary 샤드(true)인지 replica 샤드(false)인지 여부예요. |
| current_state | 샤드의 현재 상태예요: started, unassigned, initializing, relocating. |
할당된 샤드의 필드
다음 표는 할당된 샤드의 응답 필드예요.
| Field | Description |
|---|---|
| current_node | 샤드가 현재 할당된 노드의 정보로, 노드 ID, 이름, transport 주소, 사용자 정의 속성을 포함해요. |
| can_remain_on_current_node | 샤드가 현재 노드에 남을 수 있는지 여부예요: yes, no, decision_not_taken. |
| can_rebalance_cluster | 클러스터에서 리밸런싱이 허용되는지 여부예요: yes, no, decision_not_taken. |
| can_rebalance_to_other_node | 샤드를 다른 노드로 리밸런싱할 수 있는지 여부예요: yes 또는 no. |
| rebalance_explanation | 리밸런싱 결정에 대한 사람이 읽을 수 있는 설명이에요. |
| can_remain_decisions | 샤드가 현재 노드에 남을 수 있는지 결정한 decider 배열이에요. can_remain_on_current_node가 no일 때만 포함돼요. |
| can_rebalance_cluster_decisions | 클러스터 리밸런싱 허용 여부를 결정한 decider 배열이에요. can_rebalance_cluster가 no일 때만 포함돼요. |
| node_allocation_decisions | 각 노드에 대한 할당 결정이 있는 잠재적 대상 노드 배열이에요. |
unassigned 샤드의 필드
다음 표는 unassigned 샤드의 응답 필드예요.
| Field | Description |
|---|---|
| unassigned_info | 샤드가 unassigned인 이유, 타임스탬프, 마지막 할당 시도를 포함한 정보예요. |
| unassigned_info.reason | INDEX_CREATED, CLUSTER_RECOVERED, NODE_LEFT, REPLICA_ADDED 같은 샤드가 unassigned가 된 이유예요. |
| unassigned_info.at | 샤드가 unassigned가 된 타임스탬프(ISO 8601 형식)예요. |
| unassigned_info.last_allocation_status | 마지막 할당 시도의 결과예요: no_attempt, no, throttled, no_valid_shard_copy. |
| unassigned_info.details | 샤드가 unassigned가 된 추가 세부 정보예요. 추가 정보가 있을 때만 포함돼요. |
| can_allocate | 샤드 할당 가능 여부예요: yes, no, throttled, no_valid_shard_copy, allocation_delayed. |
| allocate_explanation | 샤드를 할당할 수 없는 이유에 대한 사람이 읽을 수 있는 설명이에요. |
| configured_delay | 샤드를 할당하기 전에 설정된 지연이에요. can_allocate가 allocation_delayed일 때만 포함돼요. |
| configured_delay_in_millis | 밀리초 단위의 설정된 지연이에요. can_allocate가 allocation_delayed일 때만 포함돼요. |
| remaining_delay | 샤드를 할당할 수 있을 때까지 남은 시간이에요. can_allocate가 allocation_delayed일 때만 포함돼요. |
| remaining_delay_in_millis | 밀리초 단위의 남은 지연이에요. can_allocate가 allocation_delayed일 때만 포함돼요. |
| node_allocation_decisions | 각 노드에 대한 할당 결정이 있는 노드 배열이에요. |
노드 할당 결정 필드
다음 표는 노드 할당 결정 배열의 필드예요.
| Field | Description |
|---|---|
| node_id | 노드의 고유 식별자예요. |
| node_name | 노드의 이름이에요. |
| transport_address | 노드의 transport 주소예요. |
| node_attributes | Availability Zone이나 인스턴스 유형 같은 노드에 할당된 사용자 정의 속성이에요. |
| node_decision | 이 노드에 대한 할당 결정이에요: yes, no, throttled, worse_balance, awaiting_info. |
| weight_ranking | 할당 결정에서 이 노드의 상대적 가중치 순위예요. 값이 낮을수록 선호도가 높아요. 노드가 할당 결정에 대해 순위가 매겨질 때만 포함돼요. |
| deciders | 이 노드에 샤드를 할당할지 결정한 할당자 배열이에요. |
| store | 노드에서 찾은 샤드 데이터 정보예요(replica 샤드용). matching_size와 matching_size_in_bytes를 포함해요. 샤드 스토어 정보가 있을 때만 포함돼요. |
Decider 필드
deciders 배열의 각 decider에는 다음 필드가 포함돼요.
| Field | Description |
|---|---|
| decider | 결정을 내린 할당자의 이름이에요. |
| decision | 할당자가 내린 결정이에요: YES, NO, THROTTLE. |
| explanation | 관련 설정이나 제약을 포함해 할당자가 이 결정을 내린 이유에 대한 상세한 설명이에요. |
일반적인 할당자 (Common allocators)
샤드 할당 결정에 영향을 주는 일반적인 할당자는 다음 표와 같아요.
| Allocator | Description |
|---|---|
| same_shard | primary 샤드와 그 replica가 같은 노드에 할당되는 것을 방지해요. |
| disk_threshold | low/high watermark 임계값을 기준으로 노드에 샤드를 위한 충분한 디스크 공간이 있는지 확인해요. |
| filter | index.routing.allocation.include, exclude, require 같은 인덱스 설정을 기반으로 할당 필터를 적용해요. |
| awareness | 노드 속성을 기반으로 샤드 할당 awareness를 강제하고, Availability Zone이나 rack에 걸쳐 샤드를 분산해요. |
| enable | cluster.routing.allocation.enable 설정을 사용해 클러스터, 인덱스, 또는 샤드 수준에서 샤드 할당 활성화 여부를 확인해요. |
| throttling | cluster.routing.allocation.node_concurrent_recoveries를 기준으로 동시 샤드 복구 수를 제한해요. |
| shards_limit | 노드당 최대 샤드 수(cluster.routing.allocation.total_shards_per_node) 또는 인덱스당 최대 샤드 수를 강제해요. |
| max_retry | 여러 번 할당에 실패한 샤드에 대한 반복 할당 시도를 방지해요. |
| node_version | 호환되는 OpenSearch 버전의 노드에 샤드가 할당되도록 해서 버전 다운그레이드를 방지해요. |
| snapshot_in_progress | 해당 샤드에 스냅샷 작업이 진행 중일 때 샤드 할당을 방지해요. |
| restore_in_progress | 스냅샷에서 샤드 복원 중 할당을 제어해요. |
| rebalance_only_when_active | 클러스터의 모든 샤드 복사본(primary와 replica)이 활성화되지 않았을 때 리밸런싱을 방지해요. |
| cluster_rebalance | cluster.routing.allocation.allow_rebalance 설정(always, indices_primaries_active, indices_all_active)을 기준으로 클러스터 리밸런싱이 허용되는 시점을 제어해요. |
| replica_after_primary_active | replica 샤드가 primary 샤드가 활성화된 후에만 할당되도록 해요. |
보안
Security 플러그인을 사용한다면 적절한 권한이 있는지 확인해야 해요: cluster:monitor/allocation/explain.
더 알아보기 (Learn more)
- 샤드 할당의 전반적인 개념은 Cluster formation과 Shard allocation awareness에서 다뤄요.
include_disk_info로 디스크 관련 문제,include_yes_decisions로 성공적인 할당 시도까지 모두 확인할 수 있어요.