Elasticsearch _bulk API 명령을 활용한 효율적인 데이터 관리

`_bulk` API를 마스터하여 Elasticsearch에서 상당한 성능 향상을 경험하세요. 이 종합 가이드는 명령의 구조를 설명하고, 단일의 고도로 최적화된 요청으로 여러 문서를 효율적으로 색인, 업데이트, 삭제하는 실용적인 예시를 제공합니다. 네트워크 오버헤드를 줄이고 데이터 관리 워크플로를 간소화하여 더욱 빠르고 확장 가능한 Elasticsearch를 경험하는 방법을 배우세요.

40 조회수

Elasticsearch _bulk API 명령어를 사용한 효율적인 데이터 관리

Elasticsearch는 속도와 확장성으로 유명한 강력한 분산 검색 및 분석 엔진입니다. 데이터 양이 늘어나고 애플리케이션의 요구 사항이 증가함에 따라 클러스터와의 상호 작용 방식을 최적화하는 것이 중요해집니다. 특히 데이터 수집 및 수정 시 성능을 향상시키는 가장 효과적인 방법 중 하나는 _bulk API를 활용하는 것입니다. 이 명령어를 사용하면 여러 인덱싱, 업데이트 및 삭제 작업을 단일하고 매우 효율적인 요청으로 결합할 수 있어 네트워크 오버헤드를 크게 줄이고 전반적인 처리량을 향상시킬 수 있습니다.

이 글에서는 _bulk API의 구조를 이해하고 Elasticsearch에서 데이터 관리 작업을 간소화하기 위해 이를 사용하는 실용적인 예제를 보여드리겠습니다. _bulk API를 숙달하면 상당한 성능 향상을 얻고 Elasticsearch 상호 작용을 더욱 효율적으로 만들 수 있습니다.

_bulk API 구조 이해하기

_bulk API는 작업 목록과 해당 메타데이터 및 데이터를 수락하여 작동합니다. 각 작업은 별도의 줄에 정의되며, 이 줄들은 줄바꿈 문자()로 구분됩니다. 요청 본문은 본질적으로 JSON 객체의 시퀀스로, 각 객체는 작업을 나타냅니다. API는 일반적으로 "작업 및 메타데이터" 줄 다음에 문서 데이터가 포함된 "소스" 줄로 구성되는 이러한 작업에 대해 특정 형식을 기대합니다.

_bulk 요청의 주요 구성 요소:

  • 작업 및 메타데이터 줄: 이 줄은 작업 유형(예: index, create, update, delete), 대상 인덱스, 그리고 선택적으로 문서 유형 및 ID를 지정합니다. indexcreate 작업의 경우 문서 ID는 선택 사항입니다. 생략하면 Elasticsearch가 자동으로 생성합니다.
  • 소스 줄: 이 줄에는 인덱싱되거나 업데이트될 실제 JSON 문서가 포함됩니다. 이 줄은 delete 작업의 경우 생략됩니다.
  • 줄바꿈 구분 기호: 각 작업/메타데이터 쌍과 해당 소스(해당하는 경우)는 줄바꿈 문자(\n)로 구분되어야 합니다. 전체 요청 본문은 줄바꿈 문자로 끝나야 합니다.

예제 구조:

{ "action_and_metadata_line" }
{ "source_line" }
{ "action_and_metadata_line" }
{ "source_line" }
...

또는 삭제 작업의 경우:

{ "action_and_metadata_line" }
...

_bulk를 사용한 일반적인 작업 수행

_bulk API는 다재다능하며 단일 요청 내에서 다양한 작업을 처리할 수 있습니다. 이것이 진정한 힘을 발휘하는 곳으로, 한 번의 왕복 통신으로 복잡한 데이터 조작을 수행할 수 있습니다.

여러 문서 인덱싱

여러 문서를 인덱싱하려면 index 작업을 사용합니다. 지정된 ID를 가진 문서가 이미 존재하는 경우 index는 해당 문서를 덮어씁니다. 문서가 아직 존재하지 않는 경우에만 인덱싱되도록 하려면 대신 create 작업을 사용하십시오.

예제: 새 문서 두 개 인덱싱.

POST /_bulk
{
  "index": { "_index": "my-index", "_id": "1" }
}
{
  "field1": "value1",
  "field2": "value2"
}
{
  "index": { "_index": "my-index", "_id": "2" }
}
{
  "field1": "another_value",
  "field2": "different_value"
}

문서 업데이트

update 작업을 사용하여 문서를 업데이트할 수 있습니다. 업데이트할 문서 ID를 지정하고 변경하려는 필드를 포함하는 부분 문서를 제공합니다. 업데이트를 위해 스크립트를 사용하려면 update 작업 내에서 할 수 있습니다.

예제: 기존 문서의 필드 업데이트.

