Skip to main content
ClickHouse Cloud에서는 복제가 자동으로 관리됩니다. 테이블을 생성할 때 인수를 추가하지 마십시오. 예를 들어 아래 내용에서는 다음을:
다음으로 바꾸면 됩니다:
복제는 MergeTree 엔진 계열의 테이블에서만 지원됩니다
  • ReplicatedSummingMergeTree
  • ReplicatedCoalescingMergeTree
  • ReplicatedVersionedCollapsingMergeTree
  • ReplicatedCollapsingMergeTree
  • ReplicatedGraphiteMergeTree
  • ReplicatedMergeTree
  • ReplicatedReplacingMergeTree
  • ReplicatedAggregatingMergeTree
복제는 전체 서버가 아니라 개별 테이블 수준에서 작동합니다. 하나의 서버에는 복제된 테이블과 복제되지 않는 테이블이 동시에 저장될 수 있습니다. 복제는 세그먼트 분할에 의존하지 않습니다. 각 세그먼트는 자체적으로 독립적인 복제를 가집니다. INSERTALTER 쿼리의 압축된 데이터가 복제됩니다(자세한 내용은 ALTER 문서를 참조하십시오). CREATE, DROP, ATTACH, DETACHRENAME 쿼리는 단일 서버에서 실행되며 복제되지 않습니다:
  • CREATE TABLE 쿼리는 쿼리가 실행된 서버에 새로운 복제 가능 테이블을 생성합니다. 이 테이블이 다른 서버에 이미 존재하는 경우 새 레플리카를 추가합니다.
  • DROP TABLE 쿼리는 쿼리가 실행된 서버에 있는 레플리카를 삭제합니다.
  • RENAME 쿼리는 레플리카 중 하나에서 테이블 이름을 변경합니다. 즉, 복제된 테이블은 레플리카마다 서로 다른 이름을 가질 수 있습니다.
