Lucene을 공부하면서 실제 세그먼트를 조작 하고 인덱싱을 반영 하는 부분을 보면서 Lucene에 commit에 대해서 공부했었다.
그럼 실제로 Elasticsearch에서 이 Lucene commit에 영향을 받는 부분이 어디인지 알아보게 되면서 translog에 대해 공부해봤다.
우선 translog는 양 자체가 워낙 방대하기 때문에 성능을 위해서는 이 부분에 대한 튜닝이 중요하다고 들었고 Elasticsearch 업데이트 때마다 release note에서 이 부분에 대한 이야기가 많이 나온다. 그럼 실제로 이 translog가 무엇인지 확인해보자.
TransLog란?
Lucene의 변경 사항은 Lucene commit 중에만 디스크에서 지속하며 이는 저번에 공부하였듯이 비용이 많이 들고 모든 색인 또는 삭제 작업 후에 실행할 수는 없다. 하나의 커밋이 발생한 후 다른 커밋이 발생되기 전에 프로세스가 종료되거나 하드웨어에 오류가 발생되는 경우에는 Lucene에 의해 변경사항은 제거가 된다.
이와 같은 이유로Lucene의 모든 개별적인 변화에 commit이 수행되기에는 너무 비용이 비싸기 때문에 각 shard들은 translog라고 하는 곳에 트랜잭션 로그를 기록한다. Elasticsearch에서 모든 indexing과 delete 작업은 내부 Lucene에 의해서 색인이 되기전까지 translog에 기록된다. 이렇게 기록된 translog는 충돌이 발생한 경우에는 아직 마지막으로 Lucene에 의해 기록되지 못한 request를 복구하기 위해 사용된다.
Elasticsearch의 flush는 Lucene commit을 수행하고 새로운 translog를 생성하는 작업이다. flush는 translog가 너무 커져서 복구 작업이 너무 오래 걸리지 않게 하기 위해서 백그라운드에서 주기적으로 실행된다. (이 flush interval이 너무 작게 되면 그만큼 Lucene의 commit을 수행하기 때문에 너무 짧게 가져가면 안된다. 하지만 Lucene commit이 되어야 실질적으로 searchable하기 때문에 이는 잘 조절해야한다.)
그리고 flush를 매뉴얼 하게 실행시키기 위해서 사용하는 api가 제공 되는데 이는 거의 사용되지 않는다.
Translog 설정
translog 내부에 있는 데이터는 오직 fsynced나 commit 상태에서만 디스크에서 존재한다. (이곳에서 말하는 commit은 translog에 대한 commit으로 Lucene에서의 commit과 다르다.) 하드웨어 손상이나 os system 충돌, jvm 충돌, shard failure과 같은 이벤트가 발생하게 되면 이전 translog 커밋 이후 기록된 모든 데이터는 손상된다.
기본적으로 index.translog.durability 설정은 request로 설정되어 있는데 이는 Elasticsearch가 translog가 성공적으로 fsync 상태가 되고 모든 shard(복제본 포함)에 commit이 된 상태에서만 client에 index, delete, bulk등의 동작에 대한 성공여부를 전달해준다. 만약 async로 설정되어 있을 경우 Elasticsearch는 모든 index.tranlog.sync_interval로 설정된 주기에서만 translog를 디스크에 fsync하고 commit한다. 이럴 경우 주기에 도달하기 전에 충돌이 발생했다면 노드가 복구될 때 이전 까지의 작업들은 모든 손실된다.
index.tranlog.sync_interval
-> 다른 동작에 상관없이 얼마나 종종 translog를 디스크에 fsync, commit할 것인지에 대한 설정
-> 기본 설정은 5초이며 100ms보다 작은건 허용되지 않는다.
index.translog.durability
-> 모든 index, delete, bulk등의 작업 수행 후 translog를 fsync하고 commit 할 것인지에 대한 여부를 설정
-> 기본은 request이며 모든 요청에 대해서 translog를 fsync하고 commit한다. 하드웨어 실패가 발생되었을 때 모든 변경 내용을 이미 disk에 commit 되어 있어 복구가 가능하다.
-> aync로 설정한 경우 sync_interval로만 trnaslog를 기록한다. 실패가 발생하게 되면 마지막 commit 이후에 발생된 모든 내용은 손실된다.
index.translog.flush_treshold_size
-> translog는 위에 말했듯이 아직 Lucene에 반영되지 못한 내용들이 저장된다. 이러한 내용들은 shard가 멈추게 되면 복구를 위해서 읽어야하는데 이 translog를 읽는 데이터가 너무 많게 되면 복구를 지연시키기 때문에 해당 설정을 통해 이 동작의 최대 크기를 조절해줘야 한다. shard의 복구 작업 중 해당 설정의 값만큼 읽어서 복구를 진행하게 되면 Elasticsearch의 flush를 실행 시키고 이때 새로운 Lucene 포인트가 발생된다. 이 설정의 기본값은 512mb이다.
정리하면,
translog는 Elasticseach에서 index에 작업을 하는 내용을 각 shard별로 기록하는 로그이며 이는 Elasticserach가 flush가 되는 순간에 Lucene에 commit 명령어를 보내면서 기록된다. 이때 기록된 translog는 Lucene commit작업이 완벽하게 끝나기전에 여러 이벤트로 shard 손상이 왔을 경우 복구하는데 사용되는 지점이 된다.
이 translog를 기록하는 것도 비용이 많이 들기 때문에 주기를 둬서 기록을 할 것인지 실제로 Elasticsearch에 index 작업이 있은다음에 발생할 것인지를 정할 수 있으며 복구할 때 읽어들이는 threshold값도 설정이 가능하다.
'데이터베이스 > Elasticsearch' 카테고리의 다른 글
Bulk Index 진행 시 search api 느려지는 현상 해결 방법 리서치 (0) | 2021.07.24 |
---|---|
Nested field에 대한 대체 필드 flattened type (0) | 2021.06.14 |
elasticsearch metric 수집 방법 (0) | 2021.01.11 |
Elasticsearch 7.7 feature와 heap 메모리 사용량의 두드러진 감소량 (0) | 2020.06.06 |
Too many dynamic script compilations 에러 (0) | 2020.03.07 |