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

> ClickHouse와 Amazon Glue 통합

# Amazon Glue를 ClickHouse 및 Spark와 통합

export const ClickHouseSupportedBadge = () => {
  return <div className="ClickHouseSupportedBadge">
            <div className="ClickHouseSupportedIcon">
                <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M1.30762 1.39073C1.30762 1.3103 1.37465 1.22986 1.46849 1.22986H2.64824C2.72868 1.22986 2.80912 1.29689 2.80912 1.39073V14.4886C2.80912 14.5691 2.74209 14.6495 2.64824 14.6495H1.46849C1.38805 14.6495 1.30762 14.5825 1.30762 14.4886V1.39073Z" fill="currentColor" />
                    <path d="M4.2832 1.39073C4.2832 1.3103 4.35023 1.22986 4.44408 1.22986H5.62383C5.70427 1.22986 5.7847 1.29689 5.7847 1.39073V14.4886C5.7847 14.5691 5.71767 14.6495 5.62383 14.6495H4.44408C4.36364 14.6495 4.2832 14.5825 4.2832 14.4886V1.39073Z" fill="currentColor" />
                    <path d="M7.25977 1.39073C7.25977 1.3103 7.3268 1.22986 7.42064 1.22986H8.60039C8.68083 1.22986 8.76127 1.29689 8.76127 1.39073V14.4886C8.76127 14.5691 8.69423 14.6495 8.60039 14.6495H7.42064C7.3402 14.6495 7.25977 14.5825 7.25977 14.4886V1.39073Z" fill="currentColor" />
                    <path d="M10.2354 1.39073C10.2354 1.3103 10.3024 1.22986 10.3962 1.22986H11.576C11.6564 1.22986 11.7369 1.29689 11.7369 1.39073V14.4886C11.7369 14.5691 11.6698 14.6495 11.576 14.6495H10.3962C10.3158 14.6495 10.2354 14.5825 10.2354 14.4886V1.39073Z" fill="currentColor" />
                    <path d="M13.2256 6.6057C13.2256 6.52526 13.2926 6.44482 13.3865 6.44482H14.5662C14.6466 6.44482 14.7271 6.51186 14.7271 6.6057V9.27354C14.7271 9.35398 14.6601 9.43442 14.5662 9.43442H13.3865C13.306 9.43442 13.2256 9.36739 13.2256 9.27354V6.6057Z" fill="currentColor" />
                </svg>
            </div>
            ClickHouse 지원
        </div>;
};

export const Image = ({img, alt, size = "lg"}) => {
  const normalizedSize = ["sm", "md", "lg"].includes(size) ? size : "lg";
  return <div className={`ch-image-${normalizedSize}`}>
      <Frame>
        <img src={img} alt={alt} />
      </Frame>
    </div>;
};

<ClickHouseSupportedBadge />

