[Clickhouse] S3로 계층화하기
DB에 로그 같은 데이터를 쌓을때 생기는 가장 큰 문제는 항상 디스크의 팽창이다.
로그는 무한으로 쌓이는데, 디스크 공간은 무한하지 않기 때문이다. 그렇다고 서비스 데이터처럼 귀중한 것도 아니다.
그래서 보통 N일이 지나면 만료 기반으로 백업을 하거나 삭제를 하는 식으로 정책을 많이들 정하는데, Clickhouse는 여기에서 꽤 강점을 갖고 있다.
S3 같은 오브젝트 스토리지를 볼륨으로 쉽게 붙일 수 있고, 만료 기반으로 볼륨 간 이동을 잘 지원하기 때문이다. 그리고 백업된 데이터에 대해서도 동일한 SQL로 쿼리를 날릴 수 있다.
게다가 기본 저장형식이 충분히 효율적이기 때문에 parquet 같은 압축 과정을 굳이 거치지 않아도 된다.
여기서는 기본적인 구성, 사용 방법을 정리해본다.
버킷 준비
버킷에 백업을 하려면, 당연히 버킷이 있어야 한다.
버킷을 만들고, 버킷에 접근할 수 있는 IAM 계정, 액세스키를 뽑는다.
Clickhouse에 S3 디스크 추가
Clickhouse에서 모든 저장공간은 디스크라는 단위를 통해 추상화된다.
config.d에 storage_s3.xml이란 파일을 만들고, 다음과 같이 설정을 채워주자.
<clickhouse>
<storage_configuration>
<disks>
<s3_cold>
<type>object_storage</type>
<object_storage_type>s3</object_storage_type>
<metadata_type>local</metadata_type>
<endpoint>https://YOUR_BUCKET.s3.ap-northeast-2.amazonaws.com/clickhouse/cold/</endpoint>
<access_key_id>YOUR_ACCESS_KEY_ID</access_key_id>
<secret_access_key>YOUR_SECRET_ACCESS_KEY</secret_access_key>
</s3_cold>
</disks>
<policies>
<hot_cold>
<volumes>
<default>
<disk>default</disk>
</default>
<cold>
<disk>s3_cold</disk>
</cold>
</volumes>
</hot_cold>
</policies>
</storage_configuration>
</clickhouse>
그리고 clickhouse를 재부팅한다. 이건 다운타임이 필수적이다.
그러고 나서 다음과 같이 쿼리를 날렸을 때
SELECT
name,
type,
path
FROM system.disks;
S3가 잘 뜨면 성공이다.
S3 연동 확인
S3에 파일이 자동으로 잘 올라가는지 확인해보자.
다음 쿼리는 테이블을 만들고, 30일이 지난 타임스탬프의 값을 전부 S3로 올리는 구성이다.
CREATE TABLE s3_ttl_test
(
timestamp DateTime,
id UInt64,
message String
)
ENGINE = MergeTree
PARTITION BY toYYYYMMDD(timestamp)
ORDER BY (timestamp, id)
TTL timestamp + INTERVAL 30 DAY TO VOLUME 'cold'
SETTINGS storage_policy = 'hot_cold';
INSERT INTO s3_ttl_test VALUES
(now(), 1, 'local data'),
(now() - INTERVAL 31 DAY, 2, 's3 data');
# 강제 TTL 트리거
ALTER TABLE s3_ttl_test MATERIALIZE TTL;
이렇게 했을때
S3에 파일이 잘 올라왔다면, 연동까지 잘 끝난 것이다.
S3 백업 정책 설정하기
2단계로 진행해야 한다.
먼저 cold disk를 정책으로 가지는 내 커스텀 정책으로 테이블을 생성하거나, 기존 테이블 정책을 수정해야 한다.
만약 기존 테이블이 default 정책을 가지고 있었다면, 재생성 없이 교체가 가능하다.

그리고 나서는, TTL용 시간 컬럼을 하나 고른 뒤에 다음과 같이 cold move 설정을 추가하면 된다.
ALTER TABLE otel_logs
MODIFY TTL
Timestamp + INTERVAL 30 DAY TO VOLUME 'cold';

그럼 자동으로 TTL이 지날때마다 S3 백업이 자동으로 될 것이다.
다만 백업본에 대해 쿼리를 할 때는 S3 비용이 사용량만큼 청구될 수 있으니, 염두에 두길 바란다.
그리고 비용에 민감한 상황이라면, S3 저장본에 대해서도 만료를 하고 싶을 수도 있다.
30일이 지나면 S3에 백업하고, 90일이 지나면 S3에서도 삭제하는 식으로 말이다.

이런 경우도 어렵지 않다. 계층형으로 TTL을 거는 것이 가능하기 때문에, 그냥 이렇게 옵션을 주면 된다.
ALTER TABLE otel_logs
MODIFY TTL
Timestamp + INTERVAL 30 DAY TO VOLUME 'cold',
Timestamp + INTERVAL 90 DAY DELETE;참조
https://clickhouse.com/docs/ko/concepts/features/operations/delete/ttl
https://clickhouse.com/docs/ko/clickstack/managing/ttl