> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 存储与计算分离

> 本指南将介绍如何使用 ClickHouse 和 S3 实现存储与计算分离的架构。

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>;
};

<div id="overview">
  ## 概述
</div>

本指南将介绍如何使用 ClickHouse 和 S3 实现存储与计算分离的架构。

存储与计算分离意味着计算资源和存储资源是分别独立管理的。在 ClickHouse 中，这种方式可以带来更好的可扩展性、更高的成本效益以及更强的灵活性。您可以根据需要分别扩展存储资源和计算资源，从而优化性能和成本。

基于 S3 的 ClickHouse 特别适用于对“冷”数据查询性能要求不高的场景。ClickHouse 支持通过 `S3BackedMergeTree` 将 S3 用作 `MergeTree` 引擎的存储层。这种表引擎使您能够利用 S3 在可扩展性和成本方面的优势，同时保持 `MergeTree` 引擎的插入和查询性能。

请注意，与标准 ClickHouse 部署相比，实现和管理存储与计算分离架构更加复杂。虽然自管理 ClickHouse 支持本指南中介绍的存储与计算分离方案，但我们建议使用 [ClickHouse Cloud](https://clickhouse.com/cloud)。借助 [`SharedMergeTree` 表引擎](/docs/zh/products/cloud/features/infrastructure/shared-merge-tree)，您无需额外配置即可在这种架构下使用 ClickHouse。

*本指南假设您使用的是 22.8 或更高版本的 ClickHouse。*

<Warning>
  请勿配置任何 AWS/GCS 生命周期策略。这种做法不受支持，并且可能导致表损坏。
</Warning>

<Steps>
  <Step title="将 S3 用作 ClickHouse 的磁盘" id="1-use-s3-as-a-clickhouse-disk">
    ### 创建磁盘

    在 ClickHouse 的 `config.d` 目录中新建一个文件，用于存放存储配置：

    ```bash theme={null}
    vim /etc/clickhouse-server/config.d/storage_config.xml
    ```

    将以下 XML 复制到新建的文件中，并将 `BUCKET`、`ACCESS_KEY_ID` 和 `SECRET_ACCESS_KEY` 替换为你希望用于存储数据的 AWS 存储桶详细信息：

    ```xml theme={null}
    <clickhouse>
      <storage_configuration>
        <disks>
          <s3_disk>
            <type>s3</type>
            <endpoint>$BUCKET</endpoint>
            <access_key_id>$ACCESS_KEY_ID</access_key_id>
            <secret_access_key>$SECRET_ACCESS_KEY</secret_access_key>
            <metadata_path>/var/lib/clickhouse/disks/s3_disk/</metadata_path>
          </s3_disk>
          <s3_cache>
            <type>cache</type>
            <disk>s3_disk</disk>
            <path>/var/lib/clickhouse/disks/s3_cache/</path>
            <max_size>10Gi</max_size>
          </s3_cache>
        </disks>
        <policies>
          <s3_main>
            <volumes>
              <main>
                <disk>s3_disk</disk>
              </main>
            </volumes>
          </s3_main>
        </policies>
      </storage_configuration>
    </clickhouse>
    ```

    如果你需要进一步指定 S3 磁盘的设置，例如指定 `region` 或发送自定义 HTTP `header`，可以在[此处](/docs/zh/reference/engines/table-engines/mergetree-family/mergetree#table_engine-mergetree-s3)查看相关设置列表。

    你也可以将 `access_key_id` 和 `secret_access_key` 替换为以下内容，这会尝试从环境变量和 Amazon EC2 元数据中获取凭证：

    ```bash theme={null}
    <use_environment_credentials>true</use_environment_credentials>
    ```

    创建好配置文件后，您需要将该文件的属主和属组更改为 clickhouse 用户和组：

    ```bash theme={null}
    chown clickhouse:clickhouse /etc/clickhouse-server/config.d/storage_config.xml
    ```

    现在，您可以重启 ClickHouse 服务器，以使更改生效：

    ```bash theme={null}
    service clickhouse-server restart
    ```
  </Step>

  <Step title="创建基于 S3 的表" id="2-create-a-table-backed-by-s3">
    为了测试 S3 磁盘是否已正确配置，我们可以尝试创建一个表并进行查询。

    创建一个表，并指定新的 S3 存储策略：

    ```sql theme={null}
    CREATE TABLE my_s3_table
      (
        `id` UInt64,
        `column1` String
      )
    ENGINE = MergeTree
    ORDER BY id
    SETTINGS storage_policy = 's3_main';
    ```

    请注意，我们不必将引擎指定为 `S3BackedMergeTree`。如果 ClickHouse 检测到该表使用 S3 作为存储，它会在内部自动转换引擎类型。

    确认该表已使用正确的策略创建：

    ```sql theme={null}
    SHOW CREATE TABLE my_s3_table;
    ```

    你应该会看到以下结果：

    ```response theme={null}
    ┌─statement────────────────────────────────────────────────────
    │ CREATE TABLE default.my_s3_table
    (
      `id` UInt64,
      `column1` String
    )
    ENGINE = MergeTree
    ORDER BY id
    SETTINGS storage_policy = 's3_main', index_granularity = 8192
    └──────────────────────────────────────────────────────────────
    ```

    现在，向新表中插入一些行：

    ```sql theme={null}
    INSERT INTO my_s3_table (id, column1)
      VALUES (1, 'abc'), (2, 'xyz');
    ```

    让我们验证这些行是否已插入：

    ```sql theme={null}
    SELECT * FROM my_s3_table;
    ```

    ```response theme={null}
    ┌─id─┬─column1─┐
    │  1 │ abc     │
    │  2 │ xyz     │
    └────┴─────────┘

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

    在 AWS 控制台中，如果你的数据已成功写入 S3，你应该会看到 ClickHouse 已在你指定的存储桶中创建了新文件。

    如果一切都正常，你现在已经在使用采用存储与计算分离架构的 ClickHouse！

    <Image img="https://mintcdn.com/private-7c7dfe99/k4wNHsd_gyvah7Fr/images/guides/s3_bucket_example.webp?fit=max&auto=format&n=k4wNHsd_gyvah7Fr&q=85&s=5125bc42e40bfb41790536f985463ff6" size="md" alt="采用存储与计算分离的 S3 存储桶示例" border width="1208" height="736" data-path="images/guides/s3_bucket_example.webp" />
  </Step>

  <Step title="配置复制以实现容错（可选）" id="3-implementing-replication-for-fault-tolerance-optional">
    <Warning>
      不要配置任何 AWS/GCS 生命周期策略。这不受支持，且可能导致表损坏。
    </Warning>

    为实现容错，您可以使用分布在多个 AWS 区域的多个 ClickHouse 服务器节点，并为每个节点配置一个 S3 存储桶。

    可以使用 `ReplicatedMergeTree` 表引擎来实现 S3 磁盘的复制。有关详细信息，请参阅以下指南：

    * [使用 S3 对象存储在两个 AWS 区域之间复制单个分片](/docs/zh/integrations/connectors/data-ingestion/AWS/integrating-s3-with-clickhouse#s3-multi-region).
  </Step>
</Steps>

<div id="further-reading">
  ## 延伸阅读
</div>

* [SharedMergeTree 表引擎](/docs/zh/products/cloud/features/infrastructure/shared-merge-tree)
* [SharedMergeTree 发布博文](https://clickhouse.com/blog/clickhouse-cloud-boosts-performance-with-sharedmergetree-and-lightweight-updates)
