Ken
ClickHouse Self-Managed(OSS)에서 ClickHouse Cloud로 마이그레이션을 진행할 때, 단순히 전체 데이터를 옮기는 것 이상의 요구사항이 있는 경우가 많습니다. 특정 테이블만 이관하거나, 이관 과정에서 스키마를 변경하거나, 데이터를 정제해야 하는 상황에서는 BACKUP/RESTORE 보다 유연한 방법이 필요합니다. 이 글에서는 remoteSecure() 테이블 함수와 S3를 경유하는 두 가지 방식을 심층적으로 다룹니다.
- 왜 BACKUP/RESTORE 대신 다른 방법을 선택하는가
- 선택적 데이터 이관
- 데이터 변환이 필요한 경우
- 그럼에도 BACKUP/RESTORE가 나은 경우
- remoteSecure() 이해하기
- 기본 개념
- 실전 사용법
- 잠재적 문제들
- 문제 대응 방안
- 1. 타임아웃 파라미터 조정
- 2. 파티션 기반 분할 처리
- 3. 상태 관리를 통한 안정적 이관 (샘플 코드)
- S3 경유 방식 이해하기
- 개념 및 강점
- 실전 사용법
- 1단계: OSS에서 S3로 내보내기
- 2단계: Cloud에서 S3로부터 읽어오기
- 포맷 선택 가이드
- 잠재적 문제들
- 문제 대응 방안
- 적절한 파일 크기 유지
- 병렬 처리로 속도 향상
- 검증 쿼리
- 방식 비교 및 선택 가이드
- 마이그레이션 방식 선택 Decision Tree
- 추천 시나리오 요약
- 마치며
- 참고 자료
왜 BACKUP/RESTORE 대신 다른 방법을 선택하는가
ClickHouse의 BACKUP/RESTORE 기능은 전체 데이터베이스나 테이블을 그대로 복제하는 데 최적화되어 있습니다. 그러나 실제 마이그레이션 프로젝트에서는 이보다 복잡한 요구사항이 발생합니다.
선택적 데이터 이관
운영 환경에서는 모든 데이터를 이관할 필요가 없는 경우가 많습니다. 최근 1년치 데이터만 필요하거나, 특정 조건을 만족하는 레코드만 이관해야 할 수 있습니다. BACKUP/RESTORE는 테이블 단위의 전체 복사만 지원하므로, 이러한 세밀한 제어가 불가능합니다.
-- remoteSecure를 사용한 선택적 이관 예시
INSERT INTO cloud_orders
SELECT * FROM remoteSecure(
'oss-cluster.example.com:9440',
'production', 'orders',
'migration_user', 'password'
)
WHERE order_date >= '2024-01-01'
AND status != 'cancelled';
데이터 변환이 필요한 경우
마이그레이션은 종종 스키마 개선의 기회이기도 합니다. 컬럼 타입 변경, 새로운 컬럼 추가, 데이터 정규화, 파티셔닝 전략 변경 등이 필요할 때 SELECT ... INSERT 패턴이 훨씬 유연합니다.
그럼에도 BACKUP/RESTORE가 나은 경우
물론 BACKUP/RESTORE가 더 적합한 시나리오도 있습니다. 데이터 변경 없이 동일한 스키마로 전체 복제가 필요하고, 데이터 무결성 검증이 중요하며, 인덱스와 파티션 구조를 그대로 유지해야 할 때입니다. 특히 ClickHouse Cloud 간 마이그레이션에서는 BACKUP/RESTORE가 가장 빠르고 안전한 선택입니다.
remoteSecure() 이해하기
기본 개념
remoteSecure()는 TLS/SSL로 암호화된 연결을 통해 원격 ClickHouse 서버의 데이터에 접근하는 테이블 함수입니다. remote() 함수와 동일한 기능을 제공하지만, 보안 연결을 사용한다는 점이 다릅니다.
remoteSecure('host:port', 'database', 'table', 'user', 'password')
내부적으로는 원격 서버에 쿼리를 전송하고, 결과를 스트리밍 방식으로 수신합니다. 이 과정에서 로컬 테이블처럼 조회하거나 INSERT INTO ... SELECT FROM remoteSecure(...) 패턴으로 데이터를 복사할 수 있습니다.
실전 사용법
가장 기본적인 형태는 직접 연결 정보를 명시하는 것입니다.
Cloud에서 OSS로 접근할 때는 네트워크 구성을 확인해야 합니다. OSS 서버가 Public IP를 가지고 있거나, PrivateLink로 연결되어 있어야 합니다.
잠재적 문제들
remoteSecure()는 편리하지만 대용량 데이터 이관 시 몇 가지 문제에 직면할 수 있습니다.
연결 타임아웃: 기본 receive_timeout이 300초(5분)로 설정되어 있어, 대용량 쿼리에서 타임아웃이 발생할 수 있습니다.
네트워크 불안정: 장시간 연결이 유지되어야 하므로, 중간에 네트워크가 끊기면 전체 작업이 실패합니다. 자동 재시도 메커니즘이 없습니다.
메모리 압박: 큰 결과셋을 처리할 때 양쪽 서버 모두에서 메모리 사용량이 증가합니다.
-- 현재 타임아웃 설정 확인
SELECT name, value, description
FROM system.settings
WHERE name IN ('connect_timeout', 'receive_timeout', 'send_timeout', 'max_execution_time');
name | value | 설명 |
connect_timeout | 10 | 연결 수립 타임아웃 (초) |
receive_timeout | 300 | 데이터 수신 타임아웃 (초) |
send_timeout | 300 | 데이터 송신 타임아웃 (초) |
max_execution_time | 0 | 쿼리 실행 제한 (0=무제한) |
문제 대응 방안
1. 타임아웃 파라미터 조정
시간적 여유가 있다면 타임아웃을 늘려 안정성을 확보할 수 있습니다.
SET receive_timeout = 86400; -- 24시간
SET send_timeout = 86400;
SET max_execution_time = 0; -- 무제한
SET connect_timeout_with_failover_ms = 50000;
INSERT INTO cloud_table
SELECT * FROM remoteSecure('host:9440', 'db', 'table', 'user', 'pwd');
2. 파티션 기반 분할 처리
대용량 테이블은 파티션이나 날짜 기준으로 나누어 처리하는 것이 안전합니다.
실제 nyc_taxi 테이블의 경우 월별 데이터 분포는 다음과 같습니다:
월 | 행 수 | 예상 크기 |
201507 | 3,858,582 | ~45 MiB |
201508 | 11,130,304 | ~132 MiB |
201509 | 5,011,114 | ~60 MiB |
3. 상태 관리를 통한 안정적 이관 (샘플 코드)
S3 경유 방식 이해하기
개념 및 강점
S3를 중간 저장소로 활용하는 방식은 OSS에서 S3로 데이터를 내보내고, Cloud에서 S3로부터 데이터를 읽어오는 2단계 프로세스입니다.
이 방식의 핵심 강점은 단계 분리입니다. 각 단계가 독립적이므로 네트워크 문제가 발생해도 이미 S3에 저장된 데이터는 안전합니다. 또한 Parquet, ORC 같은 컬럼형 포맷으로 저장하면 압축 효율과 후속 처리 성능이 향상됩니다.
ClickHouse Cloud에서 지원하는 S3 관련 테이블 함수들:
함수 | 용도 |
s3() | 기본 S3 읽기/쓰기 |
s3Cluster() | 클러스터 전체에서 병렬 S3 처리 |
deltaLakeS3() | Delta Lake 형식 읽기 |
icebergS3() | Apache Iceberg 형식 읽기 |
실전 사용법
1단계: OSS에서 S3로 내보내기
2단계: Cloud에서 S3로부터 읽어오기
포맷 선택 가이드
포맷 | 압축률 | 읽기 성능 | 스키마 보존 | 권장 상황 |
Parquet | 높음 | 매우 빠름 | 완벽 | 대부분의 경우 권장 |
ORC | 높음 | 빠름 | 완벽 | Hive 에코시스템 연동 시 |
Native | 중간 | 가장 빠름 | 완벽 | ClickHouse 간 이동 |
JSONEachRow | 낮음 | 느림 | 유연함 | 디버깅, 외부 시스템 연동 |
CSV | 매우 낮음 | 느림 | 제한적 | 레거시 호환 필요 시 |
잠재적 문제들
S3 권한 설정: IAM Role이나 Access Key 설정이 올바르지 않으면 접근이 실패합니다.
대용량 단일 파일: 너무 큰 파일은 메모리 문제를 일으킬 수 있습니다. 적절한 크기로 분할하는 것이 좋습니다.
스키마 불일치: S3 파일의 스키마와 대상 테이블 스키마가 다르면 오류가 발생합니다.
비용: S3 PUT/GET 요청과 데이터 전송에 비용이 발생합니다. 특히 리전 간 전송은 비용이 높습니다.
문제 대응 방안
적절한 파일 크기 유지
-- 파티션 + 청크 번호로 파일 분할
INSERT INTO FUNCTION s3(
's3://bucket/migration/table/partition={partition}/chunk_{_partition_id}.parquet',
'Parquet'
)
SELECT * FROM large_table
SETTINGS max_insert_block_size = 1000000; -- 블록 크기 조정
병렬 처리로 속도 향상
-- s3Cluster를 사용한 병렬 읽기
INSERT INTO target_table
SELECT * FROM s3Cluster(
'default', -- 클러스터 이름
'https://s3.../migration/*.parquet',
extra_credentials(role_arn = '...')
);
검증 쿼리
-- 이관 전후 데이터 건수 비교
SELECT
(SELECT count() FROM s3('s3://bucket/migration/*.parquet')) as s3_count,
(SELECT count() FROM target_table) as table_count,
s3_count = table_count as is_match;
방식 비교 및 선택 가이드
항목 | remoteSecure | S3 경유 |
설정 복잡도 | 낮음 (직접 연결) | 중간 (S3 + IAM 설정) |
네트워크 요구사항 | OSS 서버 접근 필요 | S3만 접근 가능하면 됨 |
실패 복구 | 어려움 (전체 재시작) | 용이 (파일 단위 재처리) |
중간 데이터 보관 | 없음 | S3에 보관 가능 |
추가 비용 | 없음 | S3 스토리지/전송 비용 |
대용량 안정성 | 중간 | 높음 |
데이터 변환 | 쿼리에서 처리 | 내보내기/읽기 양쪽에서 처리 가능 |
마이그레이션 방식 선택 Decision Tree
추천 시나리오 요약
remoteSecure 권장: 소중규모 데이터(수십 GB 이하), 일회성 이관, OSS 서버에 직접 접근 가능한 경우, 빠른 테스트나 검증이 필요할 때
S3 경유 권장: 대용량 데이터(수백 GB 이상), 네트워크가 불안정하거나 OSS 직접 접근이 어려운 경우, 이관 데이터를 백업 용도로 보관하고 싶을 때, 여러 번 반복 이관이 예상될 때
마치며
ClickHouse OSS에서 Cloud로의 마이그레이션은 단순한 데이터 복사가 아닌, 비즈니스 요구사항에 맞는 전략적 선택이 필요합니다. remoteSecure()는 간편함과 유연성을, S3 경유 방식은 안정성과 확장성을 제공합니다. 데이터 규모, 네트워크 환경, 변환 요구사항을 고려하여 적절한 방식을 선택하시기 바랍니다.
현재 저는 이 두 가지 방식을 통합하여 상태 관리, 자동 재시도, 검증까지 포함한 마이그레이션 도구를 개인적으로 개발하고 있습니다. 완성되면 별도로 공유드리겠습니다.
참고 자료
- remoteSecure 테이블 함수 공식 문서
- S3 테이블 함수 공식 문서
- Self-Managed에서 ClickHouse Cloud로 마이그레이션 가이드
- ClickHouse Backup and Restore 공식 문서
- remoteSecure 타임아웃 문제 해결 가이드
- Altinity Knowledge Base - Remote Table Function