Elasticsearch 인덱스를 API 명령어로 관리하는 궁극의 가이드

이 궁극의 가이드로 Elasticsearch 인덱스 관리를 마스터하세요. `PUT`을 사용하여 사용자 정의 매핑 및 설정으로 인덱스를 꼼꼼하게 생성하고, `GET`으로 구성과 세부 정보를 종합적으로 확인하며, `DELETE`로 불필요한 인덱스를 안전하게 삭제하는 방법을 배웁니다. 이 글은 실용적인 예제, 모범 사례 및 중요한 경고를 제공하여 Elasticsearch 내에서 데이터 수명 주기를 효과적으로 제어하고 최적의 성능과 리소스 관리를 달성할 수 있도록 도와줍니다.

Elasticsearch 인덱스를 API 명령어로 관리하는 궁극의 가이드

API를 통해 Elasticsearch 인덱스를 관리하는 것은 일상적인 작업이지만, 값비싼 실수가 발생하기 쉬운 부분이기도 합니다. 잘못된 매핑은 재인덱싱을 강제할 수 있습니다. 와일드카드 삭제는 의도한 것보다 더 많은 것을 제거할 수 있습니다. 개발 환경에서 적절했던 복제본 설정은 배포 후 프로덕션 환경을 노란색 상태로 만들 수 있습니다.

Elasticsearch 인덱스는 단순히 JSON 문서를 담는 버킷이 아닙니다. 매핑, 설정, 별칭, 샤드 수, 복제본 수, 분석기, 수명 주기 동작을 포함합니다. 이를 잘 관리하기 위해 모든 API를 외울 필요는 없지만, 신중한 루틴은 필요합니다: 의도적으로 인덱스를 생성하고, Elasticsearch가 실제로 생성한 것을 검사하고, 안전하게 변경할 수 있는 설정만 업데이트하고, 보호 장치를 갖추고 삭제하는 것입니다.

아래 예제는 Kibana Dev Tools 스타일의 요청을 사용합니다. curl을 선호하는 경우, http://host:9200에 대해 동일한 경로와 JSON 본문을 적용하면 됩니다.

인덱스가 포함하는 것

인덱스는 문서를 위한 논리적 네임스페이스입니다. 내부적으로 기본 샤드는 데이터를 보유하고, 복제본 샤드는 중복성과 검색 용량을 위해 데이터를 복사합니다. 정확한 기본 샤드 및 복제본 동작은 Elasticsearch 버전과 배포 모드에 따라 다를 수 있으므로 메모리에 의존하지 마십시오. 자체 클러스터의 설정을 확인하십시오.

가장 자주 검사할 세 가지 요소는 다음과 같습니다:

  • settings: number_of_shards, number_of_replicas, refresh_interval, 분석 구성 등.
  • mappings: keyword, text, date, long, double, boolean, ip, 중첩/객체 필드와 같은 필드 유형을 정의합니다.
  • aliases: 애플리케이션이 안정적인 이름을 사용하는 동안 그 뒤에 있는 실제 백업 인덱스를 교체할 수 있게 해줍니다.

좋은 인덱스 API 워크플로우는 첫 번째 문서가 인덱싱되기 전에 시작됩니다. 동적 매핑은 탐색에 유용하지만, 프로덕션 인덱스는 중요한 필드에 대해 명시적인 매핑을 가져야 합니다. user_id가 실수로 text로 매핑되면 집계와 정확한 필터가 어색해집니다. 타임스탬프가 text로 매핑되면 시간 범위 쿼리가 날짜 쿼리처럼 작동하지 않습니다. 이러한 실수는 수정 가능하지만, 일반적으로 새 인덱스를 생성하고 재인덱싱해야 합니다.

간단한 인덱스 생성

가장 간단한 생성 요청은 다음과 같습니다:

PUT /my_first_index

Elasticsearch는 인덱스가 생성되면 승인을 반환합니다:

{
  "acknowledged": true,
  "shards_acknowledged": true,
  "index": "my_first_index"
}

