> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-fbfa8bee.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Google Cloud Storage (GCS) 기반 MergeTree

# Google Cloud Storage를 ClickHouse에 통합하기

export const Image = ({img, alt, size}) => {
  return <Frame>
      <img src={img} alt={alt} />
    </Frame>;
};

<Note>
  [Google Cloud](https://cloud.google.com)에서 ClickHouse Cloud를 사용 중이라면 서비스가 이미 [Google Cloud Storage](https://cloud.google.com/storage)를 사용하므로 이 페이지는 해당되지 않습니다. GCS에서 데이터를 `SELECT`하거나 `INSERT`하려면 [`gcs` 테이블 함수](/ko/reference/functions/table-functions/gcs)를 참조하십시오.
</Note>

ClickHouse는 스토리지와 컴퓨트를 분리하려는 경우 GCS가 매력적인 스토리지 솔루션이 될 수 있음을 인지하고 있습니다. 이를 지원하기 위해 MergeTree 엔진의 스토리지로 GCS를 사용할 수 있도록 지원합니다. 이를 통해 GCS의 확장성과 비용상 이점을 활용하는 동시에 MergeTree 엔진의 삽입 및 쿼리 성능도 활용할 수 있습니다.

<div id="gcs-backed-mergetree">
  ## GCS 기반 MergeTree
</div>

<div id="creating-a-disk">
  ### 디스크 생성
</div>

GCS 버킷을 디스크로 사용하려면 먼저 `conf.d` 아래의 파일에 있는 ClickHouse 구성에서 이를 선언해야 합니다. 아래는 GCS 디스크 선언 예시입니다. 이 구성에는 GCS "디스크", 캐시, 그리고 GCS 디스크에 테이블(table)을 생성할 때 DDL 쿼리에서 지정할 정책을 설정하는 여러 섹션이 포함되어 있습니다. 각 섹션은 아래에서 설명합니다.

<div id="storage_configuration--disks--gcs">
  #### 스토리지 구성 > disks > gcs
</div>

이 구성 부분은 강조 표시된 섹션에 나와 있으며, 다음을 지정합니다.

* 디스크 유형은 S3 API를 사용하므로 `s3`입니다.
* GCS에서 제공하는 endpoint
* 서비스 계정 HMAC 키와 시크릿
* 로컬 디스크의 메타데이터 경로

```xml highlight={5-10} theme={null}
<clickhouse>
    <storage_configuration>
        <disks>
            <gcs>
                <support_batch_delete>true</support_batch_delete>
                <type>s3</type>
                <endpoint>https://storage.googleapis.com/BUCKET NAME/FOLDER NAME/</endpoint>
                <access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
                <secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
                <metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
            </gcs>
        </disks>
        <policies>
            <gcs_main>
                <volumes>
                    <main>
                        <disk>gcs</disk>
                    </main>
                </volumes>
            </gcs_main>
        </policies>
    </storage_configuration>
</clickhouse>
```

<div id="storage_configuration--disks--cache">
  #### 스토리지 구성 > disks > 캐시
</div>

아래 강조 표시된 예시 구성은 디스크 `gcs`에 10Gi 메모리 캐시를 활성화합니다.

```xml highlight={12-17} theme={null}
<clickhouse>
    <storage_configuration>
        <disks>
            <gcs>
                <support_batch_delete>true</support_batch_delete>
                <type>s3</type>
                <endpoint>https://storage.googleapis.com/BUCKET NAME/FOLDER NAME/</endpoint>
                <access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
                <secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
                <metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
            </gcs>
            <gcs_cache>
                <type>cache</type>
                <disk>gcs</disk>
                <path>/var/lib/clickhouse/disks/gcs_cache/</path>
                <max_size>10Gi</max_size>
            </gcs_cache>
        </disks>
        <policies>
            <gcs_main>
                <volumes>
                    <main>
                        <disk>gcs_cache</disk>
                    </main>
                </volumes>
            </gcs_main>
        </policies>
    </storage_configuration>
</clickhouse>
```

<div id="storage_configuration--policies--gcs_main">
  #### 스토리지 구성 > 정책 > gcs\_main
</div>

스토리지 구성 정책을 사용하면 데이터를 저장할 위치를 선택할 수 있습니다. 아래에 표시된 정책은 `gcs_main` 정책을 지정해 데이터를 디스크 `gcs`에 저장할 수 있도록 합니다. 예를 들어 `CREATE TABLE ... SETTINGS storage_policy='gcs_main'`와 같습니다.

```xml highlight={14-20} theme={null}
<clickhouse>
    <storage_configuration>
        <disks>
            <gcs>
                <support_batch_delete>true</support_batch_delete>
                <type>s3</type>
                <endpoint>https://storage.googleapis.com/BUCKET NAME/FOLDER NAME/</endpoint>
                <access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
                <secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
                <metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
            </gcs>
        </disks>
        <policies>
            <gcs_main>
                <volumes>
                    <main>
                        <disk>gcs</disk>
                    </main>
                </volumes>
            </gcs_main>
        </policies>
    </storage_configuration>
</clickhouse>
```

이 디스크 선언과 관련된 전체 설정 목록은 [여기](/ko/reference/engines/table-engines/mergetree-family/mergetree#table_engine-mergetree-s3)에서 확인할 수 있습니다.

<div id="creating-a-table">
  ### 테이블 생성
</div>

디스크가 쓰기 권한이 있는 버킷을 사용하도록 구성되어 있다면, 아래 예시와 같은 테이블을 생성할 수 있습니다. 설명을 간단히 하기 위해 NYC taxi 컬럼 일부만 사용하고, 데이터를 GCS 기반 테이블로 직접 스트리밍합니다:

```sql highlight={20} theme={null}
CREATE TABLE trips_gcs
(
   `trip_id` UInt32,
   `pickup_date` Date,
   `pickup_datetime` DateTime,
   `dropoff_datetime` DateTime,
   `pickup_longitude` Float64,
   `pickup_latitude` Float64,
   `dropoff_longitude` Float64,
   `dropoff_latitude` Float64,
   `passenger_count` UInt8,
   `trip_distance` Float64,
   `tip_amount` Float32,
   `total_amount` Float32,
   `payment_type` Enum8('UNK' = 0, 'CSH' = 1, 'CRE' = 2, 'NOC' = 3, 'DIS' = 4)
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(pickup_date)
ORDER BY pickup_datetime
SETTINGS storage_policy='gcs_main'
```

```sql theme={null}
INSERT INTO trips_gcs SELECT trip_id, pickup_date, pickup_datetime, dropoff_datetime, pickup_longitude, pickup_latitude, dropoff_longitude, dropoff_latitude, passenger_count, trip_distance, tip_amount, total_amount, payment_type FROM s3('https://ch-nyc-taxi.s3.eu-west-3.amazonaws.com/tsv/trips_{0..9}.tsv.gz', 'TabSeparatedWithNames') LIMIT 1000000;
```

하드웨어에 따라 이 마지막 100만 행 삽입 작업은 완료하는 데 몇 분 정도 걸릴 수 있습니다. 진행 상황은 system.processes 테이블(table)에서 확인할 수 있습니다. 행 수는 최대 1000만까지 늘려 보고, 샘플 쿼리도 몇 가지 살펴보십시오.

```sql theme={null}
SELECT passenger_count, avg(tip_amount) AS avg_tip, avg(total_amount) AS avg_amount FROM trips_gcs GROUP BY passenger_count;
```

<div id="handling-replication">
  ### 복제 처리
</div>

GCS 디스크를 사용하는 복제는 `ReplicatedMergeTree` 테이블 엔진으로 구현할 수 있습니다. 자세한 내용은 [GCS를 사용해 두 GCP 리전에서 단일 세그먼트를 복제하는 방법](#gcs-multi-region) 가이드를 참조하십시오.

<div id="learn-more">
  ### 자세히 알아보기
</div>

[Cloud Storage XML API](https://cloud.google.com/storage/docs/xml-api/overview)는 Amazon Simple Storage Service(Amazon S3)와 같은 서비스에서 사용하는 일부 도구 및 라이브러리와 호환됩니다.

스레드 조정에 대한 자세한 내용은 [성능 최적화](/ko/integrations/connectors/data-ingestion/AWS/integrating-s3-with-clickhouse#s3-optimizing-performance)를 참조하십시오.

<div id="gcs-multi-region">
  ## Google Cloud Storage (GCS) 사용
</div>

<Tip>
  ClickHouse Cloud에서는 기본적으로 객체 스토리지를 사용하므로, ClickHouse Cloud에서 실행 중이라면 이 절차를 따를 필요가 없습니다.
</Tip>

<div id="plan-the-deployment">
  ### 배포 계획
</div>

이 튜토리얼은 Google Cloud에서 실행되고, ClickHouse 스토리지 디스크 "type"으로 Google Cloud Storage(GCS)를 사용하는 복제된 ClickHouse 배포를 설명합니다.

이 튜토리얼에서는 각 노드에 스토리지용 GCS 버킷이 연결된 Google Cloud Engine VM에 ClickHouse 서버 노드를 배포합니다. 복제는 역시 VM으로 배포된 ClickHouse Keeper 노드 집합이 조정합니다.

고가용성을 위한 예시 요구 사항:

* 2개의 GCP 리전에 각각 배포된 2개의 ClickHouse 서버 노드
* 두 ClickHouse 서버 노드와 동일한 리전에 배포된 2개의 GCS 버킷
* 3개의 ClickHouse Keeper 노드. 이 중 2개는 ClickHouse 서버 노드와 동일한 리전에 배포됩니다. 세 번째 노드는 첫 두 Keeper 노드 중 하나와 동일한 리전에 둘 수 있지만, 가용 영역은 달라야 합니다.

ClickHouse Keeper가 작동하려면 최소 2개의 노드가 필요하므로, 고가용성을 위해서는 3개의 노드가 필요합니다.

<div id="prepare-vms">
  ### 가상 머신 준비
</div>

3개의 리전에 VM 5대를 배포합니다:

| 리전    | ClickHouse 서버 | 버킷                  | ClickHouse Keeper |
| ----- | ------------- | ------------------- | ----------------- |
| 1     | `chnode1`     | `bucket_regionname` | `keepernode1`     |
| 2     | `chnode2`     | `bucket_regionname` | `keepernode2`     |
| 3 `*` |               |                     | `keepernode3`     |

`*` 이는 1 또는 2와 동일한 리전 내의 다른 가용 영역일 수 있습니다.

<div id="deploy-clickhouse">
  #### ClickHouse 배포
</div>

두 개의 호스트에 ClickHouse를 배포합니다. 이 샘플 구성에서는 호스트 이름을 `chnode1`, `chnode2`로 사용합니다.

`chnode1`은 한 GCP 리전에, `chnode2`는 다른 리전에 배치합니다. 이 가이드에서는 Compute Engine VM과 GCS 버킷에 `us-east1` 및 `us-east4`를 사용합니다.

<Note>
  구성이 완료되기 전에는 `clickhouse server`를 시작하지 마십시오. 설치만 진행하십시오.
</Note>

ClickHouse 서버 노드에서 배포 단계를 수행할 때는 [설치 지침](/ko/get-started/setup/install)을 참조하십시오.

<div id="deploy-clickhouse-keeper">
  #### ClickHouse Keeper 배포
</div>

3개의 호스트에 ClickHouse Keeper를 배포합니다. 샘플 구성에서는 이 호스트의 이름을 `keepernode1`, `keepernode2`, `keepernode3`로 사용합니다. `keepernode1`은 `chnode1`과 동일한 리전에, `keepernode2`는 `chnode2`와 동일한 리전에 배포할 수 있습니다. `keepernode3`는 두 리전 중 어느 곳에든 배포할 수 있지만, 해당 리전의 ClickHouse 노드와는 서로 다른 가용 영역에 배포해야 합니다.

ClickHouse Keeper 노드에서 배포 단계를 수행할 때는 [설치 지침](/ko/get-started/setup/install)을 참조하십시오.

<div id="create-two-buckets">
  ### 버킷 두 개 만들기
</div>

고가용성을 위해 두 ClickHouse 서버는 서로 다른 리전에 배치됩니다. 각 서버에는 동일한 리전에 GCS 버킷이 하나씩 있어야 합니다.

**Cloud Storage > Buckets**에서 **CREATE BUCKET**을 선택하십시오. 이 튜토리얼에서는 `us-east1`과 `us-east4`에 각각 하나씩, 총 2개의 버킷을 만듭니다. 버킷은 단일 리전, Standard 스토리지 클래스, 비공개로 설정합니다. 메시지가 표시되면 public access prevention을 활성화하십시오. 폴더는 만들지 마십시오. ClickHouse가 스토리지에 쓸 때 자동으로 생성됩니다.

버킷과 HMAC 키를 만드는 단계별 안내가 필요하면 **Create GCS buckets and an HMAC key**를 펼쳐 따라 하십시오:

<Accordion title="GCS 버킷 및 HMAC 키 생성">
  ### ch\_bucket\_us\_east1

  <Image size="md" img="https://mintcdn.com/private-7c7dfe99-mintlify-fbfa8bee/ysNmqKfMa0gVKvYj/images/integrations/data-ingestion/s3/GCS-bucket-1.png?fit=max&auto=format&n=ysNmqKfMa0gVKvYj&q=85&s=27b3795ec2c474f21115db86517d7c94" alt="US East 1에서 GCS 버킷 생성" border width="1437" height="387" data-path="images/integrations/data-ingestion/s3/GCS-bucket-1.png" />

  ### ch\_bucket\_us\_east4

  <Image size="md" img="https://mintcdn.com/private-7c7dfe99-mintlify-fbfa8bee/ysNmqKfMa0gVKvYj/images/integrations/data-ingestion/s3/GCS-bucket-2.png?fit=max&auto=format&n=ysNmqKfMa0gVKvYj&q=85&s=a529210c01f0debd00d2dc188d2ac502" alt="US East 4에서 GCS 버킷 생성" border width="1437" height="386" data-path="images/integrations/data-ingestion/s3/GCS-bucket-2.png" />

  ### 액세스 키 생성

  ### 서비스 계정 HMAC 키 및 시크릿 생성

  **Cloud Storage > 설정 > Interoperability**를 열고 기존 **Access key**를 선택하거나 **CREATE A KEY FOR A SERVICE ACCOUNT**를 선택합니다. 이 가이드에서는 새 서비스 계정용 새 키를 생성하는 절차를 설명합니다.

  <Image size="md" img="https://mintcdn.com/private-7c7dfe99-mintlify-fbfa8bee/ysNmqKfMa0gVKvYj/images/integrations/data-ingestion/s3/GCS-create-a-service-account-key.png?fit=max&auto=format&n=ysNmqKfMa0gVKvYj&q=85&s=c4d60f90c6ac63adf42c0d5b9e46a326" alt="GCS에서 서비스 계정 HMAC 키 생성" border width="969" height="911" data-path="images/integrations/data-ingestion/s3/GCS-create-a-service-account-key.png" />

  ### 새 서비스 계정 추가

  기존 서비스 계정이 없는 프로젝트라면 **CREATE NEW ACCOUNT**를 선택합니다.

  <Image size="md" img="https://mintcdn.com/private-7c7dfe99-mintlify-fbfa8bee/ysNmqKfMa0gVKvYj/images/integrations/data-ingestion/s3/GCS-create-service-account-0.png?fit=max&auto=format&n=ysNmqKfMa0gVKvYj&q=85&s=5532ca2ab7181e65069c23c7ad0ace77" alt="GCS에서 새 서비스 계정 추가" border width="924" height="317" data-path="images/integrations/data-ingestion/s3/GCS-create-service-account-0.png" />

  서비스 계정 생성은 3단계로 이루어집니다. 첫 번째 단계에서는 계정에 의미 있는 이름, ID 및 설명을 지정합니다.

  <Image size="md" img="https://mintcdn.com/private-7c7dfe99-mintlify-fbfa8bee/ysNmqKfMa0gVKvYj/images/integrations/data-ingestion/s3/GCS-create-service-account-a.png?fit=max&auto=format&n=ysNmqKfMa0gVKvYj&q=85&s=4ec5be0e99acbf2d2bed9f9e4cad3a95" alt="GCS에서 새 서비스 계정 이름과 ID 지정" border width="842" height="737" data-path="images/integrations/data-ingestion/s3/GCS-create-service-account-a.png" />

  Interoperability 설정 대화상자에서는 IAM role인 **Storage Object Admin** 역할을 권장합니다. 두 번째 단계에서 해당 역할을 선택합니다.

  <Image size="md" img="https://mintcdn.com/private-7c7dfe99-mintlify-fbfa8bee/ysNmqKfMa0gVKvYj/images/integrations/data-ingestion/s3/GCS-create-service-account-2.png?fit=max&auto=format&n=ysNmqKfMa0gVKvYj&q=85&s=99f98f7f2684736aa2181191b44cc4c0" alt="GCS에서 IAM role Storage Object Admin 선택" border width="822" height="396" data-path="images/integrations/data-ingestion/s3/GCS-create-service-account-2.png" />

  세 번째 단계는 선택 사항이며, 이 가이드에서는 사용하지 않습니다. 정책에 따라 사용자에게 이러한 권한을 부여할 수 있습니다.

  <Image size="md" img="https://mintcdn.com/private-7c7dfe99-mintlify-fbfa8bee/ysNmqKfMa0gVKvYj/images/integrations/data-ingestion/s3/GCS-create-service-account-3.png?fit=max&auto=format&n=ysNmqKfMa0gVKvYj&q=85&s=97534c90225ce94557ea1ea97bc57ec7" alt="GCS에서 새 서비스 계정의 추가 설정 구성" border width="635" height="697" data-path="images/integrations/data-ingestion/s3/GCS-create-service-account-3.png" />

  서비스 계정 HMAC 키가 표시됩니다. 이 정보는 ClickHouse 구성에서 사용되므로 저장해 두십시오.

  <Image size="md" img="https://mintcdn.com/private-7c7dfe99-mintlify-fbfa8bee/5u7Mhe0xzzPTUaXM/images/integrations/data-ingestion/s3/GCS-guide-key.png?fit=max&auto=format&n=5u7Mhe0xzzPTUaXM&q=85&s=898ccd9ed73756ff5cd39843eb29eeaa" alt="GCS용으로 생성된 HMAC 키 확인" border width="917" height="390" data-path="images/integrations/data-ingestion/s3/GCS-guide-key.png" />
</Accordion>

<div id="configure-clickhouse-keeper">
  ### ClickHouse Keeper 구성
</div>

모든 ClickHouse Keeper 노드는 `server_id` 줄(아래에서 첫 번째로 강조 표시된 줄)을 제외하면 동일한 설정 파일을 사용합니다. ClickHouse Keeper 서버의 호스트명에 맞게 파일을 수정하고, 각 서버에서 `server_id`를 `raft_configuration`의 해당 `server` 항목과 일치하도록 설정하십시오. 이 예시에서는 `server_id`가 `3`으로 설정되어 있으므로 `raft_configuration`에서 일치하는 줄을 강조 표시했습니다.

* 파일에서 호스트명을 수정하고, 해당 호스트명이 ClickHouse 서버 노드와 Keeper 노드에서 모두 확인되는지 확인하세요
* 파일을 각 Keeper 서버의 지정된 위치로 복사하세요(`/etc/clickhouse-keeper/keeper_config.xml`)
* 각 머신에서 `raft_configuration`의 항목 번호를 기준으로 `server_id`를 수정하세요

```xml title=/etc/clickhouse-keeper/keeper_config.xml highlight={12,33-37} theme={null}
<clickhouse>
    <logger>
        <level>trace</level>
        <log>/var/log/clickhouse-keeper/clickhouse-keeper.log</log>
        <errorlog>/var/log/clickhouse-keeper/clickhouse-keeper.err.log</errorlog>
        <size>1000M</size>
        <count>3</count>
    </logger>
    <listen_host>0.0.0.0</listen_host>
    <keeper_server>
        <tcp_port>9181</tcp_port>
        <server_id>3</server_id>
        <log_storage_path>/var/lib/clickhouse/coordination/log</log_storage_path>
        <snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>

        <coordination_settings>
            <operation_timeout_ms>10000</operation_timeout_ms>
            <session_timeout_ms>30000</session_timeout_ms>
            <raft_logs_level>warning</raft_logs_level>
        </coordination_settings>

        <raft_configuration>
            <server>
                <id>1</id>
                <hostname>keepernode1.us-east1-b.c.clickhousegcs-374921.internal</hostname>
                <port>9234</port>
            </server>
            <server>
                <id>2</id>
                <hostname>keepernode2.us-east4-c.c.clickhousegcs-374921.internal</hostname>
                <port>9234</port>
            </server>
            <server>
                <id>3</id>
                <hostname>keepernode3.us-east5-a.c.clickhousegcs-374921.internal</hostname>
                <port>9234</port>
            </server>
        </raft_configuration>
    </keeper_server>
</clickhouse>
```

<div id="configure-clickhouse-server">
  ### ClickHouse 서버 구성
</div>

<Info>
  **모범 사례**

  이 가이드의 일부 단계에서는 설정 파일을 `/etc/clickhouse-server/config.d/`에 배치하도록 안내합니다. 이는 Linux 시스템에서 설정 재정의 파일의 기본 위치입니다. 이 파일을 해당 디렉터리에 넣으면 ClickHouse가 그 내용을 기본 구성과 머지합니다. 이러한 파일을 `config.d` 디렉터리에 배치하면 업그레이드 중 구성이 손실되는 것을 방지할 수 있습니다.
</Info>

<div id="networking">
  #### 네트워킹
</div>

기본적으로 ClickHouse는 루프백 인터페이스에서만 수신 대기합니다. 복제된 구성에서는 서버 간 네트워킹이 필요합니다. 모든 인터페이스에서 수신 대기하도록 설정하십시오:

```xml title=/etc/clickhouse-server/config.d/network.xml theme={null}
<clickhouse>
    <listen_host>0.0.0.0</listen_host>
</clickhouse>
```

<div id="remote-clickhouse-keeper-servers">
  #### 원격 ClickHouse Keeper 서버
</div>

복제는 ClickHouse Keeper가 조정합니다. 이 설정 파일은 호스트명과 포트 번호를 사용해 ClickHouse Keeper 노드를 식별합니다.

* 호스트명을 Keeper 호스트에 맞게 수정하세요

```xml title=/etc/clickhouse-server/config.d/use-keeper.xml theme={null}
<clickhouse>
    <zookeeper>
        <node index="1">
            <host>keepernode1.us-east1-b.c.clickhousegcs-374921.internal</host>
            <port>9181</port>
        </node>
        <node index="2">
            <host>keepernode2.us-east4-c.c.clickhousegcs-374921.internal</host>
            <port>9181</port>
        </node>
        <node index="3">
            <host>keepernode3.us-east5-a.c.clickhousegcs-374921.internal</host>
            <port>9181</port>
        </node>
    </zookeeper>
</clickhouse>
```

<div id="remote-clickhouse-servers">
  #### 원격 ClickHouse 서버
</div>

이 파일은 클러스터에 있는 각 ClickHouse 서버의 호스트명과 포트를 설정합니다. 기본 설정 파일에는 예시 클러스터 정의가 포함되어 있으므로, 완전히 구성된 클러스터만 표시하려면 `remote_servers` 항목에 `replace="true"` 태그를 추가합니다. 이렇게 하면 이 구성이 기본 구성과 머지될 때 `remote_servers` 섹션에 내용을 추가하지 않고 해당 섹션을 대체합니다.

* 파일에서 호스트명을 알맞게 수정하고, 해당 호스트명이 ClickHouse 서버 노드에서 이름 해석되는지 확인하세요

```xml title=/etc/clickhouse-server/config.d/remote-servers.xml theme={null}
<clickhouse>
    <remote_servers replace="true">
        <cluster_1S_2R>
            <shard>
                <replica>
                    <host>chnode1.us-east1-b.c.clickhousegcs-374921.internal</host>
                    <port>9000</port>
                </replica>
                <replica>
                    <host>chnode2.us-east4-c.c.clickhousegcs-374921.internal</host>
                    <port>9000</port>
                </replica>
            </shard>
        </cluster_1S_2R>
    </remote_servers>
</clickhouse>
```

<div id="replica-identification">
  #### 레플리카 식별
</div>

이 파일은 ClickHouse Keeper 경로와 관련된 설정을 구성합니다. 구체적으로는 데이터가 어느 레플리카에 속하는지 식별하는 데 사용되는 매크로를 설정합니다. 한 server에서는 레플리카를 `replica_1`로 지정하고, 다른 server에서는 `replica_2`로 지정해야 합니다. 이름은 변경할 수 있습니다. 예를 들어 한 레플리카가 South Carolina에 저장되고 다른 레플리카가 Northern Virginia에 저장되는 경우, 값은 `carolina`와 `virginia`로 지정할 수 있습니다. 각 머신에서 서로 다른 값만 사용하도록 하십시오.

```xml title=/etc/clickhouse-server/config.d/macros.xml highlight={8} theme={null}
<clickhouse>
    <distributed_ddl>
            <path>/clickhouse/task_queue/ddl</path>
    </distributed_ddl>
    <macros>
        <cluster>cluster_1S_2R</cluster>
        <shard>1</shard>
        <replica>replica_1</replica>
    </macros>
</clickhouse>
```

<div id="storage-in-gcs">
  #### GCS 스토리지
</div>

ClickHouse 스토리지 구성에는 `disks`와 `policies`가 포함됩니다. 아래에서 구성하는 디스크의 이름은 `gcs`이고, `type`은 `s3`입니다. `type`이 `s3`인 이유는 ClickHouse가 GCS 버킷을 AWS S3 버킷처럼 액세스하기 때문입니다. 이 구성은 각 ClickHouse 서버 노드에 하나씩, 총 2개가 필요합니다.

아래 구성에서는 다음 치환값을 적용해야 합니다.

다음 치환값은 두 ClickHouse 서버 노드마다 서로 다릅니다.

* `REPLICA 1 BUCKET`은 서버와 동일한 리전(Region)에 있는 버킷 이름으로 설정해야 합니다
* `REPLICA 1 FOLDER`는 한 서버에서는 `replica_1`로, 다른 서버에서는 `replica_2`로 변경해야 합니다

다음 치환값은 두 노드에 공통으로 적용됩니다.

* `access_key_id`는 앞서 생성한 HMAC Key로 설정해야 합니다
* `secret_access_key`는 앞서 생성한 HMAC Secret으로 설정해야 합니다

```xml title=/etc/clickhouse-server/config.d/storage.xml theme={null}
<clickhouse>
    <storage_configuration>
        <disks>
            <gcs>
                <support_batch_delete>true</support_batch_delete>
                <type>s3</type>
                <endpoint>https://storage.googleapis.com/REPLICA 1 BUCKET/REPLICA 1 FOLDER/</endpoint>
                <access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
                <secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
                <metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
            </gcs>
            <cache>
                <type>cache</type>
                <disk>gcs</disk>
                <path>/var/lib/clickhouse/disks/gcs_cache/</path>
                <max_size>10Gi</max_size>
            </cache>
        </disks>
        <policies>
            <gcs_main>
                <volumes>
                    <main>
                        <disk>gcs</disk>
                    </main>
                </volumes>
            </gcs_main>
        </policies>
    </storage_configuration>
</clickhouse>
```

<div id="start-clickhouse-keeper">
  ### ClickHouse Keeper 시작
</div>

예를 들어, 사용 중인 운영 체제에 맞는 다음 명령을 사용하십시오:

```bash theme={null}
sudo systemctl enable clickhouse-keeper
sudo systemctl start clickhouse-keeper
sudo systemctl status clickhouse-keeper
```

<div id="check-clickhouse-keeper-status">
  #### ClickHouse Keeper 상태 확인
</div>

`netcat`을 사용해 ClickHouse Keeper에 명령을 전송합니다. 예를 들어 `mntr` 명령은 ClickHouse Keeper 클러스터의 상태를 반환합니다. 각 Keeper 노드에서 이 명령을 실행하면 하나는 리더이고 나머지 두 개는 팔로워임을 확인할 수 있습니다:

```bash theme={null}
echo mntr | nc localhost 9181
```

```response highlight={7-9,18-19} theme={null}
zk_version      v22.7.2.15-stable-f843089624e8dd3ff7927b8a125cf3a7a769c069
zk_avg_latency  0
zk_max_latency  11
zk_min_latency  0
zk_packets_received     1783
zk_packets_sent 1783
zk_num_alive_connections        2
zk_outstanding_requests 0
zk_server_state leader
zk_znode_count  135
zk_watch_count  8
zk_ephemerals_count     3
zk_approximate_data_size        42533
zk_key_arena_size       28672
zk_latest_snapshot_size 0
zk_open_file_descriptor_count   182
zk_max_file_descriptor_count    18446744073709551615
zk_followers    2
zk_synced_followers     2
```

<div id="start-clickhouse-server">
  ### ClickHouse 서버 시작
</div>

`chnode1` 및 `chnode`에서 다음을 실행하세요:

```bash theme={null}
sudo service clickhouse-server start
```

```bash theme={null}
sudo service clickhouse-server status
```

<div id="verification">
  ### 확인
</div>

<div id="verify-disk-configuration">
  #### 디스크 구성을 확인하세요
</div>

`system.disks`에는 각 디스크에 대한 레코드가 있어야 합니다.

* default
* gcs
* cache

```sql theme={null}
SELECT *
FROM system.disks
FORMAT Vertical
```

```response theme={null}
행 1:
──────
name:             cache
path:             /var/lib/clickhouse/disks/gcs/
free_space:       18446744073709551615
total_space:      18446744073709551615
unreserved_space: 18446744073709551615
keep_free_space:  0
type:             s3
is_encrypted:     0
is_read_only:     0
is_write_once:    0
is_remote:        1
is_broken:        0
cache_path:       /var/lib/clickhouse/disks/gcs_cache/

행 2:
──────
name:             default
path:             /var/lib/clickhouse/
free_space:       6555529216
total_space:      10331889664
unreserved_space: 6555529216
keep_free_space:  0
type:             local
is_encrypted:     0
is_read_only:     0
is_write_once:    0
is_remote:        0
is_broken:        0
cache_path:

행 3:
──────
name:             gcs
path:             /var/lib/clickhouse/disks/gcs/
free_space:       18446744073709551615
total_space:      18446744073709551615
unreserved_space: 18446744073709551615
keep_free_space:  0
type:             s3
is_encrypted:     0
is_read_only:     0
is_write_once:    0
is_remote:        1
is_broken:        0
cache_path:

3 rows in set. Elapsed: 0.002 sec.
```

<div id="verify-that-tables-created-on-the-cluster-are-created-on-both-nodes">
  #### 클러스터에서 생성한 테이블이 두 노드 모두에 생성되었는지 확인
</div>

```sql highlight={1,18} theme={null}
create table trips on cluster 'cluster_1S_2R' (
 `trip_id` UInt32,
 `pickup_date` Date,
 `pickup_datetime` DateTime,
 `dropoff_datetime` DateTime,
 `pickup_longitude` Float64,
 `pickup_latitude` Float64,
 `dropoff_longitude` Float64,
 `dropoff_latitude` Float64,
 `passenger_count` UInt8,
 `trip_distance` Float64,
 `tip_amount` Float32,
 `total_amount` Float32,
 `payment_type` Enum8('UNK' = 0, 'CSH' = 1, 'CRE' = 2, 'NOC' = 3, 'DIS' = 4))
ENGINE = ReplicatedMergeTree
PARTITION BY toYYYYMM(pickup_date)
ORDER BY pickup_datetime
SETTINGS storage_policy='gcs_main'
```

```response theme={null}
┌─host───────────────────────────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode2.us-east4-c.c.gcsqa-375100.internal │ 9000 │      0 │       │                   1 │                1 │
└────────────────────────────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
┌─host───────────────────────────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode1.us-east1-b.c.gcsqa-375100.internal │ 9000 │      0 │       │                   0 │                0 │
└────────────────────────────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘

2 rows in set. Elapsed: 0.641 sec.
```

<div id="verify-that-data-can-be-inserted">
  #### 데이터를 삽입할 수 있는지 확인
</div>

```sql theme={null}
INSERT INTO trips SELECT
    trip_id,
    pickup_date,
    pickup_datetime,
    dropoff_datetime,
    pickup_longitude,
    pickup_latitude,
    dropoff_longitude,
    dropoff_latitude,
    passenger_count,
    trip_distance,
    tip_amount,
    total_amount,
    payment_type
FROM s3('https://ch-nyc-taxi.s3.eu-west-3.amazonaws.com/tsv/trips_{0..9}.tsv.gz', 'TabSeparatedWithNames')
LIMIT 1000000
```

<div id="verify-that-the-storage-policy-gcs_main-is-used-for-the-table">
  #### 테이블에 `gcs_main` 스토리지 정책이 사용되는지 확인합니다.
</div>

```sql theme={null}
SELECT
    engine,
    data_paths,
    metadata_path,
    storage_policy,
    formatReadableSize(total_bytes)
FROM system.tables
WHERE name = 'trips'
FORMAT Vertical
```

```response theme={null}
Row 1:
──────
engine:                          ReplicatedMergeTree
data_paths:                      ['/var/lib/clickhouse/disks/gcs/store/631/6315b109-d639-4214-a1e7-afbd98f39727/']
metadata_path:                   /var/lib/clickhouse/store/e0f/e0f3e248-7996-44d4-853e-0384e153b740/trips.sql
storage_policy:                  gcs_main
formatReadableSize(total_bytes): 36.42 MiB

1 row in set. Elapsed: 0.002 sec.
```

<div id="verify-in-google-cloud-console">
  #### Google Cloud 콘솔에서 확인
</div>

버킷을 보면 `storage.xml` 설정 파일에서 사용한 이름의 폴더가 각 버킷에 생성된 것을 확인할 수 있습니다. 폴더를 펼치면 데이터 파티션을 나타내는 여러 파일이 표시됩니다.

<div id="bucket-for-replica-one">
  #### 레플리카 1용 버킷
</div>

<Image img="https://mintcdn.com/private-7c7dfe99-mintlify-fbfa8bee/ysNmqKfMa0gVKvYj/images/integrations/data-ingestion/s3/GCS-examine-bucket-1.png?fit=max&auto=format&n=ysNmqKfMa0gVKvYj&q=85&s=aae0ab212beb28ec1a27503abff20f1e" size="lg" border alt="데이터 파티션이 포함된 폴더 구조를 보여주는 Google Cloud Storage의 레플리카 1용 버킷" width="958" height="736" data-path="images/integrations/data-ingestion/s3/GCS-examine-bucket-1.png" />

<div id="bucket-for-replica-two">
  #### 레플리카 2용 버킷
</div>

<Image img="https://mintcdn.com/private-7c7dfe99-mintlify-fbfa8bee/5u7Mhe0xzzPTUaXM/images/integrations/data-ingestion/s3/GCS-examine-bucket-2.png?fit=max&auto=format&n=5u7Mhe0xzzPTUaXM&q=85&s=2bd6dabb699bd88ded113cc554f6888b" size="lg" border alt="데이터 파티션이 있는 폴더 구조를 보여주는 Google Cloud Storage의 레플리카 2 버킷" width="958" height="736" data-path="images/integrations/data-ingestion/s3/GCS-examine-bucket-2.png" />
