엔지니어링

10분 이내에 페타바이트 규모의 클라우드 저장 공간 쿼리 작업

Elastic의 새로운 프로즌 데이터 티어는 컴퓨팅을 저장 공간에서 분리하고 Google Cloud Storage, Azure Blob Storage 또는 Amazon S3와 같은 저가 객체 저장소를 활용하여 직접 검색을 수행합니다. 저장 공간을 무제한 확장하는 동시에 데이터를 먼저 리하이드레이션할 필요 없이 효율적으로 쿼리할 수 있는 기능을 보존하여 규모에 맞게 데이터를 보다 쉽고 저렴하게 관리할 수 있습니다.

이 블로그 포스팅에서는 새로운 프로즌 티어의 검색 성능을 기존의 Elasticsearch 데이터 티어와 비교하고, 프로즌 티어를 사용하여 훨씬 더 많은 양의 데이터를 저장하고 검색하면서 성능을 낮추는 방법을 보여 드립니다. 프로즌 티어의 주요 내용은 다음과 같습니다.

  • 데이터가 캐시되지 않은 경우, 몇 초 만에 4TB 데이터 세트에 대한 간단한 용어 쿼리의 결과를 반환합니다. 캐싱된 경우, 성능은 밀리초 단위입니다. 웜 티어나 콜드 티어와 비슷합니다.
  • 4TB 데이터 세트에 걸쳐 복잡한 Kibana 대시보드를 계산하는 작업은 데이터가 캐시되지 않은 경우 5분 이내에 완료됩니다. 캐싱된 경우, 몇 초 안에 완료됩니다. 웜 티어나 콜드 티어와 비슷합니다.
  • 데이터 볼륨을 1PB 데이터 세트로 쉽게 확장합니다. 캐시되지 않은 간단한 용어 쿼리의 결과는 10분 이내에 반환됩니다.

프로즌 티어는 현재 Elasticsearch 7.12 및 Elastic Cloud에서 기술 미리보기로 제공되며, 조만간 정식 버전으로 출시될 예정입니다.

데이터 티어에 대한 빠른 소개

데이터 티어는 다양한 필요에 따라, 예를 들어 보존 기간, 데이터 소스 또는 기타 기준에 따라 데이터에 액세스할 수 있는 최적화된 저장 공간 및 처리 능력을 제공합니다. 핫 티어는 일반적으로 클러스터에 있는 새 데이터의 모든 색인을 처리하며 가장 자주 쿼리되는 최신 일일 인덱스를 보관합니다. 색인은 I/O 집약적인 작업인 경우가 많기 때문에 이러한 노드가 실행되는 하드웨어는 더 강력해야 하므로 SSD 저장 공간을 사용합니다. 웜 티어는 쿼리 빈도가 낮은 대량의 인덱스를 처리할 수 있으며, 대신 매우 큰 회전 디스크와 같이 대기 시간이 긴좀더 긴 저렴한 저장 공간을 사용할 수 있으므로 시간이 지남에 따라 데이터 보존에 드는 전체 비용이 절감되지만 쿼리에는 여전히 액세스할 수 있습니다.

최근에 도입된 콜드 티어와 프로즌 티어는 저렴한 객체 저장소를 활용하여 대용량 데이터 볼륨을 비용 효율적으로 관리하면서도 검색할 수 있습니다.

Price_Performance.PNG

콜드 티어는 복제본이 필요하지 않으므로 대신 스냅샷에서 데이터를 복원하여 복구 이벤트를 수행합니다. 핫 티어와 웜 티어에서는 일반적으로 디스크 공간의 절반이 복제본 샤드를 저장하는 데 사용됩니다. 이러한 중복 복사본은 빠르고 일관된 쿼리 성능을 보장하며, 복제본이 새로운 기본 저장 공간으로 대체되는 시스템 장애 시 복원력을 제공합니다. 그러나 데이터가 수명 주기 동안 읽기 전용이 되면 복구 작업을 스냅샷으로 오프로드할 수 있습니다. 즉, 콜드 티어에서는 복제본 샤드가 필요하지 않습니다. 노드나 디스크에 장애가 발생할 경우 스냅샷에서 자동으로 데이터를 복구하고, 로컬 디스크에서 검색을 다시 수행할 수 있도록 클러스터에 전체 복사본을 다시 생성합니다. 스냅샷 저장소는 로컬 SSD나 회전식 디스크보다 BLOB 저장소에 데이터를 저장하는 것이 훨씬 더 저렴하고, 대부분의 경우 백업 용도로 이미 BLOB 저장소에 있기 때문에 여기에 적합합니다. 따라서 콜드 티어는 웜 티어 로컬 저장 공간의 절반만 필요하며 쿼리 성능은 비슷하고 가용성은 약간 떨어지기 때문에 웜 티어보다 50%의 비용 절감 효과가 있습니다.