임시 인덱스에는 괜찮습니다. 실제 데이터의 경우, 처음 몇 개의 문서가 형태를 정의하도록 두지 말고 예상되는 설정과 매핑으로 인덱스를 생성하십시오.

매핑 및 설정으로 인덱스 생성

다음은 실용적인 products 인덱스입니다. 이름과 설명에 대한 전문 검색, ID 및 카테고리에 대한 정확한 필터링, 날짜 정렬, 숫자 범위 필터, 간단한 가용성 확인을 지원합니다.

PUT /products-v1
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1,
    "refresh_interval": "5s"
  },
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "product_id": { "type": "keyword" },
      "sku": { "type": "keyword" },
      "name": {
        "type": "text",
        "fields": {
          "raw": { "type": "keyword", "ignore_above": 256 }
        }
      },
      "description": { "type": "text" },
      "category": { "type": "keyword" },
      "price": { "type": "scaled_float", "scaling_factor": 100 },
      "stock": { "type": "integer" },
      "available": { "type": "boolean" },
      "created_at": { "type": "date" },
      "updated_at": { "type": "date" }
    }
  }
}

여기서 몇 가지 선택은 의도적입니다. product_id, sku, categorykeyword입니다. 일반적으로 정확한 값을 기준으로 필터링, 집계 또는 애플리케이션 동작을 조인하기 때문입니다. name은 검색을 위해 text이며, 정렬 및 정확한 일치를 위한 name.raw 키워드 하위 필드가 있습니다. pricescaled_float를 사용하여 가격을 이진 부동 소수점 근사 대신 센트 단위의 스케일링된 값으로 저장할 수 있습니다. dynamic: strict는 알 수 없는 필드를 거부하며, 잘못된 프로듀서 데이터가 명확하게 실패해야 할 때 유용합니다.

샤드 수를 맹목적으로 복사하지 마십시오. 기본 샤드 3개는 작은 인덱스에는 너무 많고 큰 인덱스에는 너무 적을 수 있습니다. 샤드 수는 축소, 분할 또는 재인덱싱 스타일 마이그레이션 없이는 생성 후 변경하기 어렵습니다. 따라서 예상 데이터 볼륨, 보존 기간 및 노드 수에 따라 크기를 조정하십시오.

생성 후 인덱스 검사

Elasticsearch가 무엇을 수락했는지 항상 확인하십시오:

GET /products-v1

설정, 매핑 및 별칭을 반환합니다. 집중적인 확인을 위해 더 좁은 엔드포인트를 사용하십시오:

GET /products-v1/_mapping
GET /products-v1/_settings
GET /products-v1/_alias

많은 인덱스에 대한 간결한 명령줄 보기를 위해:

GET /_cat/indices/products-*?v

유용한 열에는 상태, 기본 샤드 수, 복제본 수, 문서 수, 삭제된 문서 수, 저장소 크기가 포함됩니다. _cat API는 사람을 위한 것입니다. 스크립트에는 JSON API를 사용하십시오.

필드가 올바르게 매핑되었는지 확인하려면 다음을 사용하십시오:

GET /products-v1/_mapping/field/price
GET /products-v1/_mapping/field/name.raw

큰 매핑을 스크롤하는 것보다 읽기가 더 빠릅니다.

인덱스 설정 안전하게 업데이트

일부 설정은 동적입니다. 복제본 수가 일반적인 예입니다:

PUT /products-v1/_settings
{
  "index": {
    "number_of_replicas": 2
  }
}

이것은 복사본을 배치할 충분한 적절한 데이터 노드가 없으면 녹색 클러스터를 노란색으로 만들 수 있습니다. 예를 들어, 하나의 기본 샤드와 두 개의 복제본은 복사본을 저장할 세 개의 별도 위치가 필요합니다. 할당 인식 규칙은 요구 사항을 더 엄격하게 만들 수 있습니다.

refresh_interval은 대량 로드 중에 변경할 수 있는 또 다른 설정입니다:

PUT /products-v1/_settings
{
  "index": {
    "refresh_interval": "30s"
  }
}

