클러스터 재라우팅 API

클러스터 재라우팅 API (Cluster Reroute API)

클러스터 안에서 개별 샤드의 할당을 직접 제어하고 싶으시죠? /_cluster/reroute API가 샤드 할당을 이동하거나, 할당하거나, 취소하는 작업을 지원해요. 주로 수동 복구나 사용자 지정 로드 밸런싱 같은 고급 시나리오에 사용돼요.

출처: 문서

본문

1.0에서 도입

/_cluster/reroute API는 클러스터 내 개별 샤드의 할당을 수동으로 제어할 수 있게 해요. 여기에는 샤드 할당 이동, 할당, 취소가 포함돼요. 주로 수동 복구나 사용자 지정 로드 밸런싱 같은 고급 시나리오에 사용돼요.

샤드 이동은 클러스터 할당 decider의 적용을 받아요. 실제 운영 환경에 적용하기 전에 항상 dry_run=true를 사용해 reroute 명령을 테스트해야 해요. explain=true 파라미터를 사용하면 할당 결정에 대한 자세한 통찰을 얻어, 특정 reroute 요청이 허용되거나 허용되지 않는 이유를 이해하는 데 도움이 돼요. 이전 문제나 클러스터 불안정으로 샤드 할당이 실패했다면 retry_failed=true 파라미터로 할당을 다시 시도할 수 있어요.

엔드포인트

POST /_cluster/reroute

쿼리 파라미터

Parameter Data type Description
dry_run Boolean true면 reroute 요청을 적용하지 않고 검증·시뮬레이션해요. 기본값은 false예요.
explain Boolean true면 명령이 수락되거나 거부된 이유에 대한 설명을 반환해요. 기본값은 false예요.
retry_failed Boolean true면 이전에 실패한 샤드의 할당을 재시도해요. 기본값은 false예요.
metric String 반환되는 메타데이터를 제한해요. 사용 가능한 옵션 목록은 Metric options를 참고하세요. 기본값은 _all이에요.
cluster_manager_timeout Time cluster manager 노드에 연결하는 타임아웃이에요. 기본값은 30s예요.
timeout Time 전체 요청 타임아웃이에요. 기본값은 30s예요.

메트릭 옵션 (Metric options)

metric 파라미터는 Reroute API가 반환하는 클러스터 상태 값을 필터링해요. 응답 크기를 줄이거나 클러스터 상태의 특정 부분을 검사하는 데 유용해요. 이 파라미터는 다음 값을 지원해요.

  • _all (기본값): 사용 가능한 모든 클러스터 상태 섹션을 반환해요.
  • blocks: 클러스터의 읽기 및 쓰기 수준 블록에 대한 정보를 포함해요.
  • cluster_manager_node: 현재 cluster manager 역할을 하는 노드를 보여줘요.
  • metadata: 인덱스 설정, 매핑, alias를 반환해요. 특정 인덱스를 대상으로 하면 해당 인덱스의 메타데이터만 반환돼요.
  • nodes: 클러스터의 모든 노드와 그 메타데이터를 포함해요.
  • routing_table: 모든 샤드와 replica의 라우팅 정보를 반환해요.
  • version: 클러스터 상태 버전 번호를 표시해요.

값을 쉼표로 구분해 결합할 수 있어요(예: metric=metadata,nodes,routing_table).

요청 본문 필드

요청 본문의 commands 배열은 샤드 할당에 적용할 작업을 정의해요. 다음 작업을 지원해요.

이동 (Move)

move 명령은 시작된 샤드(primary 또는 replica)를 한 노드에서 다른 노드로 이동해요. 이는 로드를 균형 있게 하거나 유지 관리 전에 노드를 비우는 데 사용할 수 있어요. 샤드는 STARTED 상태여야 해요. 이 명령으로 primary와 replica 샤드 모두 이동할 수 있어요.

move 명령은 다음 파라미터가 필요해요.

  • index: 인덱스 이름.
  • shard: 샤드 번호.
  • from_node: 샤드를 이동할 노드 이름.
  • to_node: 샤드를 이동할 노드 이름.

취소 (Cancel)

cancel 명령은 샤드의 할당(복구 포함)을 취소해요. 이 명령은 기존 할당을 취소하고 시스템이 재초기화하도록 함으로써 재동기화를 강제해요. replica 샤드 할당은 기본적으로 취소할 수 있지만, primary 샤드를 취소하려면 우발적인 데이터 중단을 방지하기 위해 allow_primary=true가 필요해요.

cancel 명령은 다음 파라미터가 필요해요.

  • index: 인덱스 이름.
  • shard: 샤드 번호.
  • node: 작업을 수행할 노드 이름 또는 노드 ID.
  • allow_primary (선택): true면 primary 샤드 할당 취소를 허용해요. 기본값은 false예요.

replica 할당 (Allocate replica)

allocate_replica 명령은 unassigned replica를 지정된 노드에 할당해요. 이 연산은 할당 decider를 존중해요. 자동 할당이 실패할 때 replica 할당을 수동으로 트리거하는 데 사용해요.

allocate_replica 명령은 다음 파라미터가 필요해요.

  • index: 인덱스 이름.
  • shard: 샤드 번호.
  • node: 작업을 수행할 노드 이름 또는 노드 ID.