ClickHouse는 레플리카 메타데이터를 저장하기 위해 ClickHouse Keeper를 사용합니다. ZooKeeper 3.4.5 이상을 사용할 수도 있지만, ClickHouse Keeper 사용을 권장합니다. 복제를 사용하려면 zookeeper 서버 구성 섹션에서 매개변수를 설정하십시오.
보안 설정을 소홀히 하지 마십시오. ClickHouse는 ZooKeeper 보안 하위 시스템의 digest ACL scheme을 지원합니다.
ClickHouse Keeper 클러스터 주소를 설정하는 예시:
ClickHouse는 레플리카 메타데이터를 보조 ZooKeeper 클러스터에 저장하는 기능도 지원합니다. 이를 위해 엔진 인수로 ZooKeeper 클러스터 이름과 경로를 지정하십시오. 즉, 서로 다른 테이블의 메타데이터를 서로 다른 ZooKeeper 클러스터에 저장할 수 있습니다. 보조 ZooKeeper 클러스터 주소를 설정하는 예시는 다음과 같습니다.
기본 ZooKeeper 클러스터 대신 보조 ZooKeeper 클러스터에 테이블 메타데이터를 저장하려면, 다음과 같이 SQL을 사용하여 ReplicatedMergeTree 엔진으로 테이블을 생성할 수 있습니다:
기존 ZooKeeper 클러스터를 지정할 수 있으며, 시스템은 자체 데이터를 저장할 디렉터리로 해당 클러스터의 디렉터리를 사용합니다(이 디렉터리는 복제 가능한 테이블을 생성할 때 지정합니다). 구성 파일에 ZooKeeper가 설정되어 있지 않으면 복제된 테이블(Replicated Table)을 생성할 수 없으며, 기존 복제된 테이블은 모두 읽기 전용이 됩니다. ZooKeeper는 복제가 SELECT 쿼리의 성능에 영향을 주지 않으므로 SELECT 쿼리에서는 사용되지 않으며, 쿼리는 비복제 테이블과 동일한 속도로 실행됩니다. 분산 복제 테이블에 쿼리할 때 ClickHouse의 동작은 max_replica_delay_for_distributed_queriesfallback_to_stale_replicas_for_distributed_queries 설정으로 제어됩니다. INSERT 쿼리마다 여러 트랜잭션을 통해 ZooKeeper에 약 10개의 엔트리가 추가됩니다. (더 정확히는, 삽입되는 각 데이터 블록마다 그렇습니다. INSERT 쿼리에는 하나의 블록 또는 max_insert_block_size = 1048576행마다 하나의 블록이 포함됩니다.) 이로 인해 INSERT의 지연 시간은 비복제 테이블보다 약간 더 길어집니다. 하지만 데이터를 초당 INSERT 1회를 넘지 않는 batch로 삽입하라는 권장 사항을 따르면 문제를 일으키지 않습니다. 하나의 ZooKeeper 클러스터로 조정되는 전체 ClickHouse 클러스터는 초당 총 수백 개의 INSERTs를 처리합니다. 데이터 삽입 처리량(초당 행 수)은 비복제 데이터와 동일하게 높습니다. 매우 큰 클러스터에서는 서로 다른 세그먼트에 서로 다른 ZooKeeper 클러스터를 사용할 수 있습니다. 그러나 약 300대의 서버로 구성된 production 클러스터를 운영한 경험상, 이것이 필요했던 경우는 없었습니다. 복제는 비동기식이며 멀티 마스터입니다. INSERT 쿼리(ALTER도 마찬가지)는 사용 가능한 어느 서버로든 보낼 수 있습니다. 데이터는 쿼리가 실행된 서버에 삽입된 다음, 다른 서버로 복사됩니다. 비동기식이므로 방금 삽입된 데이터는 약간의 지연 후 다른 레플리카에 반영됩니다. 일부 레플리카를 사용할 수 없는 경우에는, 해당 레플리카를 다시 사용할 수 있게 되면 데이터가 기록됩니다. 레플리카를 사용할 수 있다면, 지연 시간은 압축된 데이터 블록을 네트워크로 전송하는 데 걸리는 시간입니다. 복제된 테이블의 백그라운드 작업을 수행하는 스레드 수는 background_schedule_pool_size 설정으로 지정할 수 있습니다. ReplicatedMergeTree 엔진은 복제 fetches를 위해 별도의 스레드 풀을 사용합니다. 이 풀의 크기는 background_fetches_pool_size 설정으로 제한되며, 서버를 재시작하면 조정할 수 있습니다. 기본적으로 INSERT 쿼리는 하나의 레플리카에서 데이터 쓰기 확인만 기다립니다. 데이터가 하나의 레플리카에만 성공적으로 기록된 상태에서 그 레플리카가 있는 서버가 더 이상 존재하지 않게 되면, 저장된 데이터는 손실됩니다. 여러 레플리카로부터 데이터 쓰기 확인을 받으려면 insert_quorum 옵션을 사용하십시오. 각 데이터 블록은 원자적으로 기록됩니다. INSERT 쿼리는 최대 max_insert_block_size = 1048576행의 블록으로 나뉩니다. 즉, INSERT 쿼리에 1048576행보다 적은 행이 있으면 원자적으로 수행됩니다. 데이터 블록은 중복 제거됩니다. 동일한 데이터 블록(같은 크기이며 동일한 순서로 같은 행을 포함하는 데이터 블록)을 여러 번 기록하더라도 해당 블록은 한 번만 기록됩니다. 이는 네트워크 장애가 발생했을 때 클라이언트 애플리케이션이 데이터가 DB에 기록되었는지 알 수 없더라도 INSERT 쿼리를 그대로 다시 실행할 수 있도록 하기 위한 것입니다. 동일한 데이터를 가진 INSERTs가 어느 레플리카로 전송되었는지는 중요하지 않습니다. INSERTs는 멱등적입니다. 중복 제거 매개변수는 merge_tree 서버 설정으로 제어됩니다. 복제 중에는 삽입할 원본 데이터만 네트워크를 통해 전송됩니다. 이후의 데이터 변환(머지)은 모든 레플리카에서 동일한 방식으로 조정되고 수행됩니다. 따라서 네트워크 사용량이 최소화되며, 레플리카가 서로 다른 datacenter에 위치해 있어도 복제가 잘 작동합니다. (서로 다른 datacenter에 데이터를 중복 저장하는 것이 복제의 주된 목적이라는 점에 유의하십시오.) 동일한 데이터에 대해 원하는 수만큼 레플리카를 둘 수 있습니다. 경험상 비교적 안정적이고 운영하기 편한 방법은 production 환경에서 각 서버에 RAID-5 또는 RAID-6(경우에 따라 RAID-10)를 사용하고 이중 복제를 구성하는 것입니다. 시스템은 레플리카 간 데이터 동기 상태를 모니터링하며 장애 이후에도 복구할 수 있습니다. 장애 조치는 자동으로(데이터 차이가 작은 경우) 또는 반자동으로(데이터 차이가 너무 커서 구성 오류를 나타낼 수 있는 경우) 수행됩니다.