프로즌 티어는 한 단계 더 나아가, 검색 시 필요에 따라 클러스터에서 규모가 작고 자주 액세스하는 데이터 부분만 로컬로 캐싱하고 객체 저장소에서 데이터를 지연 로딩하여 컴퓨팅을 저장 공간과 분리합니다. 이는 Elasticsearch로 지금까지 가능했던 것보다 훨씬 높은 컴퓨팅 대 저장 공간 비율을 제공합니다. 물론 이러한 프로즌 티어의 검색 속도는 핫, 웜 또는 콜드 티어보다 훨씬 느릴 수 있지만, 운영 또는 보안 조사, 법적 발견 또는 이전 성능 비교와 같은 검색 빈도가 낮은 경우에는 이러한 차이가 허용될 수 있습니다. Elasticsearch에서 기본적으로 모든 항목을 색인할 수 있다는 이점은 쿼리 시 데이터를 전체 스캔할 필요가 없고 이러한 인덱스 구조를 활용하여 매우 큰 데이터 세트에 대한 결과를 신속하게 반환할 수 있기 때문에 매우 강력한 기능입니다.

프로즌 티어 작동 방식

프로즌 티어의 노드에는 모든 인덱스의 전체 복사본을 위한 충분한 디스크 공간이 필요하지 않습니다. 대신 특정 쿼리를 처리하기 위해 BLOB 저장소에서 다운로드한 인덱스 데이터의 일부만 캐시하는 디스크의 LFU 캐시를 도입했습니다. 디스크의 캐시는 운영 체제의 페이지 캐시와 유사하게 작동하여 자주 요청되는 BLOB 저장소 데이터에 대한 액세스 속도를 높입니다. Lucene 레벨의 읽기 요청은 이 로컬 캐시의 읽기 요청에 매핑됩니다. 캐시 누락이 발생하면 Lucene 파일의 더 큰 영역(16MB 청크)이 BLOB 저장소에서 다운로드되어 검색에 사용할 수 있습니다. 다음에 Lucene이 파일의 동일한 영역에 액세스할 때 로컬 캐시에서 바로 제공됩니다.

노드 레벨 공유 캐시는 "가장 자주 사용하지 않는" 정책에 따라 매핑된 파일 영역을 제거합니다. Lucene 파일의 일부 영역은 다른 영역보다 더 자주 사용될 것으로 예상됩니다. @timestamp 필드의 범위 쿼리와 같이 Lucene 파일의 일부 영역이 계속해서 쿼리에 응답해야 하는 경우, 다른 데이터가 제거되는 동안 데이터가 캐시 상태로 유지됩니다.

이제 검색에는 액세스 중인 파일의 영역을 다운로드해야 하지만, 사전 계산된 인덱스 구조 세트를 기반으로 검색을 실행하는 Lucene의 방식은 검색할 데이터의 양을 줄이고 이를 빠르게 만듭니다. 이러한 샤드의 메모리 설치 공간을 더욱 줄이기 위해 Lucene 인덱스는 필요할 때, 즉 활성 검색이 있을 때만 열립니다. 따라서 프로즌 티어 노드에서 다수의 인덱스를 사용할 수 있습니다.

벤치마킹 목표

각 티어에 대해 첫 번째 액세스 시(아직 워밍업되지 않았기 때문에 캐시를 활용하지 않음) 검색 성능과 동일한 쿼리(캐시 워밍업)로 반복 검색 성능을 측정합니다. 프로즌 티어의 경우 디스크의 LFU 캐시가 모든 데이터를 수용할 수 없을 때 반복 검색 성능도 확인합니다. 