stale primary 할당 (Allocate stale primary)

allocate_stale_primary 명령은 stale 복사본을 보유한 노드에 primary 샤드를 강제 할당해요.

이 명령은 극도로 주의해서 사용해야 해요. 이 명령은 안전 검사를 우회하며, 특히 일시적으로 오프라인인 다른 노드에 더 최신 샤드 복사본이 있다면 데이터 손실로 이어질 수 있어요. 그 노드가 나중에 클러스터에 다시 합류하면 그 데이터는 강제로 승격된 stale 복사본으로 삭제되거나 대체될 거예요.

최신 복사본이 없고 원본 데이터를 복원할 방법이 없을 때만 이 명령을 사용하세요.

allocate_stale_primary 명령은 다음 파라미터가 필요해요.

  • index: 인덱스 이름.
  • shard: 샤드 번호.
  • node: 작업을 수행할 노드 이름 또는 노드 ID.
  • accept_data_loss: 반드시 true로 설정해야 해요.

빈 primary 할당 (Allocate empty primary)

allocate_empty_primary 명령은 노드에 새 빈 primary 샤드를 강제로 할당해요. 이 연산은 기존 데이터 없이 새 primary 샤드를 초기화해요.

샤드에 대한 이전 데이터는 영구적으로 손실돼요. 나중에 그 샤드에 유효한 데이터가 있는 노드가 클러스터에 다시 합류하면 그 복사본은 지워질 거예요. 이 명령은 유효한 샤드 복사본이 없고 백업이나 스냅샷에서 복구가 불가능한 재해 복구를 위한 것이에요.

allocate_empty_primary 명령은 다음 파라미터가 필요해요.

  • index: 인덱스 이름.
  • shard: 샤드 번호.
  • node: 작업을 수행할 노드 이름 또는 노드 ID.
  • accept_data_loss: 반드시 true로 설정해야 해요.

예시

다음은 Cluster Reroute API를 사용하는 예시예요.

샤드 이동하기

샘플 인덱스를 만들어요.

PUT /test-cluster-index
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  }
}

다음 reroute 명령을 실행해 test-cluster-index 인덱스의 샤드 0을 노드 node1에서 node2로 이동해요.

POST /_cluster/reroute
{
  "commands": [
    {
      "move": {
        "index": "test-cluster-index",
        "shard": 0,
        "from_node": "node1",
        "to_node": "node2"
      }
    }
  ]
}

reroute 시뮬레이션하기

실행하지 않고 reroute를 시뮬레이션하려면 dry_run=true로 설정해요.

POST /_cluster/reroute?dry_run=true
{
  "commands": [
    {
      "move": {
        "index": "test-cluster-index",
        "shard": 0,
        "from_node": "node1",
        "to_node": "node2"
      }
    }
  ]
}

실패한 할당 재시도하기

이전 문제로 일부 샤드가 할당에 실패했다면 할당을 다시 시도할 수 있어요.

POST /_cluster/reroute?retry_failed=true

reroute 결정 설명하기

reroute 명령이 수락되거나 거부되는 이유를 이해하려면 explain=true를 추가해요.

POST /_cluster/reroute?explain=true
{
  "commands": [
    {
      "move": {
        "index": "test-cluster-index",
        "shard": 0,
        "from_node": "node1",
        "to_node": "node2"
      }
    }
  ]
}

이것은 결과를 설명하는 decisions 배열을 반환해요.

"decisions": [
        {
          "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": "remote_store_migration",
          "decision": "YES",
          "explanation": "[none migration_direction]: primary shard copy can be relocated to a non-remote node for strict compatibility mode"
        }
      ]

응답 본문 필드

응답은 클러스터 상태 메타데이터와, explain=true를 사용했다면 선택적으로 decisions 배열을 포함해요.

Field Data type Description
acknowledged Boolean reroute 요청이 수락됐는지 여부를 나타내요.
state.cluster_uuid String 클러스터의 고유 식별자예요.
state.version Integer 클러스터 상태의 버전이에요.
state.state_uuid String 이 특정 상태 버전의 UUID예요.
state.master_node String cluster_manager_node와 마찬가지로 하위 호환성을 위해 유지돼요.
state.cluster_manager_node String elected cluster manager 노드의 ID예요.
state.blocks Object 전역 또는 인덱스 수준 클러스터 블록이에요.
state.nodes Object 클러스터 노드의 메타데이터로, 이름과 주소를 포함해요.
state.routing_table Object 각 인덱스의 샤드 라우팅 정보예요.
state.routing_nodes Object 노드별로 구성된 샤드 할당이에요.
commands List 처리된 reroute 명령 목록이에요.
explanations List explain=true면 결과에 대한 상세한 설명을 포함해요.

보안

Security 플러그인을 사용한다면 적절한 권한이 있는지 확인해야 해요: cluster:admin/reroute.

더 알아보기 (Learn more)

  • 샤드 분포와 클러스터 상태는 Cluster health와 Cluster allocation explain에서 다뤄요.
  • data loss가 우려되는 allocate_stale_primary, allocate_empty_primary 명령은 반드시 신중하게 사용해야 해요.