본 포스팅은 2023년 01월 01일을 기준으로 작성되었습니다.
Searchable Snapshot은 검색이 가능한 snapshot을 의미합니다. Searchable Snapshot을 사용하면 S3를 비롯한 다른 외부 저장소에 저장된 snapshot을 바로 검색할 수 있습니다. 이를 통해 보다 낮은 비용으로 데이터를 빠르게 복구하거나 불러올 수 있습니다.
이러한 원리를 이해하기 위해서는 cold티어와 frozn티어의 데이터 저장 및 로드 구성을 알아볼 필요가 있습니다.
Elasitcsearch에서 데이터 티어는 Hot, Warm, Cold, Frozen 4가지로 나뉩니다. 데이터 티어가 오른쪽으로 넘어갈 수록 일반적으로 검색 속도가 느려지고, 비용이 저렴해집니다.
Hot티어와 Warm티어에서는 디스크의 절반이 샤드의 replica를 저장하는데 사용됩니다.
이러한 replica를 통해서 쿼리의 빠르고 일관된 성능을 보장하고, 시스템 장애 시 replica가 primary shard로 승격함으로서 복구가 빨라 인덱싱과 검색 모두 중단 없이 유지됩니다. (이렇듯 replica는 빠르고 일관된 쿼리 성능와 시스템 장애시 데이터 복원을 해주는 역할을 합니다.)
<hot&warm티어에서의 데이터 저장 방식>
Cold티어부터는 데이터가 자주 엑세스되지 않기에 read-only 타입으로 변환되고, 데이터의 replica를 S3에 snapshot 형태로 저장됩니다. Snapshot은 S3와 같은 외부 저장소에 저장됩니다.
Hot(또는 Warm)티어와 비교하면 저장공간을 최대 50%까지 줄일 수 있습니다.
Cold티어는 Hot(또는 Warm)티어에서와 동일한 수준의 안정성 및 중복성을 유지하며 노드나 하드웨어에 장애 발생 시 자동 복구를 완벽하게 지원합니다. Cold티어에서 로컬 노드(또는 로컬 디스크)에 장애가 발생하는 경우 S3에 snapshot으로 저장된 replica 인덱스를 통해 자동으로 복구할 수 있습니다.
이때 S3(외부 저장소)에 저장된 snapshot은 restore 과정을 거칠 필요 없이 searchable snapshot 기능을 사용하여 바로 검색을 할 수 있기 때문에 일반적인 snapshot 복원에 걸리는 시간보다 훨씬 짧은 시간에 검색 요청을 처리할 수 있습니다.
Frozen티어에서는 오래되었지만 의무적으로 보관해야하는 데이터를 보관하기에 적절합니다.
또한, Frozen티어에서는 searchable snapshot이 필수적으로 사용되며, S3에 있는 데이터를 바로 검색할 수 있습니다. 그렇기에 저장된 snapshot을 restore하는 과정을 거칠 필요가 없어 매우 빠릅니다. 그리고, Frozen티어는 외부 저장소(S3)를 캐시 스토어로 활용하며, searchable snapshot을 캐시 형태로 저장합니다.
<Frozn티어에서의 캐시 저장 >
Frozen티어 노드에서는 LFU 캐시 알고리즘을 사용하여 자주 요청되는 인덱스 데이터만 로컬 디스크 캐시에 유지합니다. 검색 요청 시, 먼저 디스크 캐시를 확인하고(페이지 캐시 방식) 해당 데이터가 없으면 원본 스토리지(S3 등)에서 16MB 청크 크기로 데이터를 읽어옵니다. 이후 동일한 데이터에 대한 요청은 로컬 캐시에서 빠르게 제공됩니다.
요약하면, Frozen Tier에서 S3같은 저렴한 대용량 스토리지를 활용하면서도 자주 사용되는 데이터에 대해서는 로컬 캐시를 통해 검색 성능을 높이는 Searchable Snapshot에 대한 설명입니다.
즉, Frozen Tier는 LFU 캐시 정책으로 불필요한 데이터는 제거하되, 범위 쿼리에 필요한 데이터는 유지합니다.
그리고 검색 시 필요한 부분만 인덱스 구조를 활용해 빠르게 로드하고, 인덱스 자체도 온디멘드 방식으로 열어 메모리 사용을 최적화하는 전략을 사용합니다.
<그때그때 필요한 인덱스 구조만 활용하여 속도 향상>
ILM(Index lifecycle management)을 구성하여 오래된 데이터를 자동으로 Frozen Tier로 이동하도록 설정할 수 있다.
아래 예제는 Hot phase에서 인덱스의 primary shard 사이즈가 10GB가 되면 Roll-over되며, 생성된지 90일이 지난 데이터를 Frozen phase로 보내는 설정입니다.
Rollover된 날을 기준으로 90일이 경과되면 Frozen으로 이동
Frozen으로 이동되는 단위는 Index단위
샘플로 사용한 데이터는 "캐리샷(Carryshot)"이라는 골프 스윙 녹화 어플로 사용자들이 해당 어플을 사용할 때마다 실시간으로 데이터가 엘라스틱서치에 인덱싱되는 실시간 데이터입니다. (정보제공 동의한 사람의 한에서 데이터 수집)
데이터는 carry_event라는 Index에 저장됩니다.
테스트 환경을 위해 ILM에서 Hot phase: Rollover 설정을 10mb정도로 굉장히 낮게 하였습니다.
carry_event-000001 ~ carry_event-000022와 같은 형태는 rollover와 alias 기능을 사용하여 해당 인덱스가 적정 사이즈(또는 일수days)가 되었을 때 새로운 인덱스에 저장하게 설정을 해주었기 때문에 다음과 같은 형식으로 인덱스가 생성됩니다.
위에 사진을 보시면, Storage size가 0b인 인덱스는 index이름 앞에 partial-이라는 접두사가 붙습니다.
즉, 해당 인덱스들은 Frozen Phase에 스냅샷이 저장되어 현재 데이터 사이즈는 0으로 나타납니다. Frozen은 부분적으로 마운트되기 때문에 인덱스는 접두사 partial-가 붙습니다.
Frozen Phase로 옮겨진 인덱스 partial-carry_event-000001으로 쿼리를 날려보았습니다.
데이터 사이즈나 갯수가 많지 않지만 그래도 0.356ms 안에 데이터를 가져오는 것을 확인할 수 있었습니다.
대시보드도 데이터를 잘 불러옴을 확인 할 수 있었습니다.
Cold Phase 설정에서 Searchable snapshot을 비활성화하면 데이터 사이즈는 아무런 변화없이 Cold Phase로 이동됩니다.
Cold Phase 설정에서 Searchable snapshot을 활성화 하게 되면 위에 설명과 같이 Primary 샤드만 저장됨으로 현재 Primary 1개, Replica 1개가 설정되어 있는 상태에서는 50% 용량이 줄어든 것을 확인할 수 있습니다.