Husky 쿼리 엔진 내부: 100조 개 이벤트에 대한 실시간 액세스 (새 탭에서 열림)
Datadog은 매일 100조 개 이상의 이벤트와 수십억 개의 쿼리를 처리하기 위해 3세대 이벤트 저장소인 'Husky'를 구축했습니다. Husky의 쿼리 엔진은 고정된 스키마가 없고 데이터 볼륨이 가변적인 대규모 멀티테넌트 환경에서도 오브젝트 스토리지에 저장된 페타바이트급 데이터를 실시간으로 조회할 수 있도록 설계되었습니다. 이를 위해 시스템은 쿼리 플래너, 오케스트레이터, 메타데이터 서비스, 리더 서비스로 역할을 분산하여 성능과 비용 효율성을 동시에 달성했습니다. ### Husky의 데이터 모델과 주요 쿼리 패턴 Husky는 로그나 네트워크 트래픽과 같이 타임스탬프와 다양한 속성을 가진 '이벤트' 데이터를 저장하며, 서비스별로 상이한 데이터 형태를 유연하게 수용합니다. * **가변적인 스키마 지원:** 테넌트나 사용 사례(로그 vs 네트워크 데이터)에 따라 속성의 종류와 데이터의 크기가 극명하게 달성하더라도 효율적으로 처리할 수 있습니다. * **Needle-in-a-haystack 검색:** 수많은 데이터 중 특정 IP나 에러 메시지, 트레이스 ID 등을 찾아내는 고도로 선택적인 필터링 쿼리를 지원합니다. * **분석형(Analytics-style) 검색:** 특정 기간 동안의 서비스 지연 시간 추이나 지역별 매출 분석과 같이 대규모 데이터를 집계하여 시각화하는 쿼리를 최적화합니다. ### 쿼리 실행의 4단계 아키텍처 Husky의 쿼리 경로는 네 가지 핵심 서비스로 나뉘어 멀티테넌트 환경에서 안정적으로 동작합니다. * **쿼리 플래너(Query Planner):** 모든 쿼리의 진입점으로, 쿼리 유효성 검사 및 최적화를 수행합니다. 통계 데이터를 기반으로 쿼리를 시간 단위의 여러 단계로 분할하고 실행 결과를 최종 병합합니다. * **쿼리 오케스트레이터(Query Orchestrator):** 데이터 저장소의 관문 역할을 하며 메타데이터 조회, 프래그먼트(데이터 파일) 할당, 집계 조율을 담당합니다. 특히 '존 맵(Zone-map) 프루닝'을 통해 불필요한 데이터를 걸러냄으로써 다운스트림 작업량을 평균 30~60% 절감합니다. * **메타데이터 서비스(Metadata Service):** FoundationDB의 프런트엔드로서 데이터 컴팩션 중에도 쿼리 결과의 원자성(Atomicity)을 보장합니다. DB 내부 로직을 추상화하여 전체 쿼리 경로와 분리하는 역할을 합니다. * **리더 서비스(Reader Service):** 실제 오브젝트 스토리지에 저장된 프래그먼트에서 데이터를 읽어 응답을 반환하는 핵심 실행 엔진입니다. ### 리더(Reader) 서비스의 데이터 스캔 최적화 오브젝트 스토리지는 비용이 저렴하지만 읽기 속도가 느리므로, 리더 서비스는 "읽지 않아도 되는 데이터를 스캔하지 않는 것"을 최우선 목표로 삼습니다. * **행 그룹(Row Groups) 구조:** 수백만 행을 가진 대용량 프래그먼트를 '행 그룹' 단위로 물리적으로 배치하여 관리합니다. 이는 쿼리 실행 시 전체 파일을 메모리에 올리는 부담을 줄이고 메모리 부족(OOM) 오류를 방지합니다. * **입출력(I/O) 최소화:** 오브젝트 스토리지에 대한 GET 요청은 비용이 많이 들기 때문에, 쿼리에 꼭 필요한 행 그룹만 선택적으로 가져와 비용 효율성과 응답 속도를 극대화합니다. * **반복자 기반 실행 모델:** Volcano 모델에서 영감을 받은 반복자(Iterator) 방식을 사용하여 데이터를 효율적으로 스트리밍하며 처리합니다. Husky의 사례는 대규모 시계열 이벤트를 처리할 때 고정된 인덱스에 의존하기보다, 메타데이터 기반의 프루닝과 물리적인 데이터 레이아웃 최적화를 통해 오브젝트 스토리지의 한계를 극복할 수 있음을 보여줍니다. 저비용 고성능의 로그 분석 시스템을 설계한다면 데이터의 물리적 구조화와 단계별 쿼리 분산 처리가 핵심이 될 것입니다.