이 벤치마크에 대해 두 가지 유형의 쿼리를 고려합니다. 첫 번째는 대규모 데이터 세트에서 일치하는 문서 세트를 찾는(건초 더미에서 바늘 찾기) 보안 조사를 나타내고, 두 번째는 대용량의 데이터에 대한 여러 개의 대용량 집계를 계산하는 Kibana 대시보드를 나타냅니다.

이러한 벤치마크의 목표는 여러 티어에서 쿼리 성능을 정확하게 비교하는 것이므로 모든 티어에서 동일한 시스템 유형을 사용하기로 선택했지만, 실제 구현에서는 티어별 시스템 유형을 사용하여 티어별 최적의 비용과 성능을 비교해야 합니다. 벤치마크의 기준선은 정기적인 시간 기반 Elasticsearch 인덱스를 제공하는 핫 티어입니다. 웜 티어는 핫 티어와 동일한 방식으로 데이터에 액세스하고, 이 벤치마크에서는 모든 티어에 걸쳐 동일한 시스템 유형을 사용하므로 핫 티어와 동일하며 별도로 나열되지 않습니다. 콜드 티어에는 스냅샷에서 마운트된 동일한 인덱스의 전체 복사본이 있습니다. 프로즌 티어에는 디스크의 LFU 캐시를 사용하여 스냅샷에서 마운트된 인덱스가 있습니다.

벤치마크 설정

벤치마크는 Elasticsearch 7.12.1을 사용하여 Google Cloud에서 실행되며 Elastic이 다양한 기능을 벤치마킹하는 데 사용하는 웹 서버 로그의 이벤트 기반 데이터 세트를 기반으로 합니다. 디스크의 색인된 데이터 세트의 크기는 4TB입니다(각각 5개의 샤드가 80GB인 10개의 시간 기반 인덱스). 샤드는 한 세그먼트로 강제 병합되어 읽기 성능이 최적화되며, 이는 데이터를 프로즌 티어로 이동할 때 인덱스 수명 주기 관리에서 기본적으로 사용하는 기능입니다. Elasticsearch의 repository-gcs 플러그인을 사용하여 Google Cloud Storage에서 액세스하는 데이터의 동일한(사전 계산된) 스냅샷이 각 티어를 벤치마킹하는 데 사용됩니다. 성능을 인위적으로 제한하지 않도록 복구 조절이 실행 중지되었습니다.

벤치마킹하는 첫 번째 검색은 간단한 용어 쿼리로서, 특정 IP 주소가 웹 서버에 액세스한 데이터 세트 "nginx.access.remote_ip": "1.0.4.230"에서 발생한 항목을 찾는 것입니다.

두 번째 검색은 5가지 시각화가 포함된 Kibana 대시보드이며, 404 응답 코드를 사용하여 요청을 분석하도록 설계되어 있습니다. 예를 들어, 더 이상 어디로도 유도하지 않는 링크를 찾는 데 사용됩니다.

blog-frozen-tier-benchmarking-1.png

각 벤치마크 시나리오에 앞서 OS 캐시 및 슬랩 객체 삭제, SSD 디스크 트리밍을 비롯한 실행 시간 변동을 줄이기 위한 여러 준비 단계를 실행합니다. 핫/웜 티어에서 Elasticsearch는 일부 Lucene 파일 유형을 매핑하는 hybridfs 저장소 유형을 기본값으로 사용합니다. 콜드 티어와 프로즌 티어는 메모리 매핑을 사용하지 않습니다. 메모리 매핑은 페이지를 프리페치하여 페이지 캐시에 영향을 미치므로, 메모리 매핑을 사용할 때 핫/웜 티어에서 결과를 제공할 뿐 아니라 콜드 티어와 프로즌 티어에서 로컬 파일에 액세스하는 방법에 더 가까운 "niofs" index.store.type으로 구성할 때에도 결과를 제공합니다.