복제된 테이블 생성

ClickHouse Cloud에서는 복제가 자동으로 처리됩니다.복제 인수 없이 MergeTree를 사용해 테이블을 생성하십시오. 시스템은 복제 및 데이터 배포를 위해 내부적으로 MergeTreeSharedMergeTree로 재작성합니다.복제는 플랫폼에서 관리되므로 ReplicatedMergeTree를 사용하거나 복제 매개변수를 지정하지 마십시오.

Replicated*MergeTree 매개변수

예시:
예시에서 볼 수 있듯이, 이 매개변수에는 {} 형태의 치환을 포함할 수 있습니다. 치환된 값은 설정 파일의 macros 섹션에서 가져옵니다. 예시:
ClickHouse Keeper에서 테이블의 경로는 각 복제된 테이블(Replicated Table)마다 고유해야 합니다. 서로 다른 세그먼트의 테이블은 서로 다른 경로를 사용해야 합니다. 이 경우 경로는 다음 부분으로 구성됩니다. /clickhouse/tables/는 공통 접두사입니다. 정확히 이 값을 그대로 사용할 것을 권장합니다. {shard}는 세그먼트 식별자로 확장됩니다. table_name은 ClickHouse Keeper에서 해당 테이블의 노드 이름입니다. 이 값을 테이블 이름과 동일하게 지정하는 것이 좋습니다. 테이블 이름과 달리 RENAME 쿼리 후에도 변경되지 않으므로 명시적으로 정의합니다. 힌트: table_name 앞에 데이터베이스 이름을 추가할 수도 있습니다. 예: db_name.table_name 기본 제공 치환인 {database}{table}도 사용할 수 있으며, 각각 테이블 이름과 데이터베이스 이름으로 확장됩니다(macros 섹션에서 이러한 매크로가 정의된 경우는 제외). 따라서 ZooKeeper 경로는 '/clickhouse/tables/{shard}/{database}/{table}'로 지정할 수 있습니다. 이러한 기본 제공 치환을 사용할 때는 테이블 이름 변경에 주의하십시오. ClickHouse Keeper의 경로는 변경할 수 없으며, 테이블 이름이 변경되면 매크로가 다른 경로로 확장됩니다. 그러면 테이블이 ClickHouse Keeper에 존재하지 않는 경로를 참조하게 되어 읽기 전용 모드로 전환됩니다. 레플리카 이름은 동일한 테이블의 서로 다른 레플리카를 식별합니다. 예시와 같이 서버 이름을 사용할 수 있습니다. 이름은 각 세그먼트 내에서만 고유하면 됩니다. 치환을 사용하는 대신 매개변수를 명시적으로 정의할 수 있습니다. 이는 테스트하거나 작은 클러스터를 구성할 때 편리할 수 있습니다. 그러나 이 경우 분산 DDL 쿼리(ON CLUSTER)는 사용할 수 없습니다. 큰 클러스터에서 작업할 때는 오류 가능성을 줄일 수 있으므로 치환을 사용할 것을 권장합니다. Replicated 테이블 엔진의 기본 인수를 서버 구성 파일에 지정할 수 있습니다. 예를 들면 다음과 같습니다:
이 경우 테이블을 생성할 때 인수를 생략할 수 있습니다.
다음과 동일합니다:
각 레플리카에서 CREATE TABLE 쿼리를 실행하세요. 이 쿼리는 새 복제된 테이블(Replicated Table)을 생성하거나, 기존 테이블에 새 레플리카를 추가합니다. 다른 레플리카에 이미 일부 데이터가 있는 상태에서 새 레플리카를 추가하면, 쿼리 실행 후 다른 레플리카의 데이터가 새 레플리카로 복사됩니다. 즉, 새 레플리카가 다른 레플리카와 자동으로 동기화됩니다. 레플리카를 삭제하려면 DROP TABLE을 실행하세요. 다만 한 번에 삭제되는 것은 하나의 레플리카뿐이며, 쿼리를 실행한 서버에 있는 레플리카만 삭제됩니다.

장애 발생 후 복구