POST /_bulk
{
  "update": { "_index": "my-index", "_id": "1" }
}
{
  "doc": {
    "field1": "updated_value"
  }
}

문서 삭제

문서를 삭제하려면 delete 작업을 사용하고 제거할 문서의 _index_id를 지정합니다. 삭제 작업에는 소스 문서가 필요하지 않습니다.

예제: 문서 삭제.

POST /_bulk
{
  "delete": { "_index": "my-index", "_id": "2" }
}

작업 결합

실제 효율성은 이러한 작업을 혼합하는 데서 나옵니다. 동일한 _bulk 요청에서 새 문서를 인덱싱하고, 기존 문서를 업데이트하고, 다른 문서를 삭제할 수 있습니다.

예제: 한 번의 요청으로 인덱싱, 업데이트 및 삭제.

POST /_bulk
{
  "index": { "_index": "my-index", "_id": "3" }
}
{
  "field1": "new_document_field",
  "field2": "new_document_value"
}
{
  "update": { "_index": "my-index", "_id": "1" }
}
{
  "doc": {
    "field1": "further_updated_value"
  }
}
{
  "delete": { "_index": "my-index", "_id": "2" }
}

응답 처리

_bulk API는 각 개별 작업의 결과를 자세히 설명하는 JSON 응답을 반환합니다. 모든 작업이 성공했는지 확인하고 오류를 식별하기 위해 이 응답을 파싱하는 것이 중요합니다.

응답에는 items 배열이 포함되며, 각 요소는 요청의 작업 중 하나에 해당하며 순서대로 정렬됩니다. 각 항목에는 index, create, update 또는 delete 작업과 해당 상태(예: created, updated, deleted, noop) 및 기타 관련 메타데이터가 포함됩니다.

예제 응답 스니펫:

{
  "took": 150,
  "errors": false,
  "items": [
    {
      "index": {
        "_index": "my-index",
        "_id": "3",
        "version": 1,
        "result": "created",
        "_shards": {"total": 2, "successful": 1, "failed": 0},
        "_seq_no": 0,
        "_primary_term": 1
      }
    },
    {
      "update": {
        "_index": "my-index",
        "_id": "1",
        "version": 2,
        "result": "updated",
        "_shards": {"total": 2, "successful": 1, "failed": 0},
        "_seq_no": 1,
        "_primary_term": 1
      }
    },
    {
      "delete": {
        "_index": "my-index",
        "_id": "2",
        "version": 2,
        "result": "deleted",
        "_shards": {"total": 2, "successful": 1, "failed": 0},
        "_seq_no": 2,
        "_primary_term": 1
      }
    }
  ]
}

작업 중 하나라도 실패하면 응답의 최상위 errors 필드가 true가 되고, 실패한 작업에 대한 개별 항목에는 문제점을 설명하는 error 객체가 포함됩니다.

모범 사례 및 팁

  • 배치 크기: _bulk API는 효율적이지만, 지나치게 큰 배치는 여전히 리소스에 부담을 줄 수 있습니다. 클러스터 및 사용 사례에 맞는 최적의 배치 크기를 찾기 위해 실험해 보십시오. 일반적인 시작점은 배치당 1,000~5,000개의 문서입니다.
  • 오류 처리: 항상 오류에 대해 응답을 파싱하십시오. 필요한 경우 일시적인 오류에 대한 재시도 로직을 구현하십시오.
  • 줄바꿈 구분 기호: 각 JSON 객체 사이에 줄바꿈 문자(\n)가 올바르게 사용되었는지 확인하십시오. 잘못된 형식은 _bulk API 실패의 일반적인 원인입니다.
  • 병렬화: 매우 높은 수집 속도의 경우 여러 _bulk 요청을 병렬로 보내는 것을 고려해 보십시오. 단, 클러스터 용량에 유의해야 합니다.
  • createindex: 기존 문서를 실수로 덮어쓰는 것을 방지하려면 create를 사용하십시오. 일반적인 upsert(업데이트 또는 삽입) 동작에는 index를 사용하십시오.
  • API 클라이언트: 대부분의 Elasticsearch 클라이언트 라이브러리는 _bulk 요청을 구성하고 실행하는 편리한 메서드를 제공하여 일부 수동 형식을 추상화합니다.

결론

Elasticsearch _bulk API는 데이터 작업을 최적화하려는 모든 사람에게 필수적인 도구입니다. 여러 인덱싱, 업데이트 및 삭제 요청을 단일 API 호출로 통합함으로써 네트워크 지연 시간을 크게 줄이고 처리 효율성을 높이며 Elasticsearch 클러스터의 전반적인 성능을 향상시킬 수 있습니다. 구조를 이해하고 효과적으로 구현하면 더 강력하고 확장 가능한 데이터 관리 전략을 얻을 수 있습니다.