여기서는 단순하게 진행하기 위해 단일 노드 클러스터만 벤치마킹하지만 각 티어는 다중 노드 클러스터도 지원합니다. 단일 노드 클러스터는 vCPU 8개, 64GB RAM(JVM 힙을 위한 이 중 29GB는 Elasticsearch가 사용) 및 RAID-0의 16x375GB 로컬 스크래치 SSD 디스크가 있는 Google Cloud의 N2D(n2d-custom-8vCPU-64GB) 인스턴스이며, 핫/웜 및 콜드 티어로 전체 4TB 데이터 세트를 수용할 수 있습니다. 디스크의 LFU 캐시에 대한 로컬 디스크가 빠르고 Google Cloud Storage에 대한 네트워크 연결이 빠르기 때문에 이 인스턴스는 프로즌 티어에 적합합니다.

또한 프로즌 티어의 디스크의 LFU 캐시에 대해 두 가지 캐시 크기를 실험하여 반복 검색의 중요성을 보여 줍니다. 200GB(데이터 세트의 5%) 및 20GB(데이터 세트의 0.5%)로 구성되었습니다.

결과

OS 레벨 페이지 캐시에서 애플리케이션 레벨 인메모리 캐시(예: Elasticsearch의 샤드 요청 캐시, 노드 쿼리 캐시)까지 다양한 캐싱 메커니즘의 영향을 받습니다. 각 결과에 대해 이러한 캐시가 어떻게 작동하는지 설명하겠습니다. 표시된 결과는 실행별 변동을 줄이기 위해 5번 실행의 중앙값입니다.

간단한 용어 쿼리

간단한 용어 쿼리부터 시작하겠습니다. 여기에서 주요 관찰 사항은 프로즌 티어가 몇 초 내에 4TB 데이터 세트에 대한 결과(5개의 일치 문서)를 반환하고, 데이터 세트의 극히 일부만 다운로드하여 일치하는 요소를 찾는다는 것입니다. 이것은 빠른 조회를 가능하게 하는 Lucene의 인덱스 구조의 힘을 강조해서 보여줍니다.

이제 데이터를 로컬 디스크의 LFU 캐시로부터 프로즌 티어에서 처리할 수 있으므로 쿼리를 반복 실행하면 모든 티어에서 유사한 성능을 얻을 수 있습니다. 이 유형의 쿼리는 캐시되지 않기 때문에 Elasticsearch의 메모리 내 결과 캐시가 여기서 작동하지 않습니다. 핫/웜 및 콜드 티어의 반복 실행 성능은 페이지 캐시에서 데이터를 사용할 수 있게 되면 영향을 받습니다.

4TB 데이터 세트에 대한 간단한 용어 쿼리

조치

핫/웜 티어 niofs

콜드 티어

프로즌 티어

간단한 용어 쿼리: 첫 실행

92ms

95ms

6257ms

간단한 용어 쿼리: 반복 실행

29ms

38ms

76ms

niofs 대신 기본 인덱스 저장소 유형 hybridfs를 사용할 경우(92ms 대신 285ms) 핫/웜 티어의 성능이 처음 실행 시 약간 저하되며, 자세한 내용은 다음 섹션에 나와 있습니다.

Kibana 대시보드

Kibana 대시보드에 대해서도 동일한 프로세스를 반복합니다. 여기에서 주요 관찰 사항은 로컬 데이터 액세스가 설정된 다른 티어에서 대시보드를 계산하는 데 20초가 걸리는 데 비해 프로즌 티어는 동일한 4TB 데이터 세트에 대해 5분 이내에 대시보드를 반환한다는 것입니다. 대시보드는 시간 범위 필터를 사용하여 데이터 세트의 75% 이상을 집계하고 있지만 인덱스 구조 덕분에 저장소에 있는 데이터의 일부만 다운로드하면 됩니다(이 경우에는 데이터의 약 3%, 자세한 내용은 아래 참조).

4TB 데이터 세트의 Kibana 대시보드

조치

핫/웜 티어 niofs

콜드 티어

프로즌 티어

(5% 캐시)

프로즌 티어(0.5% 캐시)

대시보드: 첫 실행

16.3s

16.6s

282.8s

321.5s

대시보드: ES 결과 캐시 없이 정확한 반복 실행

6.2s

7.1s

11.1s

224.1s

대시보드: ES 결과 캐시를 사용한 정확한 반복 실행

80ms

75ms

-

-

대시보드: ES 결과 캐시 없이 유사한 반복 실행

19.5s

20.3s

23.4s

238.4s

