ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [ClickHouse] remote_servers 설정 알아보기
    Database/Clickhouse 2024. 6. 3. 06:08
    728x90
    반응형

     

    - 목차

     

    들어가며.

    ClickHouse분산 테이블(Distributed Table) 을 통해 여러 노드에서 데이터를 처리하고 저장할 수 있습니다.

    이때, 각 노드 간 통신 및 데이터 분배를 위해 remote_servers 설정이 필수적입니다.

    remote_servers 설정을 통해서 샤딩(Sharding)복제(Replication) 를 구성할 수 있습니다.

     

    • 샤딩(Sharding): 데이터를 여러 노드에 나누어 저장하여, 저장 용량을 확장하고 쓰기 및 읽기 성능을 높이는 기술
    • 복제(Replication): 동일한 데이터를 여러 노드에 복제하여, 데이터 손실 방지와 장애 복구를 가능하게 하는 기술

     

    ClickHouse 는 이 두 가지를 기반으로 수평 확장이 가능한 분산 데이터베이스를 제공합니다.

    이 과정에서 Sharding 을 위한 ClickHouse Node 와 Replication 을 위한 ClickHouse Node 를 지정할 수 있습니다.

    이 글에서는 remote_servers 설정의 구조와 동작 원리를 이해하고, 이를 활용한 분산 테이블 구축 방법을 알아보겠습니다.

     

    https://westlife0615.tistory.com/880

     

    [ClickHouse] remote_servers 설정 알아보기

    - 목차 들어가며.ClickHouse 는 분산 테이블(Distributed Table) 을 통해 여러 노드에서 데이터를 처리하고 저장할 수 있습니다.이때, 각 노드 간 통신 및 데이터 분배를 위해 remote_servers 설정이 필수적입

    westlife0615.tistory.com

     

     

    remote_servers 설정으로 Sharding 구현해보기.

    remote_servers 설정을 통해서 ClickHouse 의 Multi Shards 구조를 구현해보도록 하겠습니다.

    remote_serversClickHouseconfig.xml 파일에 정의되며,

    클러스터 이름과 그 하위 샤드 및 복제본 정보를 포함합니다.

     

    아래는 ClickHouseremote_servers 설정 파일에 대한 예제입니다.

    이 설정은 두 개의 ClickHouse 노드를 샤드(shard)로 구성하여 Sharding 구조를 구성하는 방법을 보여줍니다.

    <clickhouse> 태그는 config.xml 이 요구하는 루트 태그명이며,

    <remote_servers> 태그 하위에서 샤딩 구조의 노드를 설정할 수 있습니다.

    cat <<'EOF'> /tmp/servers.xml
    <clickhouse>
        <remote_servers>
            <my_cluster>
                <shard>
                    <replica>
                        <host>clickhouse1</host>
                        <port>9000</port>
                    </replica>
                </shard>
                <shard>
                    <replica>
                        <host>clickhouse2</host>
                        <port>9000</port>
                    </replica>
                </shard>
            </my_cluster>
        </remote_servers>
    </clickhouse>
    EOF

     

     

    그리고 2개의 ClickHouse Docker Container 를 실행합니다.

    각각의 Node 는 clickhouse1, clickhouse2 라는 hostname 을 가집니다.

    이 hostname 은 <remote_servers> 설정에서 <host> 의 값으로 사용됩니다.

    docker network create clickhouse
    
    docker run -d --platform linux/amd64 \
    --name clickhouse1 \
    --network clickhouse \
    --hostname clickhouse1 \
    --mount type=bind,source=/tmp/servers.xml,target=/etc/clickhouse-server/config.d/servers.xml \
    clickhouse:24.9.3
    
    docker run -d --platform linux/amd64 \
    --name clickhouse2 \
    --network clickhouse \
    --hostname clickhouse2 \
    --mount type=bind,source=/tmp/servers.xml,target=/etc/clickhouse-server/config.d/servers.xml \
    clickhouse:24.9.3

     

    아래의 명령어와 실행 결과는 remote_servers 의 구성의 결과를 확인할 수 있는 쿼리입니다.

    my_cluster 라는 이름의 2개의 ClickHouse Node 를 확인할 수 있습니다.

    docker exec clickhouse1 clickhouse-client \
    --query='select * from system.clusters format vertical;'
    Row 1:
    ──────
    cluster:                 default
    shard_num:               1
    shard_weight:            1
    internal_replication:    0
    replica_num:             1
    host_name:               localhost
    host_address:            127.0.0.1
    port:                    9000
    is_local:                1
    user:                    default
    default_database:
    errors_count:            0
    slowdowns_count:         0
    estimated_recovery_time: 0
    database_shard_name:
    database_replica_name:
    is_active:               ᴺᵁᴸᴸ
    replication_lag:         ᴺᵁᴸᴸ
    recovery_time:           ᴺᵁᴸᴸ
    
    Row 2:
    ──────
    cluster:                 my_cluster
    shard_num:               1
    shard_weight:            1
    internal_replication:    0
    replica_num:             1
    host_name:               clickhouse1
    host_address:            172.21.0.2
    port:                    9000
    is_local:                1
    user:                    default
    default_database:
    errors_count:            0
    slowdowns_count:         0
    estimated_recovery_time: 0
    database_shard_name:
    database_replica_name:
    is_active:               ᴺᵁᴸᴸ
    replication_lag:         ᴺᵁᴸᴸ
    recovery_time:           ᴺᵁᴸᴸ
    
    Row 3:
    ──────
    cluster:                 my_cluster
    shard_num:               2
    shard_weight:            1
    internal_replication:    0
    replica_num:             1
    host_name:               clickhouse2
    host_address:            172.21.0.3
    port:                    9000
    is_local:                0
    user:                    default
    default_database:
    errors_count:            0
    slowdowns_count:         0
    estimated_recovery_time: 0
    database_shard_name:
    database_replica_name:
    is_active:               ᴺᵁᴸᴸ
    replication_lag:         ᴺᵁᴸᴸ
    recovery_time:           ᴺᵁᴸᴸ

     

     

    Distributed MergeTree Table 생성하기.

    2개의 ClickHouse Node 들이 Sharding 구조를 취하도록 ClickHouse Node 들을 실행하였습니다.

    이제 Distributed Table 을 생성해보도록 하겠습니다.

    CREATE TABLE local_table
    (
        id UInt32,
        value String
    )
    ENGINE = MergeTree()
    ORDER BY id;

     

    실행 중인 ClickHouse Node 들 중에서 임의의 ClickHouse Node 에 접근하여 테이블을 생성합니다.

    만약 clickhouse1 노드에서 테이블을 생성하였다면, clickhouse2 노드에서는 테이블이 존재하지 않습니다.

     

    아래의 이미지와 같이 local_table 은 모든 ClickHouse Node 에서 생성되지 않은 상태가 됩니다.

     

     

    clickhouse2 노드에서도 동일하게 테이블을 생성합니다.

    그리고 Distributed Table 을 생성합니다.

    CREATE TABLE distributed_table
    (
        id UInt32,
        value String
    )
    ENGINE = Distributed('my_cluster', 'default', 'local_table', id);

     

    위 과정들을 모두 마치게 되면, 아래의 이미지처럼 각각의 ClickHouse Nodelocal_tabledistributed_table 이 생성되게 됩니다.

     

    이로써 Distributed Table 의 구성이 완료되었습니다.

    한번 Insert Query 를 통해서 데이터의 샤딩이 적용되는지 확인해보겠습니다.

    아래와 같이 3개의 Insert Query 들을 실행합니다.

    Sharding Key 가 id 칼럼이므로 id 칼럼의 다른 값을 취하도록 합니다.

     

    insert into distributed_table(id, value) values (1, '1');
    insert into distributed_table(id, value) values (2, '1');
    insert into distributed_table(id, value) values (3, '1');

     

    위의 이미지와 같이 id 1 과 3 인 Row 들은 clickhouse 2 Node 에 삽입되고, id 가 2 인 Row 는 clickhouse1 Node 에 삽입됩니다.

     

     

    Replication 구성하기.

    Replication 을 구현하기 위해서 ReplicatedMergeTree 테이블 엔진을 사용합니다.

    그리고 ReplicatedMergeTree 를 사용하기 위해서는 ZookeeperClickHouse 와 함께 사용해야합니다.

     

    Zookeeper 와 ReplicatedMergeTree 를 사용하는 방법은 아래와 같습니다.

    일반적인 Sharding 보다 추가되는 설정이 더 많습니다.

    cat <<'EOF'> /tmp/servers.xml
    <clickhouse>
        <zookeeper>
            <node>
                <host>zookeeper</host>
                <port>2181</port>
            </node>
        </zookeeper>
        <remote_servers>
            <my_cluster>
                <shard>
                    <replica>
                        <host>clickhouse1</host>
                        <port>9000</port>
                    </replica>
                    <replica>
                        <host>clickhouse2</host>
                        <port>9000</port>
                    </replica>
                </shard>
            </my_cluster>
        </remote_servers>
    </clickhouse>
    EOF
    
    cat <<'EOF'> /tmp/macro1.xml
    <clickhouse>
        <macros>
            <shard>1</shard>
            <replica>node1</replica>
        </macros>
    </clickhouse>
    EOF
    
    cat <<'EOF'> /tmp/macro2.xml
    <clickhouse>
        <macros>
            <shard>1</shard>
            <replica>node2</replica>
        </macros>
    </clickhouse>
    EOF

     

    ZooKeeper 설정.

    • <zookeeper> 태그는 ZooKeeper 클러스터에 대한 설정을 나타냅니다.
    • host: ZooKeeper 서버의 호스트 이름 (여기서는 zookeeper).
    • port: ZooKeeper 서버 포트 (기본값 2181).

    ClickHouse 는 ReplicatedMergeTree 엔진을 사용할 때 ZooKeeper 를 통해 테이블 복제 상태를 관리하므로 ZooKeeper 설정이 필수입니다.

     

    remote_servers 설정.

    Replication 을 위해선 하나의 Shard 내부에 2개의 replicas 가 등록되어야합니다.

    <shard> 태그 내부에 clickhouse1과 clickhouse2 노드가 위치해야합니다.

     

    macro 설정.

    macro 는 각 Node 에서 사용될 개별적인 상수를 설정하는 방식입니다.

    일반적으로 Replication 시에 Shard 와 Replica 이름을 지정하게 됩니다.

     

     

    이제 아래의 Docker 명령어를 통해서 Zookeeper 와 2개의 ClickHouse Container 를 실행합니다.

    docker network create clickhouse
    
    docker run -d --platform linux/amd64 \
    --name zookeeper \
    --network clickhouse \
    --hostname zookeeper \
    -e ZOOKEEPER_SERVER_ID=1 \
    -e ZOOKEEPER_CLIENT_PORT=2181 \
    -e ZOOKEEPER_TICK_TIME=2000 \
    -e ZOOKEEPER_INIT_LIMIT=5 \
    -e ZOOKEEPER_SYNC_LIMIT=2 \
    confluentinc/cp-zookeeper:7.4.3
    
    docker run -d --platform linux/amd64 \
    --name clickhouse1 \
    --network clickhouse \
    --hostname clickhouse1 \
    --mount type=bind,source=/tmp/servers.xml,target=/etc/clickhouse-server/config.d/servers.xml \
    --mount type=bind,source=/tmp/macro1.xml,target=/etc/clickhouse-server/config.d/macro.xml \
    clickhouse:24.9.3
    
    docker run -d --platform linux/amd64 \
    --name clickhouse2 \
    --network clickhouse \
    --hostname clickhouse2 \
    --mount type=bind,source=/tmp/servers.xml,target=/etc/clickhouse-server/config.d/servers.xml \
    --mount type=bind,source=/tmp/macro2.xml,target=/etc/clickhouse-server/config.d/macro.xml \
    clickhouse:24.9.3

     

     

    macro 설정 확인.

    아래의 명령어를 통해서 각 노드에 설정된 Macro 를 확인할 수 있습니다.

    docker exec clickhouse1 clickhouse-client \
    --query='select * from system.macros'
    
    docker exec clickhouse2 clickhouse-client \
    --query='select * from system.macros'

     

     

    아래의 ReplicatedMergeTree Table DDL 을 통해서 테이블을 생성합니다.

    2개의 ClickHouse Node 에 개별적으로 수행해줍니다.

    CREATE TABLE replicated_table
    (
        id UInt32,
        value String
    )
    ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/replicated_table', '{replica}')
    ORDER BY id;

     

    위 이미지와 같이 replicated_table 이 모두 생성되었다면 ReplicatedMergeTree 엔진의 테이블이 준비된 상태입니다.

    이제 데이터를 추가해보도록 하겠습니다.

     

    아래의 Insert Query 와 실행 결과처럼 Row 가 복제된 결과를 확인할 수 있습니다.

    INSERT INTO default.replicated_table (id, value) values (1, '1');

     

     

     

     

    반응형
Designed by Tistory.