[Amazon Glue](https://aws.amazon.com/glue/)는 Amazon Web Services(AWS)에서 제공하는 완전 관리형 서버리스 데이터 통합 서비스입니다. 분석, 머신 러닝, 애플리케이션 개발에 사용할 데이터를 탐색하고, 준비하고, 변환하는 과정을 간소화합니다.

<div id="installation">
  ## 설치
</div>

Glue 코드와 ClickHouse를 통합하려면 다음 방법 중 하나로 Glue에서 공식 Spark 커넥터를 사용할 수 있습니다.

* AWS Marketplace에서 ClickHouse Glue 커넥터를 설치합니다(권장).
* Spark 커넥터의 JARs를 Glue 작업에 수동으로 추가합니다.

<Tabs>
  <Tab title="AWS Marketplace">
    <Steps titleSize="h3">
      <Step title="커넥터 구독" id="subscribe-to-the-connector">
        계정에서 커넥터에 액세스하려면 AWS Marketplace에서 ClickHouse AWS Glue Connector를 구독하십시오.
      </Step>

      <Step title="필수 권한 부여" id="grant-required-permissions">
        최소 권한 [가이드](https://docs.aws.amazon.com/glue/latest/dg/getting-started-min-privs-job.html#getting-started-min-privs-connectors)에 설명된 대로, Glue 작업의 IAM role에 필요한 권한이 있는지 확인하십시오.
      </Step>

      <Step title="커넥터 활성화 및 연결 생성" id="activate-the-connector">
        구독한 후 작업 요구 사항에 맞는 Glue 버전을 선택하십시오. **Additional details** 섹션의 **Usage instructions** 아래에서 **Open Glue Studio - Add ClickHouse connector** 링크를 클릭하십시오. 그러면 주요 필드가 미리 채워진 Glue 연결 생성 페이지가 열립니다. 연결 이름을 입력한 다음 create를 누르십시오(이 단계에서는 ClickHouse 연결 세부 정보를 입력할 필요가 없습니다).

        <Image img="https://mintcdn.com/private-7c7dfe99-trino-dialect/zkBy8QRjLpx6BosZ/images/integrations/data-ingestion/aws-glue/marketplace-usage-instructions.png?fit=max&auto=format&n=zkBy8QRjLpx6BosZ&q=85&s=d7eb0a5c56bb6478043408c7f043abaf" size="md" alt="AWS Marketplace usage instructions for ClickHouse Glue connector" width="1024" height="182" data-path="images/integrations/data-ingestion/aws-glue/marketplace-usage-instructions.png" />
      </Step>

      <Step title="Glue 작업에서 사용" id="use-in-glue-job">
        Glue 작업에서 `Job details` 탭을 선택한 다음 `Advanced properties` 창을 펼치십시오. `Connections` 섹션에서 방금 생성한 연결을 선택하십시오. 커넥터가 필요한 JARs를 작업 런타임에 자동으로 주입합니다.

        <Image img="https://mintcdn.com/private-7c7dfe99-trino-dialect/zkBy8QRjLpx6BosZ/images/integrations/data-ingestion/aws-glue/notebook-connections-config.webp?fit=max&auto=format&n=zkBy8QRjLpx6BosZ&q=85&s=37ac0c0187108958739175644e161f4a" size="md" alt="Glue Notebook connections config" force="true" width="877" height="742" data-path="images/integrations/data-ingestion/aws-glue/notebook-connections-config.webp" />

        <Note>
          Glue 작업 구성과 일치하는 커넥터 버전을 선택해야 합니다.

          * **Glue 4**: Spark 3.3, Scala 2, Python 3
          * **Glue 5**: Spark 3.5, Scala 2, Python 3
        </Note>
      </Step>
    </Steps>
  </Tab>

  <Tab title="수동 설치">
    필요한 JARs를 수동으로 추가하려면 다음 단계를 따르십시오.

    <Steps titleSize="h3">
      <Step title="커넥터 JAR 업로드">
        최신 Spark 커넥터 JAR(`clickhouse-spark-runtime-3.X_2.X-0.10.X.jar`)을 S3 버킷에 업로드합니다.
      </Step>

      <Step title="S3 버킷에 대한 액세스 권한 부여">
        Glue 작업이 이 버킷에 액세스할 수 있는지 확인합니다.
      </Step>

      <Step title="종속 JAR 경로 구성">
        `Job details` 탭에서 아래로 스크롤하여 `Advanced properties` 드롭다운을 펼친 다음 `Dependent JARs path`에 JAR 경로를 입력합니다.

        <Image img="https://mintcdn.com/private-7c7dfe99-trino-dialect/zkBy8QRjLpx6BosZ/images/integrations/data-ingestion/aws-glue/dependent_jars_path_option.webp?fit=max&auto=format&n=zkBy8QRjLpx6BosZ&q=85&s=b9e7143669a8e5d7ffa10ea0e105307c" size="md" alt="Glue Notebook JAR path options" force="true" width="954" height="753" data-path="images/integrations/data-ingestion/aws-glue/dependent_jars_path_option.webp" />
      </Step>
    </Steps>
  </Tab>
</Tabs>

<div id="secrets-manager">
  ## 자격 증명에 AWS Secrets Manager 사용
</div>

작업에 ClickHouse 사용자와 비밀번호를 하드코딩하는 대신, [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/)에 저장하고 Glue 연결 또는 작업 스크립트에서 해당 시크릿을 참조하십시오. 런타임에 Glue는 시크릿을 가져와 해당 key-value 쌍을 커넥터의 연결 옵션에 병합합니다.

<div id="create-secret">
  ### 시크릿 생성
</div>

AWS Secrets Manager에서 **Other type of secret** 유형의 시크릿을 생성하고, 키가 커넥터의 옵션 이름과 일치하도록 key-value 쌍을 설정하십시오:

| Key        | Value             |
| ---------- | ----------------- |
| `user`     | ClickHouse 사용자 이름 |
| `password` | ClickHouse 비밀번호   |

시크릿에 추가한 모든 키는 커넥터로 전달되므로, 코드에 포함하지 않으려면 `host`, `database` 또는 다른 옵션도 여기에 저장할 수 있습니다.

<div id="reference-secret">
  ### 시크릿 참조
</div>

작업에 시크릿을 연결하는 방법은 두 가지입니다.

**옵션 1: Glue 연결에 시크릿을 연결합니다.** Glue Studio에서 ClickHouse 연결을 생성하거나 편집할 때 **AWS secret** 필드에 시크릿 이름을 설정하십시오. 이 연결을 사용하는 모든 작업은 시크릿을 자동으로 확인하므로 코드를 변경할 필요가 없습니다.

**옵션 2: connection options에 `secretId`를 전달합니다.** 시크릿이 연결에 연결되어 있지 않을 때 이 방법을 사용하십시오. `connectionName`과 함께 `secretId`를 추가하십시오.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    source = glueContext.create_dynamic_frame.from_options(
        connection_type="marketplace.spark",
        connection_options={
            "connectionName": "<your-connection-name>",
            "secretId": "clickhouse/glue/credentials",
            "database": "default",
            "table": "example_table"
        },
        transformation_ctx="clickhouse_source"
    )
    ```
  </Tab>

  <Tab title="Scala">
    ```scala theme={null}
    val source = glueContext.getSource(
      connectionType = "marketplace.spark",
      connectionOptions = JsonOptions(Map(
        "connectionName" -> "<your-connection-name>",
        "secretId" -> "clickhouse/glue/credentials",
        "database" -> "default",
        "table" -> "example_table"
      )),
      transformationContext = "clickhouseSource"
    )
    ```
  </Tab>
</Tabs>

시크릿의 `user` 및 `password` 키는 런타임에 커넥터 옵션에 병합되므로 스크립트에서 이를 직접 읽을 필요가 없습니다.

<div id="example">
  ## 예시
</div>

아래 예시에서는 `marketplace.spark`를 사용하며, 커넥터는 `connectionName`으로 참조합니다. 커넥터를 수동으로 설치한 경우(수동 설치 탭)에는 대신 `connection_type="custom.spark"`를 사용하고 `className`, `host`, `http_port`, `user`, `password`를 옵션에 직접 전달하십시오.

AWS 시크릿을 연결 자체에 연결한 경우([자격 증명에 AWS Secrets Manager 사용](#secrets-manager)의 옵션 1)에는 옵션에서 `secretId`를 제거하십시오. 그러면 Glue가 연결에서 자격 증명을 자동으로 가져옵니다.

<Tabs>
  <Tab title="비주얼 에디터">
    ClickHouse 커넥터는 Glue Studio 비주얼 에디터에서 소스 또는 대상으로 사용할 수 있습니다. ClickHouse Spark Connector 컴포넌트를 캔버스로 끌어와 데이터 파이프라인에 연결하면 됩니다.

    <Image img="https://mintcdn.com/private-7c7dfe99-trino-dialect/zkBy8QRjLpx6BosZ/images/integrations/data-ingestion/aws-glue/glue-studio-visual-editor.png?fit=max&auto=format&n=zkBy8QRjLpx6BosZ&q=85&s=7cd32932dec2893a03442470e201b034" size="md" alt="ClickHouse 커넥터가 있는 Glue Studio 비주얼 에디터" width="1024" height="645" data-path="images/integrations/data-ingestion/aws-glue/glue-studio-visual-editor.png" />
  </Tab>

  <Tab title="Scala">
    ```java theme={null}
    import com.amazonaws.services.glue.GlueContext
    import com.amazonaws.services.glue.util.{GlueArgParser, Job, JsonOptions}
    import org.apache.spark.SparkContext
    import scala.collection.JavaConverters._

    object ClickHouseGlueExample {
      def main(sysArgs: Array[String]): Unit = {
        val args = GlueArgParser.getResolvedOptions(sysArgs, Seq("JOB_NAME").toArray)

        val sc = new SparkContext()
        val glueContext = new GlueContext(sc)
        Job.init(args("JOB_NAME"), glueContext, args.asJava)

        val readOptions = JsonOptions(Map(
          "connectionName" -> "<your-connection-name>",
          "secretId" -> "clickhouse/glue/credentials",
          "database" -> "default",
          "table" -> "example_table"
        ))

        val source = glueContext.getSource(
          connectionType = "marketplace.spark",
          connectionOptions = readOptions,
          transformationContext = "clickhouseSource"
        )
        val dyf = source.getDynamicFrame()

        val writeOptions = JsonOptions(Map(
          "connectionName" -> "<your-connection-name>",
          "secretId" -> "clickhouse/glue/credentials",
          "database" -> "default",
          "table" -> "target_table"
        ))

        glueContext.getSink(
          connectionType = "marketplace.spark",
          connectionOptions = writeOptions
        ).writeDynamicFrame(dyf)

        Job.commit()
      }
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import sys
    from awsglue.utils import getResolvedOptions
    from pyspark.context import SparkContext
    from awsglue.context import GlueContext
    from awsglue.job import Job

    args = getResolvedOptions(sys.argv, ['JOB_NAME'])

    sc = SparkContext()
    glueContext = GlueContext(sc)
    logger = glueContext.get_logger()
    job = Job(glueContext)
    job.init(args['JOB_NAME'], args)

    read_options = {
        "connectionName": "<your-connection-name>",
        "secretId": "clickhouse/glue/credentials",
        "database": "default",
        "table": "example_table"
    }

    source = glueContext.create_dynamic_frame.from_options(
        connection_type="marketplace.spark",
        connection_options=read_options,
        transformation_ctx="clickhouse_source"
    )
    dyf = source

    logger.info(f"Read {dyf.count()} rows from ClickHouse")

    write_options = {
        "connectionName": "<your-connection-name>",
        "secretId": "clickhouse/glue/credentials",
        "database": "default",
        "table": "target_table"
    }

    glueContext.write_dynamic_frame.from_options(
        frame=dyf,
        connection_type="marketplace.spark",
        connection_options=write_options,
        transformation_ctx="clickhouse_sink"
    )

    job.commit()
    ```
  </Tab>
</Tabs>

자세한 내용은 [Spark 문서](/ko/integrations/connectors/data-ingestion/apache-spark)를 참조하십시오.
