본문으로 건너뛰기

© 2026 Molayo

Dev.to중요헤드라인2026. 04. 24. 04:14

LLM 요청 로그를 위한 고성능 데이터베이스: PostgreSQL에서 ClickHouse로의 전환

요약

대규모 언어 모델(LLM) 요청 로그는 높은 쓰기 처리량과 분석 중심의 특성을 가집니다. 원문은 5만 건/일에서 2백만 건/일까지 증가한 LLM 로그를 PostgreSQL에서 ClickHouse로 마이그레이션한 경험을 공유합니다. 핵심은 LLM 로그가 '추가 전용(append-only)', '고 카디널리티', '분석 중심' 워크로드라는 점입니다. ClickHouse의 컬럼 기반 저장소, Materialized View (MV)를 활용한 사전 집계, 그리고 비동기 쓰기 경로(Async Write Path) 설계를 통해 비용 대시보드

핵심 포인트

  • LLM 로그는 '추가 전용(append-only)', '고 카디널리티', '분석 중심' 워크로드에 적합하며, PostgreSQL보다 ClickHouse와 같은 컬럼 기반 데이터베이스가 유리합니다.
  • ClickHouse의 Materialized View (MV)를 사용하여 비용 데이터를 삽입 시점에 사전 집계함으로써, 1천만 건의 원본 로그 대신 요약 테이블을 조회하여 p95 지연 시간을 3.2초에서 12ms로 대폭 개선했습니다.
  • Go 언어 기반의 비동기 쓰기 경로(Async Write Path)를 구현하여 로깅 오버헤드를 요청 처리 과정에서 2ms p95 이하로 유지함으로써, 사용자 경험을 저해하지 않으면서도 안정적인 로그 수집이 가능합니다.
  • 데이터베이스 선택 기준은 월별 요청 건수입니다. 50만 건 미만일 경우 PostgreSQL이 적합하며, 분석 쿼리가 지연되기 시작할 때(1백만 건 이상) ClickHouse로 전환하는 것이 최적의 시점입니다.

대규모 언어 모델(LLM) 서비스에서 발생하는 요청 로그를 효율적으로 처리하고 분석하는 것은 매우 중요합니다. 본 글은 LLM 요청 로그가 5만 건/일 수준에서 급증하여 2백만 건에 이르자, 기존의 PostgreSQL 환경이 성능 병목 지점(bottleneck)이 된 경험과 그 해결책을 제시합니다.

왜 PostgreSQL로는 한계가 오는가?

LLM 로그는 본질적으로 '추가 전용(append-only)', '고 카디널리티', 그리고 '분석 중심'의 특성을 가집니다. 초기에는 간단한 스키마로도 충분했지만, 쿼리 패턴이 복잡해지고 데이터 볼륨이 커지면서 문제가 발생했습니다.

기존 PostgreSQL 스키마는 UUID 기본 키와 (tenant_id, created_at) 인덱스를 사용했으나, 다음과 같은 집계 쿼리를 실행할 때 성능 저하가 심각했습니다:

SELECT model , SUM ( cost_usd ), COUNT ( * ) FROM llm_requests WHERE tenant_id = $ 1 AND created_at > NOW () - INTERVAL '30 days' GROUP BY model ; 

이러한 GROUP BY 쿼리는 데이터 볼륨이 커질수록 수십만 행을 스캔해야 했고, PostgreSQL은 행 기반(row-oriented) 저장 방식을 사용하기 때문에, 단 하나의 컬럼(cost_usd)의 합계를 구하더라도 전체 행을 읽어와야 하는 I/O 오버헤드가 발생했습니다. 이는 대규모 분석 작업에 치명적이었습니다.

ClickHouse로 전환한 이유: 3가지 핵심 특성

LLM 요청 로그가 ClickHouse에 적합한 근거는 세 가지 데이터베이스의 본질적인 차이점 때문입니다.

  1. 컬럼 기반 저장소 (Columnar Storage): PostgreSQL은 행 전체를 읽지만, ClickHouse는 쿼리에서 필요한 컬럼(cost_usd, model)만 디스크에서 읽어옵니다. 예를 들어 20개 컬럼 중 2개 컬럼을 집계할 경우, ClickHouse는 I/O를 약 10% 수준으로 줄일 수 있습니다.
  2. 추가 전용 쓰기 최적화 (Append-only Writes): LLM 로그는 업데이트나 삭제가 거의 발생하지 않습니다. ClickHouse는 높은 처리량의 삽입(insert)에 최적화되어 있으며, PostgreSQL이 쓰기 작업마다 발생하는 MVCC (Multi-Version Concurrency Control) 오버헤드를 겪지 않아 성능 이점을 얻습니다.
  3. Materialized View (MV)를 통한 사전 집계: 가장 큰 개선점 중 하나입니다. ClickHouse는 데이터를 삽입하는 시점에 Materialized View가 작동하여, 원본 로그(llm_requests)에 새로운 행이 들어올 때마다 요약 테이블(cost_by_model_daily)의 누적 합계를 업데이트합니다. 따라서 대시보드 쿼리는 수천만 건의 원본 데이터를 읽는 대신, 이미 계산된 소수의 요약 데이터만 조회하게 됩니다.

성능 개선 및 아키텍처 설계

이러한 설계를 통해 얻은 결과는 극적입니다. 1천만 건의 로그를 조회하는 경우:

  • PostgreSQL p95: 3.2초
  • ClickHouse raw: 180ms
  • ClickHouse mat. view: 12ms

또한, 요청 처리 과정에서 로깅이 메인 스레드를 막는 것을 방지하기 위해 Go 언어의 비동기 쓰기 경로(Async Write Path)를 설계했습니다. 요청 핸들러에서는 로그 엔트리를 버퍼링된 채널(logCh)에 넣고, 백그라운드 고루틴(goroutine)이 500ms 간격으로 배치 처리하여 ClickHouse에 플러시합니다. 이 방식을 통해 로깅 오버헤드를 2ms p95 이하로 유지할 수 있었습니다.

결론: 언제 마이그레이션해야 하는가?

데이터베이스 선택은 트래픽 규모와 쿼리 패턴에 따라 달라져야 합니다.

  • PostgreSQL: 월별 요청 건수가 50만 건 미만이고, ACID 트랜잭션이나 복합 읽기/쓰기가 필요한 경우 적합합니다.
  • ClickHouse: 로그가 '추가 전용'이며, 월 1백만 건 이상의 대규모 분석 쿼리가 주를 이루는 경우 필수적입니다.

핵심은 분석 쿼리가 지연되기 시작할 때(analytics queries start timing out) 마이그레이션하는 것이며, 단순히 트래픽 증가만을 기준으로 삼아서 과도하게 아키텍처를 설계할 필요는 없습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
7

댓글

0