인덱스 분할 API
인덱스 분할 API (Split Index API)
1.0부터 도입되었어요.
인덱스 분할(Split Index) API는 각 원래 프라이머리 샤드가 두 개 이상의 프라이머리 샤드로 나뉘는 새 대상 인덱스를 만들어 기존 인덱스의 프라이머리 샤드 수를 늘려요. 인덱스가 원래 샤드 수를 넘어 성장했고, 증가한 데이터 양이나 쿼리 부하를 처리할 추가 용량이 필요할 때 유용해요.
대상 인덱스의 프라이머리 샤드 수는 소스 인덱스의 프라이머리 샤드 수의 배수여야 해요. 예를 들어 프라이머리 샤드가 2개인 인덱스는 4개, 6개, 8개 또는 2의 다른 배수로 분할할 수 있어요. 단일 프라이머리 샤드를 가진 인덱스는 어떤 수의 샤드로도 분할할 수 있어요.
인덱스가 지원하는 최대 분할 수는 index.number_of_routing_shards 설정에 따라 달라져요. 이 설정은 일관된 해싱(consistent hashing)으로 문서가 분산되는 전체 해싱 공간을 정의해요. 일관된 해싱은 각 새 샤드가 원래 해시 공간의 완전하고 연속적인 하위 집합에 매핑되어야 하므로 곱셈적 인수만 지원돼요. 점진적 리샤딩(N에서 N+1)은 모든 샤드에 걸쳐 문서를 재조정해야 하는데, 검색 지향 데이터 구조에는 지나치게 비용이 많이 들기 때문이에요. 예를 들어 샤드가 2개이고 number_of_routing_shards가 12(2 x 2 x 3)로 설정된 인덱스는 다음 분할 경로를 지원해요:
2->4->12(2로 분할 후 3으로 분할)2->6->12(3으로 분할 후 2로 분할)2->12(6으로 분할)
명시적으로 구성되지 않으면 number_of_routing_shards는 최대 1,024개 샤드까지 반복적으로 두 배로 늘리는 것을 허용하는 값으로 기본 설정돼요.
출처: 문서
본문
사전 요구 사항
인덱스를 분할하기 전에 다음 조건을 충족해야 해요:
- 인덱스가 읽기 전용이어야 해요. 인덱스를 읽기 전용으로 만들려면 동적 인덱스 수준 인덱스 설정
index.blocks.write를true로 설정해요. - 클러스터 건강 상태가 green이어야 해요.
또한 분할 작업은 다음 제약을 적용해요:
- 대상 인덱스가 이미 존재하면 안 돼요.
- 소스 인덱스의 프라이머리 샤드 수가 대상 인덱스보다 적어야 해요.
- 대상 인덱스의 프라이머리 샤드 수는 소스 인덱스의 프라이머리 샤드 수의 배수여야 해요.
- 분할 과정을 처리하는 노드는 기존 인덱스의 두 번째 복사본을 수용할 충분한 여유 디스크 공간이 있어야 해요.
다음 요청은 catalog-logs 인덱스를 분할 준비를 위해 읽기 전용으로 만들어요:
PUT /catalog-logs/_settings
{
"settings": {
"index.blocks.write": true
}
}
분할 요청에는 매핑을 지정할 수 없어요. 대상 인덱스는 소스 인덱스의 모든 매핑을 상속해요.
분할 작업은 다음 단계를 수행해요:
- 동일한 매핑과 구성을 가지지만 더 많은 프라이머리 샤드 수를 가진 새 대상 인덱스를 할당해요.
- 소스 세그먼트에서 대상 인덱스 디렉터리로 하드 링크를 만들어요. 파일 시스템에 하드 링크 지원이 없다면 대신 전체 바이트 수준 복사가 발생하며, 이는 훨씬 더 오래 걸려요.
- 새 라우팅 레이아웃을 기준으로 각 문서를 올바른 대상 샤드에 재할당하고 더 이상 속하지 않는 문서를 제거하는 리해싱 패스를 실행해요.
- 닫힌 인덱스가 다시 열릴 때 실행되는 과정과 유사하게 대상 인덱스에서 샤드 복구를 시작해요.
분할 과정 모니터링
분할 API는 대상 인덱스가 클러스터 상태에 추가되자마자 반환돼요; 분할 작업이 완료될 때까지 기다리지 않아요. 분할 과정은 다음 샤드 상태를 거쳐 진행돼요:
- Unassigned : 대상 인덱스의 모든 샤드는 API가 반환된 직후 이 상태로 시작해요.
- Initializing : 프라이머리 샤드가 노드에 할당되면 이 상태로 전환되고 데이터 재분배가 시작돼요.
- Active : 분할이 완료되면 샤드가 활성 상태가 돼요. 그러면 OpenSearch가 구성된 복제본을 할당하려 시도하고, 균형을 맞추기 위해 프라이머리 샤드를 다른 노드로 옮길 수도 있어요.
샤드 복구 진행 상황은 CAT recovery API로 추적하거나, Cluster Health API를 wait_for_status=yellow와 함께 사용해 모든 프라이머리 샤드가 할당될 때까지 기다릴 수 있어요.
대상 인덱스를 만들 때 OpenSearch 인덱스 이름에는 다음 제한이 있다는 것을 기억해요:
- 모든 글자는 소문자여야 해요.
- 인덱스 이름은 밑줄(
_)이나 하이픈(-)으로 시작할 수 없어요. - 인덱스 이름에는 공백, 쉼표, 또는 다음 문자를 포함할 수 없어요:
:, ", *, +, /, \, |, ?, #, >, 또는 <
엔드포인트
POST /{index}/_split/{target}
PUT /{index}/_split/{target}
경로 파라미터
사용할 수 있는 경로 파라미터는 아래 표와 같아요.
| 파라미터 | 필수 | 데이터 타입 | 설명 |
|---|---|---|---|
index |
필수 | String | 분할할 소스 인덱스의 이름이에요. |
target |
필수 | String | 생성할 대상 인덱스의 이름이에요. |
쿼리 파라미터
사용할 수 있는 쿼리 파라미터는 아래 표와 같아요. 모든 쿼리 파라미터는 선택사항이에요.
| 파라미터 | 데이터 타입 | 설명 | 기본값 |
|---|---|---|---|
wait_for_active_shards |
String | OpenSearch가 응답을 반환하기 전에 사용할 수 있어야 하는 활성 샤드 복사본 수예요. 분할 작업은 새 인덱스를 만들기 때문에 인덱스 생성 시의 wait for active shards 설정이 여기에도 적용돼요. all 또는 양의 정수로 설정해요. 1보다 큰 값은 복제본이 필요해요. 예를 들어 값을 3으로 지정하면 요청이 성공하려면 인덱스에 두 개의 추가 노드에 분산된 복제본 두 개가 있어야 해요. |
1 |
cluster_manager_timeout |
String | 클러스터 매니저 노드에 연결될 때까지 기다리는 시간이에요. | 30s |
timeout |
String | 응답을 기다리는 시간이에요. 시간 초과 전에 응답을 받지 못하면 요청이 실패하고 오류를 반환해요. | 30s |
wait_for_completion |
Boolean | false로 설정하면 작업이 끝난 후가 아니라 즉시 요청이 반환돼요. 작업 상태를 모니터링하려면 요청이 반환한 작업 ID와 함께 Tasks API를 사용해요. |
true |
task_execution_timeout |
String | 작업이 완료될 때까지 기다리는 시간이에요. wait_for_completion이 false로 설정된 경우에만 적용돼요. |
1h |
요청 본문 필드
사용할 수 있는 요청 본문 필드는 아래 표와 같아요. 모든 필드는 선택사항이에요.
| 필드 | 데이터 타입 | 설명 |
|---|---|---|
settings |
Object | 대상 인덱스에 적용할 인덱스 설정이에요. Index settings를 참고해요. |
aliases |
Object | 대상 인덱스와 연결할 별칭이에요. Alias APIs를 참고해요. |
인덱스 코덱 고려 사항
인덱스 코덱 고려 사항은 Index codecs를 참고해요.
예시: 인덱스 분할
다음 예제는 catalog-logs 인덱스를 2개의 프라이머리 샤드에서 4개로 분할하고, 쓰기 블록을 제거하고, 별칭을 연결해요:
POST /catalog-logs/_split/catalog-logs-split
{
"settings": {
"index.number_of_shards": 4,
"index.number_of_replicas": 0,
"index.blocks.write": null
},
"aliases": {
"catalog-logs-current": {}
}
}
예시: 단일 샤드 인덱스 분할
단일 프라이머리 샤드를 가진 인덱스는 어떤 수의 샤드로도 분할할 수 있어요. 다음 예제는 catalog-events 인덱스를 1개 샤드에서 3개로 분할해요:
POST /catalog-events/_split/catalog-events-expanded
{
"settings": {
"index.number_of_shards": 3,
"index.number_of_replicas": 0,
"index.blocks.write": null
}
}
응답 예시
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "catalog-logs-split"
}
응답 본문 필드
모든 응답 본문 필드는 아래 표와 같아요.
| 필드 | 데이터 타입 | 설명 |
|---|---|---|
acknowledged |
Boolean | 클러스터의 관련 노드들이 요청을 승인했는지 여부를 나타내요. |
shards_acknowledged |
Boolean | 요청이 시간 초과되기 전에 필요한 수의 샤드 복사본이 시작되었는지 여부를 나타내요. |
index |
String | 생성된 대상 인덱스의 이름이에요. |
필요한 권한
보안 플러그인을 사용한다면 다음 권한이 필요해요: indices:admin/resize.