서버 시작 시 ClickHouse Keeper를 사용할 수 없으면 복제된 테이블은 읽기 전용 모드로 전환됩니다. 시스템은 주기적으로 ClickHouse Keeper 연결을 시도합니다. INSERT 중에 ClickHouse Keeper를 사용할 수 없거나 ClickHouse Keeper와 상호작용하는 중 오류가 발생하면 예외가 발생합니다. ClickHouse Keeper에 연결되면 시스템은 로컬 파일 시스템의 데이터 집합이 예상된 데이터 집합과 일치하는지 확인합니다(이 정보는 ClickHouse Keeper에 저장됨). 사소한 불일치가 있으면 시스템은 레플리카와 데이터를 동기화하여 이를 해결합니다. 시스템이 손상된 데이터 파트(파일 크기가 잘못된 경우) 또는 알 수 없는 파트(파일 시스템에 기록되었지만 ClickHouse Keeper에는 기록되지 않은 파트)를 감지하면, 해당 파트를 detached 하위 디렉터리로 이동합니다(삭제되지는 않음). 누락된 파트는 레플리카에서 복사합니다. ClickHouse는 대량의 데이터를 자동으로 삭제하는 등의 파괴적인 작업은 수행하지 않습니다. 서버가 시작될 때(또는 ClickHouse Keeper와 새 session을 설정할 때) 시스템은 모든 파일의 개수와 크기만 확인합니다. 파일 크기가 일치하더라도 중간 어딘가의 바이트가 변경된 경우에는 즉시 감지되지 않으며, SELECT 쿼리로 데이터를 읽으려고 할 때에만 감지됩니다. 이 경우 쿼리에서 checksum 또는 compressed block 크기가 일치하지 않는다는 예외가 발생합니다. 그러면 데이터 파트가 검증 큐에 추가되고, 필요하면 레플리카에서 복사됩니다. 로컬 데이터 집합이 예상된 집합과 너무 크게 다르면 안전 메커니즘이 작동합니다. 서버는 이를 로그에 기록하고 시작을 거부합니다. 이는 이 상황이 구성 오류를 나타낼 수 있기 때문입니다. 예를 들어, 한 세그먼트의 레플리카가 실수로 다른 세그먼트의 레플리카처럼 구성된 경우가 이에 해당합니다. 다만 이 메커니즘의 임계값은 비교적 낮게 설정되어 있으므로, 정상적인 장애 복구 중에도 이런 상황이 발생할 수 있습니다. 이런 경우 데이터는 “버튼을 누르는” 방식으로 반자동 복원됩니다. 복구를 시작하려면 ClickHouse Keeper에서 임의의 내용을 가진 노드 /path_to_table/replica_name/flags/force_restore_data를 생성하거나, 모든 복제된 테이블을 복원하는 명령을 실행하십시오:
그런 다음 server를 다시 시작하십시오. 시작되면 server가 이 플래그를 삭제하고 복구를 시작합니다.

전체 데이터 손실 후 복구

서버 중 하나에서 모든 데이터와 메타데이터가 사라진 경우에는 다음 단계에 따라 복구하십시오.
  1. 서버에 ClickHouse를 설치합니다. 치환을 사용하는 경우, 세그먼트 식별자와 레플리카가 포함된 구성 파일에서 올바르게 정의합니다.
  2. 서버 간에 수동으로 복사해야 하는 비복제 테이블이 있었다면, 레플리카에서 해당 데이터를 복사합니다(/var/lib/clickhouse/data/db_name/table_name/ 디렉터리).
  3. /var/lib/clickhouse/metadata/에 있는 테이블 정의를 레플리카에서 복사합니다. 세그먼트 또는 레플리카 식별자가 테이블 정의에 명시적으로 정의되어 있다면, 현재 레플리카에 맞게 수정합니다. (또는 서버를 시작한 다음, /var/lib/clickhouse/metadata/의 .sql 파일에 들어 있어야 하는 모든 ATTACH TABLE 쿼리를 실행할 수도 있습니다.)
  4. 복구를 시작하려면, ClickHouse Keeper 노드 /path_to_table/replica_name/flags/force_restore_data를 임의의 내용으로 생성하거나, 모든 복제된 테이블을 복원하는 다음 명령을 실행합니다: sudo -u clickhouse touch /var/lib/clickhouse/flags/force_restore_data
