본문으로 건너뛰기
clickhouse검색
핵심 구조

압축과 코덱 (LZ4, ZSTD, Delta, DoubleDelta, Gorilla, T64)

ClickHouse가 열 데이터를 어떻게 압축하는지, 범용 코덱(LZ4, ZSTD)과 특화 코덱(Delta, DoubleDelta, Gorilla, T64, FPC)을 열 특성에 따라 어떻게 조합하는지, 압축률을 측정하고 바꾸는 방법을 정리합니다.

압축코덱ZSTDLZ4DeltaGorilla2026-10 기준, 약 8분

압축이 곧 속도

ClickHouse에서 압축은 디스크 절약만이 아니라 읽기 속도입니다. 디스크와 네트워크에서 읽는 바이트가 줄고, 캐시에 더 많이 담기기 때문입니다. 분석 쿼리는 대부분 I/O 또는 메모리 대역폭에 묶이므로, 압축률 2배는 체감상 스캔 2배 빨라짐에 가깝습니다. 반면 CPU가 병목인 쿼리에서는 ZSTD 높은 레벨이 오히려 느려집니다. 데이터 특성과 쿼리 패턴을 보고 고릅니다.

압축은 그래뉼 단위 블록으로 일어납니다. 열 파일 <열>.bin은 압축 블록(기본 최대 1MB 압축 전)의 연속이고, 마크 파일이 블록 위치를 가리킵니다. 정렬 키 순서로 비슷한 값이 몰릴수록 같은 블록 안에서 반복이 늘어 압축률이 오릅니다. 그래서 정렬 키 뒤쪽 열은 인덱스보다 압축에 기여합니다(정렬 키, 기본 키, 파티션).

범용 코덱

코덱특징쓰는 때
LZ4빠른 압축과 해제. 기본값 (셀프 호스팅)CPU가 아쉬운 서버, 자주 읽는 핫 데이터
ZSTD(level)압축률 높음. 레벨 1~22, 기본 1대부분의 경우 ZSTD(1)이 균형. Cloud 기본값
LZ4HC(level)LZ4보다 압축률 높고 느림거의 ZSTD로 대체
NONE압축 없음이미 압축된 바이너리, 난수
  • ZSTD는 레벨 3 이상에서 압축률 이득이 완만해지고 쓰기 CPU가 급격히 늘어납니다. 머지가 자주 다시 압축하므로 ZSTD(1)에서 ZSTD(3) 사이가 현실적입니다.
  • 서버 기본 코덱은 config.xml의 <compression>에서 바꿀 수 있고, 테이블 열 단위 CODEC이 우선합니다.
<compression>
    <case>
        <min_part_size>10000000000</min_part_size>
        <min_part_size_ratio>0.01</min_part_size_ratio>
        <method>zstd</method>
        <level>1</level>
    </case>
</compression>

특화 코덱

특화 코덱은 데이터를 변환만 하고 실제 압축은 뒤에 붙는 범용 코덱이 합니다. 그래서 CODEC(Delta, ZSTD)처럼 체인으로 씁니다.

코덱동작맞는 열
Delta(N)이전 값과의 차이를 저장단조 증가 정수, 타임스탬프, 시퀀스 번호
DoubleDelta차이의 차이를 저장일정 간격 타임스탬프, 카운터
Gorilla이전 값과 XOR천천히 변하는 Float 게이지(온도, CPU 사용률)
FPCFloat 예측 기반Float64 시계열, Gorilla와 비교해 선택
T64블록 안 값들의 공통 상위 비트를 잘라냄범위가 좁은 정수(상태 코드, 작은 카운트)
GCD최대공약수로 나눔10, 1000 단위처럼 공약수가 있는 정수
ZSTD_QAT, DEFLATE_QAT하드웨어 가속특정 Intel 서버
CREATE TABLE metrics
(
    ts        DateTime CODEC(DoubleDelta, ZSTD(1)),
    series_id UInt32   CODEC(T64, ZSTD(1)),
    value     Float64  CODEC(Gorilla, ZSTD(1)),
    seq       UInt64   CODEC(Delta, ZSTD(1)),
    payload   String   CODEC(ZSTD(3))
)
ENGINE = MergeTree ORDER BY (series_id, ts);

팁 타임스탬프 열은 DoubleDelta가 거의 항상 이득이고, 정렬 키의 첫 열처럼 같은 값이 길게 반복되는 열은 범용 코덱만으로 충분합니다. Float 게이지는 Gorilla, 랜덤에 가까운 Float(금액, 좌표)는 그냥 ZSTD가 낫습니다.

