쓰기 작업은 3단계로 수행된다.
주 샤드가 요청을 넘겨 받은 이후 수행하는 작업들을 주 샤드 단계
라고 한다.
in-sync
복제본에 병렬적으로 요청을 넘긴다.in-sync 복제본: 마스터 노드가 관리하는 복제받을 샤드 목록
각 in-sync
복제본 샤드는 주 샤드에게 받은 요청을 로컬에서 수행하고 주 샤드에게 작업이 완료됐음을 보고한다.
조정 단계, 주 샤드 단계, 복제 단계는 이 순서대로 실행되지만 종료는 역순이다.
한 문서의 views 필드 값을 1로 색인했다면 잠시 후 복제본에도 이 내용이 적용된다.
그런데 이 변경 내용이 복제본 샤드에 완전히 적용되기 전에 다른 클라이언트로부터 주 샤드에 같은 문서의 views 필드 값을 2로 색인하는 변경이 발생했다고 가정해 보자.
_seq_no
가 존재한다._seq_no
는 각 주 샤드마다 들고 있는 시퀀스 숫자값이며 매 작업마다 1씩 증가한다.
_id
값은 같은데 _seq_no
값은 더 작은 색인 요청을 받는다면 이전 버전의 요청을 늦게 들어온 것으로 판단하고 작업을 수행하지 않는다.주 샤드를 들고 있는 노드에 문제가 발생하여 해당 노드가 클러스터에서 빠진다면 엘라스틱서치는 복제본 샤드 중 하나를 주 샤드로 지정한다.
_primary_term
이라는 값으로 새로 임명된 주 샤드를 구분한다.PUT concurrency_test
{
"settings": {
"number_of_shards": 2
}
}
PUT concurrency_test/_doc/1
{
"views": 1
}
{
"_index": "concurrency_test",
"_type": "_doc",
"_id": "1",
"_version": 1,
"result": "created",
// ...
"_seq_no": 0,
"_primary_term": 1
}
같은 _id
로 문서를 색인하면 _seq_no
가 올라간다.
PUT concurrency_test/_doc/1
{
"views": 2
}
{
"_index": "concurrency_test",
"_type": "_doc",
"_id": "1",
"_version": 2,
"result": "updated",
// ...
"_seq_no": 1,
"_primary_term": 1
}
_seq_no
는 주 샤드마다 따로 매긴다.
PUT concurrency_test/_doc/A
{
"views": 0
}
{
"_index": "concurrency_test",
"_type": "_doc",
"_id": "A",
"_version": 1,
"result": "created",
// ...
"_seq_no": 0,
"_primary_term": 1
}
if_seq_no
와 if_primary_term
에 각각 _seq_no
와 _primary_term
을 넣을 수 있다. _seq_no
와 _primary_term
이 지정한 값과 같을 때만 색인 작업이 수행된다.PUT concurrency_test/_doc/1?if_primary_term=1&if_seq_no=1
{
"views": 0
}
_version
은 _seq_no
와 _primary_term
처럼 동시성을 제어하기 위한 메타데이터로 모든 문서마다 붙는다._version
은 0이상 long 범위 이내의 정수여야 한다._seq_no
, _primary_term
과 다른 점은 클라이언트가 문서의 _version
값을 직접 지정할 수 있다.version_type
을 external(external_gt)
이나 external_gte
로 설정하면 클라이언트가 직접 _version
을 지정할 수 있다.version_type
은 internal
다른 스토리지에서 저장된 데이터의 버전을 따로 관리하고 있고 그 데이터를 엘라스틱서치로 받아 와서 2차 스토리지로 동기화하여 사용하는 경우 활용하기 좋다.
Coordination Node
)는 클라이언트로부터 읽기 작업을 요청받는다.🚨 주 샤드에 색인이 완료됐지만 특정 복제본 샤드에는 반영이 완료되지 않은 상태의 데이터를 읽을 수도 있다.
만약 문제가 생겨서 특정 노드가 재기동되었다면 그 노드가 들고 있던 샤드에 복구 작업이 진행된다.
_primary_term
과 _seq_no
를 조합하면 샤드와 샤드 사이에 어떤 반영 차이점이 있는지를 알 수 있다.
각 샤드는 로컬에 작업을 수행하고나면 몇 번 작업까지 순차적으로 수행을 완료했는지를 ✅ 로컬 체크포인트
로 기록한다.
ex) _seq_no가 각각 1, 2, 3, 5, 7인 작업을 수행한 샤드는 로컬 체크포인트값을 3으로 업데이트한다.
- 3번 작업까지는 빠짐없이 반영됐다는 뜻이다.
- 복제본 샤드는 로컬 체크포인트가 업데이트되면 이를 주 샤드에 보고한다.
- 이후에 이 복제본 샤드가 4번 작업을 수신하여 반영을 완료하면 로컬 체크포인트를 5로 업데이트한다.
주 샤드는 각 복제본 샤드로부터 받은 로컬 체크포인트
를 비교하여 가장 낮은 값을 ✅ 글로벌 체크포인트
값으로 기록한다.
글로벌 체크포인트가 업데이트되면 다음 색인 작업 시 그 내용을 주 샤드가 복제본 샤드로 전달한다.
문제가 발생해 샤드를 복구해야 할 경우가 생기면 샤드 간에 글로벌 체크포인트
를 비교한다.
글로벌 체크포인트
가 같다면 이 샤드는 추가 복구 작업이 필요 없다.엘라스틱서치는 논리적 삭제를 도입했다.
최근 삭제한 문서를 일정 기간 보존해 두고 작업 재처리에 활용한다.
재처리할 내용을 추적하는 메커니즘
루씬의 세그먼트가 병합되는 도중에도 샤드 이력은 지정한 기간 동안은 보존된다. (default: 12시간)
index.soft_deletes.retention_lease.period