그런 다음 서버를 시작합니다(이미 실행 중이면 재시작합니다). 데이터는 레플리카에서 다운로드됩니다. 다른 복구 방법으로는 ClickHouse Keeper에서 손실된 레플리카 정보(/path_to_table/replica_name)를 삭제한 다음, “복제된 테이블 생성”에 설명된 대로 레플리카를 다시 생성하는 방법이 있습니다. 복구 중에는 네트워크 대역폭 제한이 없습니다. 한 번에 많은 레플리카를 복원하는 경우 이 점을 유의하십시오.

MergeTree에서 ReplicatedMergeTree로 변환하기

여기서 MergeTree라는 용어는 ReplicatedMergeTree와 마찬가지로 MergeTree 엔진 계열에 속한 모든 테이블 엔진을 가리킵니다. 수동으로 복제해 온 MergeTree 테이블이 있다면 복제된 테이블로 변환할 수 있습니다. 이미 MergeTree 테이블에 많은 데이터를 수집해 두었고 이제 복제를 활성화하려는 경우 이 작업이 필요할 수 있습니다. ATTACH TABLE … AS REPLICATED SQL 문을 사용하면 분리된 MergeTree 테이블을 ReplicatedMergeTree로 ATTACH할 수 있습니다. 테이블의 데이터 디렉터리(Atomic 데이터베이스의 경우 /store/xxx/xxxyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy/)에 convert_to_replicated 플래그가 설정되어 있으면, 서버를 재시작할 때 MergeTree 테이블이 자동으로 변환될 수 있습니다. 비어 있는 convert_to_replicated 파일을 생성하면 다음 서버 재시작 시 해당 테이블이 복제된 테이블로 로드됩니다. 다음 쿼리를 사용하면 테이블의 데이터 경로를 확인할 수 있습니다. 테이블에 데이터 경로가 여러 개 있으면 첫 번째 경로를 사용해야 합니다.
ReplicatedMergeTree 테이블은 default_replica_pathdefault_replica_name 설정 값을 사용해 생성됩니다. 다른 레플리카에 변환된 테이블을 생성하려면 ReplicatedMergeTree 엔진의 첫 번째 인수에 해당 경로를 명시적으로 지정해야 합니다. 다음 쿼리를 사용하면 해당 경로를 확인할 수 있습니다.
이를 수행하는 수동 방법도 있습니다. 여러 레플리카의 데이터가 서로 다르면 먼저 동기화하거나, 하나를 제외한 모든 레플리카에서 해당 데이터를 삭제하십시오. 기존 MergeTree 테이블의 이름을 변경한 다음, 원래 이름으로 ReplicatedMergeTree 테이블을 생성합니다. 이전 테이블의 데이터를 새 테이블 데이터가 있는 디렉터리(/var/lib/clickhouse/data/db_name/table_name/) 안의 detached 하위 디렉터리로 이동합니다. 그런 다음 레플리카 중 하나에서 ALTER TABLE ATTACH PARTITION을 실행하여 해당 데이터 파트를 활성 세트에 추가합니다.

ReplicatedMergeTree에서 MergeTree로 변환하기

단일 서버에서 분리된 ReplicatedMergeTree 테이블을 MergeTree로 ATTACH하려면 ATTACH TABLE … AS NOT REPLICATED SQL 문을 사용합니다. 이 작업을 수행하는 또 다른 방법은 서버를 재시작하는 것입니다. 다른 이름으로 MergeTree 테이블을 생성합니다. ReplicatedMergeTree 테이블 데이터가 있는 디렉터리의 모든 데이터를 새 테이블의 데이터 디렉터리로 이동합니다. 그런 다음 ReplicatedMergeTree 테이블을 삭제하고 서버를 재시작합니다. 서버를 시작하지 않고 ReplicatedMergeTree 테이블을 제거하려면 다음을 수행하십시오:
  • 메타데이터 디렉터리(/var/lib/clickhouse/metadata/)에서 해당 .sql 파일을 삭제합니다.
  • ClickHouse Keeper에서 해당 경로(/path_to_table/replica_name)를 삭제합니다.
이후 서버를 시작하고 MergeTree 테이블을 생성한 다음, 데이터를 해당 디렉터리로 이동한 후 서버를 다시 재시작할 수 있습니다.

ClickHouse Keeper 클러스터의 메타데이터가 유실되거나 손상되었을 때 복구

ClickHouse Keeper의 데이터가 유실되거나 손상된 경우, 앞에서 설명한 대로 데이터를 복제되지 않은 테이블로 옮겨 보존할 수 있습니다. 관련 항목
마지막 수정일 2026년 7월 3일