더 긴 새로 고침 간격은 인덱싱 오버헤드를 줄일 수 있지만, 새로 인덱싱된 문서가 검색에 표시되는 속도가 느려집니다. 대량 백필의 경우 팀은 종종 새로 고침을 늘리거나 일시적으로 비활성화하고, 데이터를 로드한 다음, 정상 간격을 복원하고 한 번 새로 고칩니다:

POST /products-v1/_refresh

일부 설정은 정적입니다. number_of_shards는 열려 있는 기존 인덱스에서 변경할 수 없습니다. 기본 샤드 수가 잘못된 것을 발견하면 새 인덱스와 마이그레이션을 계획하십시오.

자신을 속이지 않고 매핑 변경

매핑에 새 필드를 추가할 수 있습니다:

PUT /products-v1/_mapping
{
  "properties": {
    "brand": { "type": "keyword" }
  }
}

일반적으로 기존 필드의 유형을 제자리에서 변경할 수 없습니다. price가 이미 text인 경우, 이전 값을 유용한 숫자 필드로 바꾸지 않습니다. 올바른 매핑으로 새 인덱스를 생성하고 재인덱싱하십시오:

POST /_reindex
{
  "source": { "index": "products-v1" },
  "dest": { "index": "products-v2" }
}

프로덕션 마이그레이션의 경우 애플리케이션이 물리적 인덱스 버전을 알 필요가 없도록 별칭을 사용하십시오.

안전한 애플리케이션 액세스를 위한 별칭 사용

첫 번째 버전을 가리키는 별칭을 지정하십시오:

POST /_aliases
{
  "actions": [
    { "add": { "index": "products-v1", "alias": "products" } }
  ]
}

애플리케이션은 products에서 읽습니다. 나중에 products-v2를 생성하고, 데이터를 재인덱싱하고, 테스트한 다음, 별칭을 원자적으로 교체하십시오:

POST /_aliases
{
  "actions": [
    { "remove": { "index": "products-v1", "alias": "products" } },
    { "add": { "index": "products-v2", "alias": "products" } }
  ]
}

쓰기 집약적인 시스템의 경우 쓰기 별칭을 사용하고 is_write_index를 명시적으로 지정하십시오:

POST /_aliases
{
  "actions": [
    { "add": { "index": "products-v2", "alias": "products-write", "is_write_index": true } }
  ]
}

별칭은 서비스에 인덱스 버전을 하드코딩하지 않는 가장 간단한 방법 중 하나입니다.

인덱스 이름 신중하게 나열 및 검색

여러 인덱스를 검사하려면:

GET /products-v1,products-v2/_settings
GET /products-*/_mapping
GET /_cat/indices/products-*?v&s=index

