문서 API
문서 API (Document APIs)
인덱스에 저장된 문서의 생성, 읽기, 수정, 삭제(CRUD) 작업을 어떻게 하면 되죠? 문서 API가 정확히 그 역할을 해요. 개별 문서를 관리하거나 일괄 작업으로 여러 문서를 효율적으로 처리할 수 있어요.
출처: 문서
본문
1.0에서 도입
문서 API는 인덱스에 저장된 문서에 대해 생성, 읽기, 수정, 삭제(CRUD) 연산을 수행할 수 있게 해줘요. 이 API를 사용해 개별 문서를 관리하거나 일괄 작업으로 여러 문서를 효율적으로 처리할 수 있어요.
작업 유형 (Operation types)
OpenSearch 문서 API는 처리하는 문서 수에 따라 다음 범주로 구성돼요.
단일 문서 작업 (Single-document operations)
단일 문서 작업은 한 번에 하나의 문서를 다뤄요. 특정 문서에 대한 정밀한 작업이 필요하거나 개별 레코드를 처리할 때 이 API를 사용해요.
- Index Document API로 새 문서를 추가하거나 같은 ID를 가진 기존 문서를 교체해요.
- Get Document API로 문서를 고유 ID로 가져와요.
- Update Document API로 전체 문서를 재인덱싱하지 않고 기존 문서의 특정 필드를 변경해요.
- Delete Document API로 인덱스에서 문서를 제거해요.
다중 문서 작업 (Multi-document operations)
다중 문서 작업은 단일 API 요청으로 여러 문서를 처리해요. 개별 요청을 제출하는 것보다 상당한 성능 이점이 있어요. 대규모 데이터셋이나 일괄 작업을 다룰 때는 항상 다중 문서 API를 선호해야 하는데, 그 이유는 다음과 같아요.
- 여러 연산을 하나의 요청으로 결합해 네트워크 오버헤드를 줄여요.
- OpenSearch가 일괄 처리를 최적화할 수 있어 처리량을 향상시켜요.
- 애플리케이션과 클러스터 사이의 왕복 횟수를 최소화해요.
데이터 수집 파이프라인, 대량 업데이트, 일괄 삭제, 그리고 여러 문서를 효율적으로 처리해야 하는 모든 시나리오에 다중 문서 작업을 사용해요.
Term vector 작업 (Term vector operations)
Term vector 작업은 특정 문서 필드의 용어에 대한 정보(용어 빈도, 위치, 오프셋)를 검색해요. 텍스트 분석, 관련성 점수 계산, 사용자 정의 유사도 계산에 사용해요.
중요한 고려 사항 (Important considerations)
단일 인덱스 제한: 모든 문서 API는 한 번에 단일 인덱스에서 작동해요. index 파라미터는 하나의 인덱스 이름 또는 단일 인덱스를 가리키는 alias만 받아요. 단일 문서 API 요청에서 여러 인덱스를 대상으로 할 수 없어요. 여러 인덱스에 걸친 작업은 각 인덱스에 대해 별도의 요청을 제출해야 해요.
문서 라우팅: OpenSearch는 라우팅 알고리즘을 사용해 각 문서를 저장할 샤드를 결정해요. 기본적으로 문서는 ID에 따라 라우팅되지만, 사용자 정의 라우팅 값을 지정해 샤드 배치를 제어할 수 있어요. 사용자 정의 라우팅으로 인덱싱한 문서를 검색, 업데이트, 삭제할 때는 반드시 같은 라우팅 값을 제공해야 해요.
데이터 복제 모델 (Data replication model)
OpenSearch는 내결함성과 고가용성을 보장하기 위해 샤드에 걸쳐 데이터의 여러 복사본을 유지해요. 이 복제 모델은 primary-backup 패턴에 기반하는데, 하나의 샤드 복사본이 primary 역할을 하고 다른 복사본은 replica 역할을 해요.
쓰기 작업 (Write operations)
문서를 인덱싱, 업데이트, 삭제할 때 OpenSearch는 다음 과정을 따르는 것 같나요? 실제로는 이렇게 진행돼요.
- 라우팅: 연산이 문서 ID 또는 사용자 정의 라우팅 값에 따라 적절한 primary 샤드로 라우팅돼요.
- Primary 처리: primary 샤드가 연산을 로컬에서 검증하고 실행해요.
- 복제: primary 샤드가 연산을 모든 활성 replica 샤드에 병렬로 전달해요.
- 승인: 모든 동기화된 replica가 연산을 확인한 후 primary 샤드가 클라이언트에 성공을 승인해요.
이 과정은 모든 샤드 복사본이 동기화 상태를 유지하고, 승인된 쓰기가 여러 노드에 걸쳐 영속적임을 보장해요.
읽기 작업 (Read operations)
읽기 작업은 어떤 샤드 복사본(primary 또는 replica)이든 처리할 수 있어요. 이는 여러 이점을 제공해요.
- 부하 분산: 읽기 요청이 여러 샤드 복사본에 분산돼 처리량과 응답 시간이 향상돼요.
- 고가용성: 샤드 복사본 하나를 사용할 수 없게 되면 OpenSearch가 자동으로 다른 복사본으로 요청을 라우팅해요.
- 일관성: 모든 샤드 복사본이 같은 데이터(진행 중인 연산 제외)를 포함해 일관된 읽기 결과를 보장해요.
기본적으로 OpenSearch는 각 읽기 요청을 처리할 샤드 복사본을 round-robin 분포로 선택해요. 많은 문서 API에서 사용할 수 있는 preference 파라미터로 이 선택에 영향을 줄 수 있어요.
Refresh 동작 (Refresh behavior)
Index, Update, Delete, Bulk API는 refresh 파라미터를 지원해요. 이 파라미터는 변경 사항이 검색 작업에 언제 표시될지 제어해요. refresh 동작을 이해하는 것은 데이터 신선도와 시스템 성능의 균형을 맞추는 데 중요해요.
Refresh 파라미터 값 (Refresh parameter values)
refresh 파라미터는 다음 값을 받아요.
false(기본값): refresh 관련 작업을 수행하지 않아요. 변경 사항은index.refresh_interval설정(기본값 1초)에 따라 인덱스가 자동으로 refresh될 때 표시돼요.true: 연산 완료 후 관련 primary 및 replica 샤드를 즉시 refresh해 변경 사항을 즉시 검색에 표시해요. 성능에 큰 영향을 줄 수 있으므로 아껴서 사용해요.wait_for: 클라이언트에 응답하기 전에 refresh를 통해 변경 사항이 표시될 때까지 기다려요. 이 옵션은 즉시 refresh를 강제하지 않고 다음 예약된 refresh나 다른 연산이 refresh를 트리거할 때까지 기다려요.
올바른 refresh 설정 선택하기 (Choosing the right refresh setting)
대부분의 사용 사례에는 기본 refresh=false가 최상의 성능을 제공해요. 다음 지침을 고려하세요.
- false(기본값) 사용: 거의 실시간(1초 내) 가시성이 acceptable한 높은 처리량 인덱싱에 사용해요.
- wait_for 사용: 변경 사항이 검색 가능하다는 확인이 필요하지만 즉시 refresh를 강제하고 싶지 않을 때 사용해요. 이 옵션은 일괄 작업에서
refresh=true보다 효율적이에요. - true는 아껴서 사용: 검색에 더 많은 리소스가 필요한 비효율적인 인덱스 세그먼트를 만들기 때문에 즉시 가시성이 절실한 경우에만 사용해요.
refresh=true를 과도하게 사용하면 작은 세그먼트가 많이 생기고 병합 오버헤드가 늘어나 클러스터 성능을 현저히 떨어뜨릴 수 있어요.
낙관적 동시성 제어 (Optimistic concurrency control)
OpenSearch는 낙관적 동시성 제어를 사용해 문서 업데이트가 최신 변경 사항을 더 오래된 데이터로 덮어쓰지 않도록 보장해요. 이 메커니즘은 여러 연산이 동시에 발생할 수 있는 분산 시스템에서 필수적이에요.
문서를 변경하는 모든 연산에는 조정하는 primary 샤드가 시퀀스 번호(_seq_no)와 primary term(_primary_term)을 할당해요.
- 시퀀스 번호: 각 연산에 할당되는 엄격히 증가하는 숫자예요. 최신 연산은 항상 이전 연산보다 높은 시퀀스 번호를 가져요.
- Primary term: 현재 primary 샤드 할당을 식별해요. 장애 후 새 primary 샤드가 선출되면 이 값이 변경돼요.
_seq_no와 _primary_term은 함께 문서에 대한 각 변경을 고유하게 식별해, OpenSearch가 순서가 어긋난 업데이트를 감지하고 방지할 수 있게 해줘요.
시퀀스 번호를 사용한 조건부 업데이트 (Using sequence numbers for conditional updates)
Index, Update, Delete API에서 if_seq_no와 if_primary_term 파라미터를 사용해, 문서를 가져온 이후 변경되지 않은 경우에만 연산이 성공하도록 보장할 수 있어요. OpenSearch는 Get API 응답과 검색 결과(요청 시)에서 현재 _seq_no와 _primary_term 값을 반환해요.
이 접근 방식은 여러 클라이언트나 프로세스가 같은 문서를 동시에 수정하는 시나리오에서 손실된 업데이트를 방지해요. 시퀀스 번호나 primary term이 현재 값과 일치하지 않으면 OpenSearch는 버전 충돌 오류를 반환하며, 애플리케이션은 최신 문서 버전으로 연산을 재시도할 수 있어요.
단일 문서 작업
- Index document
- Get document
- Update document
- Delete document
다중 문서 작업
- Bulk
- Streaming bulk
- Multi-get documents
- Update by query
- Delete by query
- Reindex documents
Term vector 작업
- Term vector
- Multi term vectors
풀 기반 수집 (Pull-based ingestion)
- Pull-based ingestion
더 알아보기 (Learn more)
- 단일 문서 작업과 다중 문서 작업의 차이를 이해하면 작업 성능을 높일 수 있어요.
- 낙관적 동시성 제어는 동시 쓰기가 잦은 환경에서 데이터 무결성을 지키는 핵심이에요.