Elasticsearch의 결과 캐시를 사용하지 않도록 설정하면 반복 검색 성능은 주로 페이지 캐시에 따라 달라지며 쿼리에 필요한 데이터 부분이 디스크의 LFU 캐시에 완전히 들어맞을 때 프로즌 티어와 비슷한 성능을 발휘합니다. 여기서도 주목할 점은 이 특정 워크로드의 메모리 매핑으로 인해 페이지 캐시 스레싱이 발생하여 기본 저장소 유형(niofs 6.2s에 비해 최대 3배 느림)을 사용할 때 핫/웜 티어의 성능에 부정적인 영향을 미친다는 것입니다.

프로즌 티어의 경우 반복 검색 성능에 미치는 영향을 보여 주기 위해 LFU 캐시에 대해 두 가지 크기를 고려합니다. 디스크의 LFU 캐시의 치수는 처음에는 200GB로, 4TB(데이터 세트 크기의 5%)의 일부에 불과하지만, 특정 대시보드를 계산하기 위해 다운로드한 모든 데이터(약 3% 또는 120GB)를 저장할 수 있을 만큼 큽니다. 두 번째 벤치마킹에서는 특정 대시보드의 모든 데이터를 저장하기에 충분하지 않은 20GB(원래 데이터 세트 크기의 0.5%)로 치수가 조정됩니다.

Elasticsearch의 메모리 내 캐시를 사용하도록 설정하면 쿼리 결과의 일부를 Elasticsearch 노드에서 직접 사용할 수 있으므로 다시 계산할 필요가 없기 때문에 반복 검색이 훨씬 더 빨라집니다. 그러나 현재 프로즌 티어는 이러한 메모리 내 Elasticsearch 캐시를 사용하지 않습니다.

또한 약간 다른 대시보드만 계산되고 다른 국가 코드로 필터링되는 경우를 벤치마킹했습니다. 이 경우 약간 다른 쿼리를 충족하는 데 필요한 데이터의 많은 부분을 이미 다운로드하고 결과를 다른 티어만큼 빠르게 반환하면 프로즌 티어에 이점을 얻을 수 있습니다.

대시보드를 처음 실행하는 동안 프로즌 티어에서 다운로드된 내용을 보여 주기 위해 요청된 가장 큰 6가지 Lucene 파일 유형과 다운로드된 파일 유형을 시각화했습니다. fdt (Field Data) 파일이 가장 많은 공간(문서 저장)을 사용하지만 이러한 파일은 컴퓨팅 집계에 액세스할 수 없습니다. 예상대로 대부분의 액세스는 집계에 사용되는 문서 값인 Lucene의 dvd(문서별 값) 파일에서 수행됩니다.

blog-frozen-tier-benchmarking-2.png

대용량 객체 저장 공간에 대한 빠른 액세스

프로즌 티어에 대한 쿼리는 확실히 느리지만, 검색에 데이터를 리하이드레이션할 필요가 없는 경우 자주 액세스하지 않는 것이 주요 이점입니다. 이에 비해 전체 데이터 세트를 로컬에서 사용할 수 있도록 설정하는 데는 복구 조절 기능이 해제되어 있더라도 1시간 이상이 소요되며, 이는 프로즌 티어에서 쿼리를 직접 실행하는 데 걸리는 시간보다 훨씬 긴 시간입니다.

4TB 데이터 세트 액세스 가능

조치

핫/웜 티어

콜드 티어

프로즌 티어

스냅샷에서 인덱스 복원

72.4min

-

-

스냅샷에서 인덱스 마운트

-

115s

47s

예열(콜드 티어에서 로컬로 데이터를 완전히 사용할 수 있는 시간)

-

82.8min

-

페타바이트까지 확장

지금까지 벤치마크는 티어 간 성능 비교에 초점을 맞췄지만, 프로즌 티어에서 가능한 전체 규모를 보여주지는 못했습니다. 이 티어는 다른 티어보다 높은 컴퓨팅 대 저장 공간 비율을 제공합니다. 이를 극단적으로 확대하기 위해 매번 다른 이름으로 동일한 데이터 세트를 250회 이상 마운트하여 별도의 인덱스로 처리했습니다. 단일 노드 클러스터에는 각각 80GB의 12500개의 샤드가 있었으며 이는 정확히 1PB의 데이터에 해당합니다. 전체 1PB(= 100만 GB) 데이터 세트에 대해 단순 용어 쿼리를 실행하는 데 10분도 걸리지 않았으며, 이는 구현이 대규모 데이터 세트로 얼마나 원활하게 확장되는지 보여줍니다.