측정하고 결정하기

감으로 고르지 말고 같은 데이터로 코덱만 바꿔 비교합니다. system.parts_columns에 열별 압축 전후 크기가 있습니다.

-- 열별 압축률
SELECT column, type, compression_codec,
       formatReadableSize(sum(column_data_compressed_bytes)) AS compressed,
       round(sum(column_data_uncompressed_bytes) / sum(column_data_compressed_bytes), 1) AS ratio
FROM system.parts_columns
WHERE active AND table = 'metrics'
GROUP BY column, type, compression_codec
ORDER BY sum(column_data_compressed_bytes) DESC;

비교 실험 절차입니다.

  1. 테이블을 CREATE TABLE t_zstd AS t ENGINE = MergeTree ORDER BY ...로 몇 벌 만들고 열 코덱만 다르게 선언합니다.
  2. 같은 파티션 한 달치를 INSERT ... SELECT로 넣습니다.
  3. OPTIMIZE TABLE ... FINAL로 머지를 끝낸 뒤 압축 크기를 비교합니다. 머지 전 작은 파트는 압축률이 낮게 나옵니다.
  4. 대표 쿼리 5개의 실행 시간과 system.query_log의 read_bytes를 비교합니다.
-- 코덱 변경. 뮤테이션이므로 큰 테이블은 파티션별로 또는 머지에 맡김
ALTER TABLE metrics MODIFY COLUMN value Float64 CODEC(Gorilla, ZSTD(1));
-- 기존 파트까지 바로 다시 압축하려면
ALTER TABLE metrics MATERIALIZE COLUMN value;  -- 또는 OPTIMIZE ... FINAL

코덱 변경 ALTER는 메타데이터만 바꾸고, 기존 파트는 다음 머지 때 새 코덱으로 다시 압축됩니다. 급하지 않으면 머지에 맡기는 것이 서버에 부담이 적습니다.

예상 압축률 감

데이터전형적 압축률 (압축 전 / 후)
웹 로그, 애플리케이션 로그 (정렬 키 잘 잡힘)10배에서 30배
시계열 메트릭 (DoubleDelta, Gorilla)20배에서 100배
트랜잭션 테이블 (금액, ID 많음)3배에서 8배
텍스트 본문, 자유 입력3배에서 6배
UUID, 해시, 난수1배에서 1.5배 (압축 안 됨)

압축이 안 되는 열은 설계로 줄입니다. UUID 문자열은 UUID 타입으로(36바이트에서 16바이트), 해시는 UInt64로, 같은 값이 반복되는 문자열은 LowCardinality로 바꾸면 코덱보다 효과가 큽니다. 타입 선택은 데이터 타입 고르기.

네트워크와 클라이언트 압축

  • 서버와 클라이언트 사이 Native 프로토콜은 기본으로 LZ4 압축을 씁니다(network_compression_method). ZSTD로 바꾸면 WAN 구간에서 전송량이 줄지만 CPU를 더 씁니다.
  • HTTP 인터페이스는 enable_http_compression = 1과 요청 헤더 Accept-Encoding: zstd(또는 gzip, br, lz4)로 응답을 압축합니다. 대용량 결과를 받는 ETL이라면 켜 두세요.
  • INSERT 요청 본문도 Content-Encoding으로 압축해 보낼 수 있습니다. 클라이언트와 드라이버 참고.

오브젝트 스토리지와 압축

S3 기반 디스크나 ClickHouse Cloud에서는 저장 비용이 압축 후 바이트로 매겨지고, 읽기는 요청 수와 바이트에 비례합니다. 압축률이 높을수록 스토리지 비용과 읽기 지연이 함께 줄어 효과가 두 배입니다. 반대로 압축이 안 되는 열(난수 UUID)은 Cloud 요금에 그대로 반영되므로 타입 정리가 비용 절감의 첫 단계입니다. 비용 구조와 절감에서 이어집니다.

체크리스트

  1. 서버 또는 테이블 기본 코덱이 ZSTD(1)인지 확인했다 (셀프 호스팅 기본은 LZ4).
  2. 타임스탬프와 단조 증가 열은 Delta 또는 DoubleDelta를 앞에 붙였다.
  3. Float 게이지는 Gorilla 또는 FPC를 실측으로 골랐다.
  4. 압축률 2배 이하인 열은 타입(UUID, UInt, LowCardinality)으로 먼저 줄였다.
  5. 코덱 변경 후 머지가 끝난 뒤 system.parts_columns로 다시 측정했다.

공식 문서

이 문서에서