> ## 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 Connector：

* 从 AWS Marketplace 安装 ClickHouse Glue 连接器 (推荐) 。
* 手动将 Spark Connector 的 JAR 添加到你的 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">
        确保你的 Glue 作业所使用的 IAM role 具备所需权限，具体请参见最低权限[指南](https://docs.aws.amazon.com/glue/latest/dg/getting-started-min-privs-job.html#getting-started-min-privs-connectors)。
      </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 中 ClickHouse Glue 连接器的使用说明" 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` 部分中，选择你刚刚创建的连接。该连接器会自动将所需 JAR 注入作业运行时。

        <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 连接配置" 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="手动安装">
    如需手动添加所需的 JAR，请按以下步骤操作：

    <Steps titleSize="h3">
      <Step title="上传连接器 JAR">
        将最新的 Spark Connector JAR (`clickhouse-spark-runtime-3.X_2.X-0.10.X.jar`) 上传到一个 S3 bucket。
      </Step>

      <Step title="授予对 S3 bucket 的访问权限">
        确保 Glue 作业可以访问该 bucket。
      </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 路径选项" 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 会拉取该密钥，并将其中的键值对合并到连接器的连接选项中。

<div id="create-secret">
  ### 创建密钥
</div>

在 AWS Secrets Manager 中，创建一个类型为 **其他类型的密钥** 的密钥，并添加键值对，其中键名需与 connector 的选项名称一致：

| 键          | 值                 |
| ---------- | ----------------- |
| `user`     | 你的 ClickHouse 用户名 |
| `password` | 你的 ClickHouse 密码  |

你在该密钥中放入的任何键都会被转发给 connector，因此如果你想避免将它们写在代码中，也可以在其中存储 `host`、`database` 或任何其他选项。

<div id="reference-secret">
  ### 引用密钥
</div>

有两种方式可让作业使用该密钥。

**选项 1：将其附加到 Glue 连接。** 在 Glue Studio 中创建或编辑 ClickHouse 连接时，将 **AWS 密钥** 字段设置为该密钥的名称。任何使用此连接的作业都会自动解析该密钥，无需修改代码。

**选项 2：在连接选项中传入 `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="可视化编辑器">
    你可以在 Glue Studio 可视化编辑器中将 ClickHouse 连接器用作数据源或目标端。只需将 ClickHouse Spark 连接器组件拖到画布上，然后连接到你的数据管道即可。

    <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 文档](/zh/integrations/connectors/data-ingestion/apache-spark)。