대규모 클러스터에서 광범위한 와일드카드를 사용할 때 주의하십시오. GET /* 또는 GET /_all은 방대한 응답을 생성할 수 있으며 버전, 설정 및 요청 옵션에 따라 시스템 또는 숨겨진 인덱스를 포함할 수 있습니다. logs-prod-* 또는 products-*와 같은 좁은 패턴을 선호하십시오.

스크립트에서 인덱스가 존재하는지 확인하려면 HEAD를 사용하십시오:

HEAD /products-v1

200은 존재함을 의미합니다. 404는 존재하지 않음을 의미합니다.

보호 장치를 갖추고 인덱스 삭제

삭제는 간단합니다:

DELETE /products-v1

운영상의 위험은 구문이 아닙니다. 위험은 잘못된 인덱스를 삭제하거나 스냅샷이 완료되기 전에 삭제하는 것입니다.

삭제하기 전에 패턴이 정확히 무엇과 일치하는지 나열하십시오:

GET /_cat/indices/products-old-*?v&s=index

출력이 정확하고 데이터를 복구할 수 있거나 더 이상 필요하지 않은 경우 동일한 패턴을 삭제하십시오:

DELETE /products-old-*

많은 클러스터는 action.destructive_requires_name으로 파괴적인 와일드카드 작업을 제한합니다. 이는 명시적인 이름이 필요하지 않는 한 DELETE /*와 같은 광범위한 삭제를 차단하므로 좋은 안전 설정입니다. 이러한 보호가 있더라도 삭제 작업을 프로덕션 변경 사항으로 취급하십시오: 인덱스 패턴을 확인하고, 스냅샷을 확인하고, 호출자에게 적절한 권한이 있는지 확인하십시오.

시계열 데이터에는 수명 주기 정책 선호

수동 삭제는 일회성 정리에 허용됩니다. 로그, 메트릭, 트레이스 및 기타 시계열 데이터의 경우 적절한 경우 Index Lifecycle Management 또는 데이터 스트림을 사용하십시오. 수명 주기 정책은 인덱스가 특정 기간 또는 크기 목표에 도달하면 롤오버하고, 오래된 데이터를 다른 계층으로 이동하며, 보존 기간이 만료된 후 삭제할 수 있습니다.

이는 수동 정리가 최악의 시점에 실패하는 경향이 있기 때문에 중요합니다. 누군가 잊어버리고, 디스크가 가득 차고, 플러드 스테이지 워터마크가 인덱스를 읽기 전용으로 만들고, 팀이 압박 속에서 정리하게 됩니다. 수명 주기 정책은 보존을 캘린더 알림 대신 구성으로 바꿉니다.

간단한 일일 루틴

프로덕션 클러스터의 경우 실용적인 인덱스 관리 루틴은 다음과 같습니다:

상태 확인:

GET /_cluster/health

패턴별 인덱스 나열:

GET /_cat/indices/logs-*?v&s=store.size:desc

의심스러운 설정 검사:

GET /logs-prod-2026.05.24/_settings

애플리케이션 릴리스에서 새 필드를 추가하기 전에 매핑 확인:

GET /logs-prod-2026.05.24/_mapping

마이그레이션 전후에 별칭 확인:

GET /_cat/aliases/products*?v

이것은 화려한 작업은 아니지만, 잘못된 복제본 수, 우발적인 동적 필드, 오래된 별칭, 만료되었어야 할 오래된 인덱스 등 많은 문제를 조기에 발견합니다.

피해야 할 일반적인 실수

개발 기본값을 프로덕션 아키텍처로 만들지 마십시오. 단일 노드 클러스터, 복제본 0개, 동적 매핑은 데모에 적합할 수 있습니다. 복구 계획이 아닙니다.

머릿속으로 매핑을 변경하고 Elasticsearch가 동의한다고 가정하지 마십시오. 실제 매핑을 검사하십시오.

일치하는 인덱스를 먼저 나열하지 않고 와일드카드 삭제를 사용하지 마십시오.

복제본을 배치할 충분한 데이터 노드와 영역 없이 높은 복제본 수를 설정하지 마십시오.

애플리케이션이 의존하는 인덱스에 대해 별칭을 건너뛰지 마십시오. 애플리케이션이 이미 별칭과 통신하고 있다면 첫 번째 마이그레이션이 훨씬 쉬울 것입니다.

좋은 인덱스 관리는 대부분 훈련된 반복입니다. 의도를 가지고 생성하고, 존재하는 것을 검사하고, 별칭으로 마이그레이션하고, 보존을 자동화하고, 파괴적인 작업을 지루할 정도로 명확하게 만드십시오.

템플릿이 일회성 생성보다 중요

동일한 종류의 인덱스를 반복적으로 생성하는 경우 수동 PUT /index-name 호출에 의존하지 마십시오. 인덱스 템플릿 또는 구성 가능한 템플릿을 사용하여 새 인덱스가 올바른 매핑, 설정, 별칭 및 수명 주기 정책을 자동으로 받도록 하십시오.

로그 플랫폼이 전형적인 예입니다. logs-web-2026.05.24에 올바른 @timestamp 매핑이 있지만 내일의 인덱스가 첫 번째 문서에 의해 동적으로 생성되는 경우, 하나의 잘못된 이벤트가 필드를 잘못 매핑할 수 있습니다. 대시보드가 실패하거나 집계가 사라질 때까지 실수가 나타나지 않을 수 있습니다. 템플릿은 이러한 드리프트를 방지합니다.

간단한 템플릿은 미래 인덱스에 대한 패턴, 설정 및 매핑을 정의할 수 있습니다:

PUT /_index_template/logs_web_template
{
  "index_patterns": ["logs-web-*"],
  "template": {
    "settings": {
      "number_of_shards": 3,
      "number_of_replicas": 1
    },
    "mappings": {
      "properties": {
        "@timestamp": { "type": "date" },
        "service": { "type": "keyword" },
        "level": { "type": "keyword" },
        "message": { "type": "text" },
        "trace_id": { "type": "keyword" }
      }
    }
  }
}

템플릿은 코드로 검토하기도 더 쉽습니다. 버전 관리에 넣고, 애플리케이션 변경 사항과 동일한 경로를 통해 배포하고, 롤오버가 다음 백업 인덱스를 생성하기 전에 테스트하십시오.

애플리케이션을 놀라게 하지 않고 재인덱싱

가장 깔끔한 인덱스 마이그레이션은 일반적으로 다음과 같습니다: 새 버전의 인덱스를 생성하고, 데이터를 재인덱싱하고, 개수와 샘플 쿼리를 비교한 다음, 별칭을 교체합니다. 긴급 구성 변경을 즐기지 않는 한 애플리케이션을 products-v1에 직접 연결하지 마십시오.

신중한 마이그레이션은 다음과 같습니다:

PUT /products-v2
{
  "mappings": {
    "properties": {
      "product_id": { "type": "keyword" },
      "name": { "type": "text" },
      "price": { "type": "scaled_float", "scaling_factor": 100 }
    }
  }
}

그런 다음 재인덱싱:

POST /_reindex?wait_for_completion=false
{
  "source": { "index": "products-v1" },
  "dest": { "index": "products-v2" }
}

wait_for_completion=false를 사용하면 작업 ID가 반환되어 긴 재인덱싱을 모니터링할 수 있습니다. 완료된 후 문서 수를 비교하고 대표적인 검색을 실행하십시오. 그런 다음에만 별칭을 교체하십시오.

쓰기 집약적인 인덱스의 경우 이중 쓰기, 일시 중지 창 또는 진실 공급원에서 재생을 고려하십시오. API 명령은 쉽습니다. 일관성 계획이 실제 작업입니다.

보안 및 권한

인덱스 API는 모든 애플리케이션 사용자가 사용할 수 있어서는 안 됩니다. 검색 서비스는 별칭에 대한 읽기 권한이 필요할 수 있습니다. 데이터 수집기는 쓰기 별칭에 대한 생성, 인덱스 및 쓰기 권한이 필요할 수 있습니다. 광범위한 삭제 또는 관리 권한을 가져야 하는 ID는 거의 없습니다.

이는 인덱스 API가 강력하기 때문에 중요합니다. manage 권한이 있는 손상된 애플리케이션 자격 증명은 복제본 설정을 변경하고, 인덱스를 닫거나, 데이터를 삭제할 수 있습니다. 파괴적인 권한을 분리하고, 프로덕션 삭제에는 애플리케이션 경로가 아닌 운영자 워크플로우가 필요하도록 만드십시오.

명명 규칙이 실수를 줄입니다

목적과 수명 주기를 인코딩하는 이름을 사용하십시오: products-v3, logs-web-2026.05.24, metrics-api-000123 또는 데이터 소스와 일치하는 데이터 스트림 이름. newindex, test2 또는 prod-final과 같은 모호한 이름은 피하십시오. 정리 중에 모호한 이름은 무엇을 안전하게 삭제할 수 있는지 알기 어렵게 만듭니다.

시계열 인덱스의 경우 일관된 날짜 형식을 사용하고 현지 시간과 UTC 가정을 혼합하지 마십시오. 버전이 지정된 비즈니스 인덱스의 경우 별칭을 안정적으로 유지하고 그 뒤에서 물리적 인덱스 버전이 변경되도록 하십시오. 지루한 명명 규칙은 운영 안전 기능입니다.