1PB 데이터 세트에 대한 간단한 용어 쿼리

조치

핫/웜 티어

콜드 티어

프로즌 티어

간단한 용어 쿼리: 첫 실행

불가능(1PB의 로컬 저장 공간 필요!)

554s

간단한 용어 쿼리: 반복 실행(4TB 디스크의 LFU 캐시 사용)

127s

실제로 단일 노드에 그렇게 많은 수의 샤드가 있고 로컬 디스크 캐시와 객체 저장 공간 크기의 비율이 매우 낮은 이상적인 설정에는 적합하지 않을 수 있습니다. 이 규모에서는 데이터 세트의 저장 공간 비용도 프로즌 티어 노드의 컴퓨팅 비용을 줄여주므로 노드를 추가하면 성능에 큰 도움이 되지만 비용에 미치는 영향은 미미합니다.

디스크의 LFU 캐시 크기 조정

앞서 살펴본 바와 같이 반복 검색에 적합한 성능을 얻기 위해 디스크의 LFU 캐시의 치수가 중요합니다. 여기서 올바른 값은 실행되는 쿼리의 종류, 특히 쿼리 결과를 얻기 위해 액세스해야 하는 데이터의 양에 따라 달라집니다. 따라서 마운트된 데이터의 양이 많아도 디스크의 캐시가 더 많이 필요하지는 않습니다. 예를 들어 시간 기반 인덱스의 컨텍스트에서 시간 범위 필터를 적용하면 쿼리해야 하는 샤드의 수가 줄어듭니다. 데이터 액세스 패턴에는 종종 공간적 또는 시간적 인접성이 내재되어 있기 때문에, 프로즌 티어는 매우 큰 데이터 세트에 대해 효율적인 쿼리를 가능하게 합니다. 현재 관찰한 바에 따르면 마운트된 데이터 세트 크기의 1%~10%가 되도록 디스크의 LFU 캐시 크기를 조정하는 것이 좋습니다. 5%의 비율은 아마도 실험의 좋은 시작점일 것입니다.

연산은 매우 병렬이므로 수직 및 수평 확장이 모두 프로즌 티어에서 잘 지원됩니다. 더 많은 성능 시스템 유형을 사용하거나 클러스터에 노드를 추가하는 것만으로 프로즌 티어에서 쿼리 성능을 높일 수 있습니다.

결론

프로즌 티어는 두 가지 유형의 쿼리에 뛰어난 성능으로 응답할 수 있다는 것을 보았습니다. Elasticsearch의 기본 인덱스별 전략을 사용하면 전체 데이터 세트를 검색하는 것보다 프로즌 티어의 검색 성능이 훨씬 더 빠릅니다. 프로즌 티어에서 반복 검색을 수행하면 디스크의 캐시의 이점을 더욱 누릴 수 있으며 다른 티어와 유사한 성능을 제공합니다.

비용 효율적인 저장 공간과 유연한 컴퓨팅 대 저장 공간 비율이 주요 목표인 경우 프로즌 티어가 큰 가치를 제공합니다. 프로즌 티어의 데이터는 일반 인덱스로 액세스되므로 기존 설정을 쉽게 전환하여 이 새로운 유용한 기능을 활용할 수 있습니다. 또한 이미 백업 용도로 사용되는 스냅샷 저장소를 재사용하고 인덱스 수명 주기 관리에 완벽하게 통합되어 데이터를 핫/웜/콜드에서 프로즌 티어로 전환하므로 설정도 어렵지 않습니다. Kibana의 비동기 검색 통합은 이 외에도 확장 기능을 제공하여 느리게 실행되는 대시보드를 백그라운드에서 계산하고 사용 가능한 경우 시각화할 수 있도록 지원합니다.

프로즌 티어는 자체 호스트형 배포와 Elastic Cloud에 모두 사용할 수 있으므로 설명서를 확인하고, 사용해 보신 후, 의견을 제공해 주세요.