-
[ClickHouse] ReplicatedMergeTree 테이블 Backup 적용하기Database/Clickhouse 2024. 2. 29. 07:04반응형
- 목차
들어가며.
이번 글에서는 ReplicatedMergeTree 테이블을 Backup 과 Restore 하는 방법에 대해서 알아보도록 하겠습니다.
먼저 ReplicatedMergeTree 에 대해서 간단히 이야기해보겠습니다.
ReplicatedMergeTree 는 최소 2개의 ClickHouse Replica 들이 필요합니다.
그리고 이 Replica 들은 새롭게 생성된 Part 파일 정보를 서로 공유하며 Replication 을 수행하게 됩니다.
이들이 복제를 위한 수단으로 Zookeeper 를 사용합니다.
각 Replica 는 클라이언트의 요청에 의해서 새롭게 생성된 Part 정보를 Zookeeper Znode 에 기록하고,
다른 Replica 는 Watcher 로써 생성된 Part 에 대한 알림을 받아 Part 를 복사합니다.
Backup 과 Restore 는 altinity/clickhouse-backup 도커 이미지를 기반으로 실습해 볼 예정이며,
아래 링크의 내용을 통해서 MergeTree Table 을 백업하는 기본적인 내용을 습득하실 수 있습니다.
https://westlife0615.tistory.com/669
[ClickHouse] MergeTree 테이블 Backup 하기 ( clickhouse-backup )
- 목차 들어가며.이번 글에서는 Altinity clickhouse-backup 이미지를 기반으로 ClickHouse 의 MergeTree 테이블을 Backup 하는 방법에 대해서 알아봅니다. https://hub.docker.com/r/altinity/clickhouse-backup https://hub.docke
westlife0615.tistory.com
ClickHouse 환경 구축.
ReplicatedMergeTree Table 생성을 위해서 1-Shard & 2-Replicas 구조의 ClickHouse Cluster 를 먼저 생성합니다.
그리고 ReplicatedMergeTree 를 사용하기 위해서는 Zookeeper 가 함께 동반되어야 합니다.
먼저 ClickHouse Cluster 를 구축할 설정 파일을 생성합니다.
아래의 명령어는 Zookeeper 와 ClickHouse 서버들의 관계를 명시한 config.xml 설정 파일입니다.
cat <<'EOF'> /tmp/config.xml <yandex> <zookeeper> <node index="1"> <host>zookeeper1</host> <port>2181</port> </node> <node index="2"> <host>zookeeper2</host> <port>2181</port> </node> <node index="3"> <host>zookeeper3</host> <port>2181</port> </node> </zookeeper> <remote_servers> <clickhouse_cluster> <shard> <replica> <host>replica1</host> <port>9000</port> </replica> <replica> <host>replica2</host> <port>9000</port> </replica> </shard> </clickhouse_cluster> </remote_servers> </yandex> EOF
그리고 macro 설정도 함께 추가합니다.
cat <<'EOF'> /tmp/macro1.xml <yandex> <macros> <shard>1</shard> <replica>1</replica> </macros> </yandex> EOF cat <<'EOF'> /tmp/macro2.xml <yandex> <macros> <shard>1</shard> <replica>2</replica> </macros> </yandex> EOF
아래의 docker-compose.yaml 파일은 3개의 Zookeeper 와 2개의 ClickHouse Replica 를 생성합니다.
cat <<'EOF'> /tmp/ch.yaml version: '3.9' services: replica1: image: altinity/clickhouse-server:22.8.15.25.altinitystable container_name: replica1 hostname: replica1 platform: linux/amd64 networks: - clickhouse volumes: - replica1:/var/lib/clickhouse - /tmp/config.xml:/etc/clickhouse-server/config.d/config.xml - /tmp/macro1.xml:/etc/clickhouse-server/config.d/macro.xml replica2: image: altinity/clickhouse-server:22.8.15.25.altinitystable container_name: replica2 hostname: replica2 platform: linux/amd64 networks: - clickhouse volumes: - replica2:/var/lib/clickhouse - /tmp/config.xml:/etc/clickhouse-server/config.d/config.xml - /tmp/macro2.xml:/etc/clickhouse-server/config.d/macro.xml zookeeper1: image: zookeeper:3.6.1 container_name: zookeeper1 hostname: zookeeper1 platform: linux/amd64 volumes: - zookeeper1:/data networks: - clickhouse environment: ZOO_MY_ID: 1 ZOO_SERVERS: "server.1=zookeeper1:2888:3888;2181 server.2=zookeeper2:2888:3888;2181 server.3=zookeeper3:2888:3888;2181" zookeeper2: image: zookeeper:3.6.1 container_name: zookeeper2 hostname: zookeeper2 platform: linux/amd64 volumes: - zookeeper2:/data networks: - clickhouse environment: ZOO_MY_ID: 2 ZOO_SERVERS: "server.1=zookeeper1:2888:3888;2181 server.2=zookeeper2:2888:3888;2181 server.3=zookeeper3:2888:3888;2181" zookeeper3: image: zookeeper:3.6.1 container_name: zookeeper3 hostname: zookeeper3 platform: linux/amd64 volumes: - zookeeper3:/data networks: - clickhouse environment: ZOO_MY_ID: 3 ZOO_SERVERS: "server.1=zookeeper1:2888:3888;2181 server.2=zookeeper2:2888:3888;2181 server.3=zookeeper3:2888:3888;2181" networks: clickhouse: driver: bridge external: true volumes: replica1: replica2: zookeeper1: zookeeper2: zookeeper3: EOF
docker-compose -f /tmp/ch.yaml -p clickhouse up -d
위 명령어의 실행 후, 생성되는 Docker Container 목록은 아래와 같습니다.
생성된 Cluster 의 구성요소는 system.clusters 테이블을 통해서 확인할 수 있습니다.
select cluster, shard_num, replica_num, host_name from system.clusters where cluster = 'clickhouse_cluster' format Vertical;
Row 1: ────── cluster: clickhouse_cluster shard_num: 1 replica_num: 1 host_name: replica1 Row 2: ────── cluster: clickhouse_cluster shard_num: 1 replica_num: 2 host_name: replica2
ReplicatedMergeTree 테이블 생성.
ReplicatedMergeTree Table 의 DDL Query 는 아래와 같습니다.
각 Replica 에 macro 를 등록해두었기에 아래와 같은 {shard} 와 {replica} 치환변수를 사용할 수 있습니다.
docker exec -it replica1 clickhouse-client
CREATE TABLE default.products_local ON CLUSTER 'clickhouse_cluster' ( id UInt64, name String, price Float64, created_at DateTime ) ENGINE = ReplicatedMergeTree( '/clickhouse/tables/{shard}/products_local', '{replica}' ) ORDER BY id PARTITION BY toYYYYMM(created_at);
그리고 아래의 Insert Query 를 통해서 10만개의 데이터를 생성합니다.
INSERT INTO default.products_local (id, name, price, created_at) SELECT number + 1 AS id, concat('Product_', toString(number + 1)) AS name, round(rand() % 10000 / 100.0, 2) AS price, toDateTime('2023-01-01 00:00:00') + intDiv(number, 100) AS created_at FROM numbers(100000);
SELECT count(*) FROM default.products_local Query id: 64a41d69-f8a2-402d-ac9c-19b92bd4f0d8 ┌─count()─┐ │ 100000 │ └─────────┘ 1 row in set. Elapsed: 0.034 sec.
아래의 Docker 명령어를 통해서 2개의 Replica 가 서로의 데이터를 복제
docker exec replica1 clickhouse-client --query="select count(*) from default.products_local;" docker exec replica2 clickhouse-client --query="select count(*) from default.products_local;"
ReplicatedMergeTree 테이블의 Backup & Restore.
이제 생성된 ReplicatedMergeTree 테이블에 Backup 과 Restore 를 수행합니다.
먼저 Backup 스냅샷을 저장할 원격 저장소를 실행합니다.
docker run --name minio -d \ --network clickhouse \ -e MINIO_ROOT_USER=ROOTUSER -e MINIO_ROOT_PASSWORD=123456789 \ -p 9000:9000 -p 9001:9001 \ bitnami/minio
docker exec minio \ bash -c ' mc alias set ch-backup http://localhost:9000 ROOTUSER 123456789 && \ mc mb ch-backup/clickhouse '
그리고 Backup 을 위한 설정 파일과 Backup 을 실행할 도커 컨테이너를 실행합니다.
cat <<'EOF'> /tmp/config1.yml general: remote_storage: s3 clickhouse: host: replica1 port: 9000 username: "" password: "" database: "default" sync_replicated_tables: true log_sql_queries: false timeout: 5m data_path: '/var/lib/clickhouse' s3: access_key: "ROOTUSER" secret_key: "123456789" bucket: "clickhouse" endpoint: "http://minio:9000" path: replica1 region: "us-east-1" force_path_style: true EOF cat <<'EOF'> /tmp/config2.yml general: remote_storage: s3 clickhouse: host: replica2 port: 9000 username: "" password: "" database: "default" sync_replicated_tables: true log_sql_queries: false timeout: 5m data_path: '/var/lib/clickhouse' s3: access_key: "ROOTUSER" secret_key: "123456789" bucket: "clickhouse" endpoint: "http://minio:9000" path: replica2 region: "us-east-1" force_path_style: true EOF
그리고 아래와 같이 2개의 Docker Container 를 실행합니다.
각각 replica1, replica2 를 백업하기 위한 컨테이너입니다.
유념해야 할 점은 ClickHouse Server 를 실행하면서 사용한 Volume 을 함께 바인딩해주어야합니다.
ClickHouse Server 의 실제 Part 파일에 접근할 수 있도록 파일시스템을 공유해야하기 때문입니다.
docker run -it --rm -u clickhouse \ --network clickhouse \ --platform linux/amd64 \ --mount type=bind,source=/tmp/config1.yml,target=/etc/clickhouse-backup/config.yml \ -v "clickhouse_replica1:/var/lib/clickhouse" \ altinity/clickhouse-backup:2.6.5 bash -c 'clickhouse-backup create backup && clickhouse-backup upload backup'
docker run -it --rm -u clickhouse \ --network clickhouse \ --platform linux/amd64 \ --mount type=bind,source=/tmp/config2.yml,target=/etc/clickhouse-backup/config.yml \ -v "clickhouse_replica2:/var/lib/clickhouse" \ altinity/clickhouse-backup:2.6.5 bash -c 'clickhouse-backup create backup && clickhouse-backup upload backup'
위 명령어가 실행됨으로써 아래와 같이 MinIO 의 Bucket 내부에 백업 파일들이 생성됩니다.
docker exec minio mc ls ch-backup -r /clickhouse
591B STANDARD clickhouse/replica1/backup/metadata.json 606B STANDARD clickhouse/replica1/backup/metadata/default/products_local.json 1.2MiB STANDARD clickhouse/replica1/backup/shadow/default/products_local/default_202301_0_0_0.tar 591B STANDARD clickhouse/replica2/backup/metadata.json 606B STANDARD clickhouse/replica2/backup/metadata/default/products_local.json 1.2MiB STANDARD clickhouse/replica2/backup/shadow/default/products_local/default_202301_0_0_0.tar
새로운 ClickHouse Server 로 Restore 하기.
이제 새로운 ClickHouse Cluster 를 실행하여 Backup 된 스냅샷을 Restore 합니다.
기존의 실행 중인 docker-compose Project 를 삭제하고 새롭게 실행하셔도 무방합니다.
저는 아래와 같은 명령어를 통해서 모든 Container 와 Volume 을 삭제한 후에 다시 Docker Compose 를 실행하였습니다.
docker rm -f replica1 docker rm -f replica2 docker rm -f zookeeper1 docker rm -f zookeeper2 docker rm -f zookeeper3 docker volume rm clickhouse_replica1 docker volume rm clickhouse_replica2 docker volume rm clickhouse_zookeeper1 docker volume rm clickhouse_zookeeper2 docker volume rm clickhouse_zookeeper3
Container 와 Volume 삭제 후에 다시 docker-compose 를 실행합니다.
docker-compose -f /tmp/ch.yaml -p clickhouse up -d
그리고 아래의 clickhouse-backup 명령어를 통해서 새롭게 생성된 ClickHouse replica1 과 replica2 의 Restore 를 수행합니다.
docker run -it --rm -u clickhouse \ --network clickhouse \ --platform linux/amd64 \ --mount type=bind,source=/tmp/config1.yml,target=/etc/clickhouse-backup/config.yml \ -v "clickhouse_replica1:/var/lib/clickhouse" \ altinity/clickhouse-backup:2.6.5 bash -c 'clickhouse-backup download backup && clickhouse-backup restore backup'
docker run -it --rm -u clickhouse \ --network clickhouse \ --platform linux/amd64 \ --mount type=bind,source=/tmp/config2.yml,target=/etc/clickhouse-backup/config.yml \ -v "clickhouse_replica2:/var/lib/clickhouse" \ altinity/clickhouse-backup:2.6.5 bash -c 'clickhouse-backup download backup && clickhouse-backup restore backup'
그 후 각 Replica 의 상태를 확인하게 되면 백업의 컨텐츠가 반영됨을 확인할 수 있습니다.
docker exec replica1 clickhouse-client --query="select count(*) from default.products_local;" docker exec replica2 clickhouse-client --query="select count(*) from default.products_local;"
반응형'Database > Clickhouse' 카테고리의 다른 글
[ClickHouse] Distributed Table 알아보기 (0) 2024.03.18 [ClickHouse] Parts & Partition 알아보기 (0) 2024.02.29 [ClickHouse] primary.idx 파일 알아보기 (0) 2024.02.28 [ClickHouse Config] listen_host 설정 알아보기 (0) 2024.02.28 [Clickhouse] ReplicatedMergeTree 알아보기 (0) 2024.02.18