メインコンテンツまでスキップ
メインコンテンツまでスキップ

S3 テーブルエンジン

このエンジンは、Amazon S3 エコシステムと統合を提供します。このエンジンは、HDFS エンジンに似ていますが、S3 固有の機能を提供します。

CREATE TABLE s3_engine_table (name String, value UInt32)
    ENGINE=S3('https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/test-data.csv.gz', 'CSV', 'gzip')
    SETTINGS input_format_with_names_use_header = 0;

INSERT INTO s3_engine_table VALUES ('one', 1), ('two', 2), ('three', 3);

SELECT * FROM s3_engine_table LIMIT 2;
┌─name─┬─value─┐
│ one  │     1 │
│ two  │     2 │
└──────┴───────┘

テーブルの作成

CREATE TABLE s3_engine_table (name String, value UInt32)
    ENGINE = S3(path [, NOSIGN | aws_access_key_id, aws_secret_access_key,] format, [compression], [partition_strategy], [partition_columns_in_data_file])
    [PARTITION BY expr]
    [SETTINGS ...]

エンジンパラメータ

  • path — ファイルへのパスを含むバケット URL。読み取り専用モードで以下のワイルドカードをサポートします: *, **, ?, {abc,def} および {N..M} (ここで NM は数字、'abc''def' は文字列)。詳細については 下記 を参照してください。
  • NOSIGN - このキーワードが資格情報の代わりに指定された場合、すべてのリクエストは署名されません。
  • format — ファイルの format
  • aws_access_key_id, aws_secret_access_key - AWS アカウントユーザーの長期資格情報。これを使用してリクエストを認証できます。パラメータはオプションです。資格情報が指定されていない場合、設定ファイルから使用されます。詳細については Using S3 for Data Storage を参照してください。
  • compression — 圧縮タイプ。サポートされている値: none, gzip/gz, brotli/br, xz/LZMA, zstd/zst。パラメータはオプションです。デフォルトでは、ファイル拡張子によって圧縮が自動的に検出されます。
  • partition_strategy – オプション: WILDCARD または HIVEWILDCARD では、パスに {_partition_id} が必要で、これがパーティションキーに置き換えられます。HIVE ではワイルドカードが許可されず、パスはテーブルのルートと見なされ、Hiveスタイルのパーティショニングディレクトリが生成され、ファイル名はスノーフレークID、ファイル形式は拡張子として使用されます。デフォルトは WILDCARD です。
  • partition_columns_in_data_file - HIVE パーティション戦略でのみ使用されます。ClickHouse にデータファイル内にパーティションカラムが書き込まれていることを期待するかどうかを示します。デフォルトは false です。
  • storage_class_name - オプション: STANDARD または INTELLIGENT_TIERINGAWS S3 Intelligent Tiering を指定できます。

データキャッシュ

S3 テーブルエンジンは、ローカルディスクにデータキャッシュをサポートします。 この セクション でファイルシステムキャッシュの設定オプションと使用法を確認してください。 キャッシュは、ストレージオブジェクトのパスと ETag に基づいて作成されるため、ClickHouse は古いキャッシュバージョンを読み取ることはありません。

キャッシングを有効にするには、設定 filesystem_cache_name = '<name>'enable_filesystem_cache = 1 を使用します。

SELECT *
FROM s3('http://minio:10000/clickhouse//test_3.csv', 'minioadmin', 'minioadminpassword', 'CSV')
SETTINGS filesystem_cache_name = 'cache_for_s3', enable_filesystem_cache = 1;

設定ファイルでキャッシュを定義する方法は2つあります。

  1. ClickHouse 設定ファイルに次のセクションを追加してください:
<clickhouse>
    <filesystem_caches>
        <cache_for_s3>
            <path>path to cache directory</path>
            <max_size>10Gi</max_size>
        </cache_for_s3>
    </filesystem_caches>
</clickhouse>
  1. ClickHouseの「storage_configuration」セクションからキャッシュ設定(およびキャッシュストレージ)を再利用します。こちらで説明しています

PARTITION BY

PARTITION BY — オプションです。ほとんどの場合、パーティションキーは必要ありませんが、必要な場合でも、月ごとよりも細かいパーティションキーは一般に必要ありません。パーティショニングはクエリを高速化するものではありません(ORDER BY式と対照的)。あまり細かいパーティショニングは決して使用しないでください。クライアント識別子や名前でデータをパーティショニングしないでください(代わりに、クライアント識別子や名前をORDER BY式の最初のカラムにしてください)。

月ごとにパーティショニングするには、toYYYYMM(date_column) 式を使用します。ここで date_columnDate 型の日付を持つカラムです。ここでのパーティション名は "YYYYMM" 形式です。

パーティション戦略

WILDCARD(デフォルト): ファイルパス内の {_partition_id} ワイルドカードを実際のパーティションキーに置き換えます。読み取りはサポートされません。

HIVE は読み取りと書き込みのために hive スタイルのパーティショニングを実装します。読み取りは再帰的な glob パターンを使用して実装され、SELECT * FROM s3('table_root/**.parquet') と同等です。 書き込みは次のフォーマットを使用してファイルを生成します: <prefix>/<key1=val1/key2=val2...>/<snowflakeid>.<toLower(file_format)>.

注意: HIVE パーティション戦略を使用する場合、use_hive_partitioning 設定は効果がありません。

HIVE パーティション戦略の例:

arthur :) CREATE TABLE t_03363_parquet (year UInt16, country String, counter UInt8)
ENGINE = S3(s3_conn, filename = 't_03363_parquet', format = Parquet, partition_strategy='hive')
PARTITION BY (year, country);

arthur :) INSERT INTO t_03363_parquet VALUES
    (2022, 'USA', 1),
    (2022, 'Canada', 2),
    (2023, 'USA', 3),
    (2023, 'Mexico', 4),
    (2024, 'France', 5),
    (2024, 'Germany', 6),
    (2024, 'Germany', 7),
    (1999, 'Brazil', 8),
    (2100, 'Japan', 9),
    (2024, 'CN', 10),
    (2025, '', 11);

arthur :) select _path, * from t_03363_parquet;

    ┌─_path──────────────────────────────────────────────────────────────────────┬─year─┬─country─┬─counter─┐
 1. │ test/t_03363_parquet/year=2100/country=Japan/7329604473272971264.parquet   │ 2100 │ Japan   │       9 │
 2. │ test/t_03363_parquet/year=2024/country=France/7329604473323302912.parquet  │ 2024 │ France  │       5 │
 3. │ test/t_03363_parquet/year=2022/country=Canada/7329604473314914304.parquet  │ 2022 │ Canada  │       2 │
 4. │ test/t_03363_parquet/year=1999/country=Brazil/7329604473289748480.parquet  │ 1999 │ Brazil  │       8 │
 5. │ test/t_03363_parquet/year=2023/country=Mexico/7329604473293942784.parquet  │ 2023 │ Mexico  │       4 │
 6. │ test/t_03363_parquet/year=2023/country=USA/7329604473319108608.parquet     │ 2023 │ USA     │       3 │
 7. │ test/t_03363_parquet/year=2025/country=/7329604473327497216.parquet        │ 2025 │         │      11 │
 8. │ test/t_03363_parquet/year=2024/country=CN/7329604473310720000.parquet      │ 2024 │ CN      │      10 │
 9. │ test/t_03363_parquet/year=2022/country=USA/7329604473298137088.parquet     │ 2022 │ USA     │       1 │
10. │ test/t_03363_parquet/year=2024/country=Germany/7329604473306525696.parquet │ 2024 │ Germany │       6 │
11. │ test/t_03363_parquet/year=2024/country=Germany/7329604473306525696.parquet │ 2024 │ Germany │       7 │
    └────────────────────────────────────────────────────────────────────────────┴──────┴─────────┴─────────┘

パーティションデータのクエリ

この例では、ClickHouse と MinIO を統合する docker compose レシピ を使用しています。同じクエリを S3 で再現できるはずで、エンドポイントと認証値を置き換えれば実現できます。

ENGINE 設定内の S3 エンドポイントが、S3 オブジェクト(ファイル名)の一部としてパラメータトークン {_partition_id} を使用していることに注意してください。SELECT クエリは、これらの結果として得られたオブジェクト名(例: test_3.csv)に対して選択されます。

注記

例に示すように、パーティショニングされた S3 テーブルからのクエリは 現時点では直接サポートされていませんが、S3 テーブル関数を使用して個々のパーティションをクエリすることで実現できます。

S3 にデータをパーティショニングして書き込む主なユースケースは、別の ClickHouse システム(たとえば、オンプレミスシステムから ClickHouse Cloud への移行)にデータを転送するためです。ClickHouse データセットは非常に大きいことが多く、ネットワークの信頼性が完璧ではないため、データセットを部分的に転送することが理にかなっており、そのためパーティショニング書き込みが行われます。

テーブルを作成する

CREATE TABLE p
(
    `column1` UInt32,
    `column2` UInt32,
    `column3` UInt32
)
ENGINE = S3(
-- highlight-next-line
           'http://minio:10000/clickhouse//test_{_partition_id}.csv',
           'minioadmin',
           'minioadminpassword',
           'CSV')
PARTITION BY column3

データを挿入する

INSERT INTO p VALUES (1, 2, 3), (3, 2, 1), (78, 43, 45)

パーティション 3 から選択する

ヒント

このクエリは S3 テーブル関数を使用します

SELECT *
FROM s3('http://minio:10000/clickhouse//test_3.csv', 'minioadmin', 'minioadminpassword', 'CSV')
┌─c1─┬─c2─┬─c3─┐
│  1 │  2 │  3 │
└────┴────┴────┘

パーティション 1 から選択する

SELECT *
FROM s3('http://minio:10000/clickhouse//test_1.csv', 'minioadmin', 'minioadminpassword', 'CSV')
┌─c1─┬─c2─┬─c3─┐
│  3 │  2 │  1 │
└────┴────┴────┘

パーティション 45 から選択する

SELECT *
FROM s3('http://minio:10000/clickhouse//test_45.csv', 'minioadmin', 'minioadminpassword', 'CSV')
┌─c1─┬─c2─┬─c3─┐
│ 78 │ 43 │ 45 │
└────┴────┴────┘

制限

Select * from p を試みることは自然ですが、上記のようにこのクエリは失敗します。前述のクエリを使用してください。

SELECT * FROM p
Received exception from server (version 23.4.1):
Code: 48. DB::Exception: Received from localhost:9000. DB::Exception: Reading from a partitioned S3 storage is not implemented yet. (NOT_IMPLEMENTED)

データを挿入する

行は新しいファイルにのみ挿入できることに注意してください。マージサイクルやファイル分割操作はありません。ファイルが書き込まれると、その後の挿入は失敗します。これを避けるには、s3_truncate_on_insert および s3_create_new_file_on_insert 設定を使用できます。詳細については こちら をご覧ください。

仮想カラム

  • _path — ファイルへのパス。型: LowCardinality(String)
  • _file — ファイルの名前。型: LowCardinality(String)
  • _size — ファイルのサイズ(バイト単位)。型: Nullable(UInt64)。サイズが不明な場合、値は NULL です。
  • _time — ファイルの最終更新時刻。型: Nullable(DateTime)。時刻が不明な場合、値は NULL です。
  • _etag — ファイルの ETag。型: LowCardinality(String)。etag が不明な場合、値は NULL です。

仮想カラムに関する詳細は こちら を参照してください。

実装の詳細

  • 読み取りと書き込みは並行して行うことができます。

  • サポートされていない:

    • ALTER および SELECT...SAMPLE 操作。
    • インデックス。
    • ゼロコピー レプリケーションは可能ですが、サポートされていません。
    ゼロコピー レプリケーションは本番環境用ではありません

    ゼロコピー レプリケーションは ClickHouse バージョン 22.8 以降でデフォルトで無効です。この機能は本番使用には推奨されません。

パスにおけるワイルドカード

path 引数は、bash 風のワイルドカードを使用して複数のファイルを指定できます。処理されるには、ファイルが存在し、全体のパスパターンに一致する必要があります。ファイルのリスティングは SELECT 時に決定されます(CREATE の瞬間ではありません)。

  • */ を含む任意の数の任意の文字に置き換えられ、空の文字列も含まれます。
  • **/ を含む任意の数の任意の文字に置き換えられ、空の文字列も含まれます。
  • ? — 任意の単一文字に置き換えられます。
  • {some_string,another_string,yet_another_one} — 文字列 'some_string', 'another_string', 'yet_another_one' のいずれかに置き換えられます。
  • {N..M} — N から M までの範囲の数値に置き換えられます(境界を含む)。N と M には先頭ゼロを含むことができます。例: 000..078

{} を用いた構文は、remote テーブル関数に似ています。

注記

先頭ゼロを持つ数値範囲がファイルリスティングに含まれる場合は、各桁に対して括弧を使用するか、? を使用してください。

ワイルドカードを使用した例 1

file-000.csv, file-001.csv, ... , file-999.csv という名前のファイルを作成します:

CREATE TABLE big_table (name String, value UInt32)
    ENGINE = S3('https://clickhouse-public-datasets.s3.amazonaws.com/my-bucket/my_folder/file-{000..999}.csv', 'CSV');

ワイルドカードを使用した例 2

次の URI にいくつかの CSV 形式のファイルが S3 にあるとします:

6つのファイルすべてで構成されるテーブルを作成する方法はいくつかあります:

  1. ファイルの接尾辞の範囲を指定します:
CREATE TABLE table_with_range (name String, value UInt32)
    ENGINE = S3('https://clickhouse-public-datasets.s3.amazonaws.com/my-bucket/{some,another}_folder/some_file_{1..3}', 'CSV');
  1. some_file_ プレフィックスを持つすべてのファイルを取得します(両方のフォルダーにそのようなプレフィックスを持つ余分なファイルがないことを確認してください):
CREATE TABLE table_with_question_mark (name String, value UInt32)
    ENGINE = S3('https://clickhouse-public-datasets.s3.amazonaws.com/my-bucket/{some,another}_folder/some_file_?', 'CSV');
  1. 両方のフォルダー内のすべてのファイルを取得します(すべてのファイルは、クエリで説明された形式およびスキーマを満たす必要があります):
CREATE TABLE table_with_asterisk (name String, value UInt32)
    ENGINE = S3('https://clickhouse-public-datasets.s3.amazonaws.com/my-bucket/{some,another}_folder/*', 'CSV');

ストレージ設定

  • s3_truncate_on_insert - 挿入する前にファイルを切り捨てることを許可します。デフォルトでは無効です。
  • s3_create_new_file_on_insert - 形式にサフィックスがある場合、各挿入で新しいファイルを作成することを許可します。デフォルトでは無効です。
  • s3_skip_empty_files - 読み取り中に空のファイルをスキップすることを許可します。デフォルトでは有効です。

S3 関連の設定

以下の設定は、クエリの実行前に設定するか、設定ファイルに配置できます。

  • s3_max_single_part_upload_size — シングルパートアップロードを使用して S3 にアップロードするオブジェクトの最大サイズ。デフォルト値は 32Mb です。
  • s3_min_upload_part_sizeS3 Multipart upload 中のマルチパートアップロード中にアップロードされるパートの最小サイズ。デフォルト値は 16Mb です。
  • s3_max_redirects — 許可される S3 リダイレクトホップの最大数。デフォルト値は 10 です。
  • s3_single_read_retries — シングルリード中の最大試行回数。デフォルト値は 4 です。
  • s3_max_put_rps — スロットリング前の最大 PUT リクエスト毎秒レート。デフォルト値は 0 (無制限)です。
  • s3_max_put_burst — 1 秒あたりのリクエスト制限に達する前に同時に発行できる最大リクエスト数。デフォルト値(0 の場合)は s3_max_put_rps と等しくなります。
  • s3_max_get_rps — スロットリング前の最大 GET リクエスト毎秒レート。デフォルト値は 0 (無制限)です。
  • s3_max_get_burst — 1 秒あたりのリクエスト制限に達する前に同時に発行できる最大リクエスト数。デフォルト値(0 の場合)は s3_max_get_rps と等しくなります。
  • s3_upload_part_size_multiply_factor - s3_min_upload_part_size をこのファクターで掛け算します。[s3_upload_part_size_multiply_parts_count_threshold] からのパーツが S3 にアップロードされるごとに。デフォルト値は 2 です。
  • s3_upload_part_size_multiply_parts_count_threshold - この数のパーツが S3 にアップロードされるたびに、s3_min_upload_part_sizes3_upload_part_size_multiply_factor で掛け算されます。デフォルト値は 500 です。
  • s3_max_inflight_parts_for_one_file - 一つのオブジェクトに対して同時に実行できる PUT リクエストの数を制限します。この数値は制限する必要があります。値 0 は無制限を意味します。デフォルト値は 20 です。各進行中のパートは、最初の s3_upload_part_size_multiply_factor パートに対して s3_min_upload_part_size でサイズのバッファを持ち、大きなファイルの場合はさらに多く持ちます。デフォルト設定で、1 回にアップロードされたファイルは、8G 未満のファイルに対して 320Mb を超えて消費しません。大きなファイルの場合は、消費はさらに大きくなります。

セキュリティ上の考慮事項: 悪意のあるユーザーが任意の S3 URL を指定できる場合、s3_max_redirects をゼロに設定して SSRF 攻撃を回避する必要があります。あるいは、サーバー設定で remote_host_filter を指定することもできます。

エンドポイントベースの設定

次の設定は、特定のエンドポイントの設定ファイルに指定できます(URL の正確なプレフィックスによって一致します):

  • endpoint — エンドポイントのプレフィックスを指定します。必須です。
  • access_key_id および secret_access_key — 指定されたエンドポイントで使用する資格情報を指定します。オプションです。
  • use_environment_credentialstrue に設定されている場合、S3 クライアントは指定されたエンドポイントの環境変数および Amazon EC2 メタデータから資格情報を取得しようとします。オプションで、デフォルト値は false です。
  • region — S3 のリージョン名を指定します。オプションです。
  • use_insecure_imds_requesttrue に設定されている場合、S3 クライアントは Amazon EC2 メタデータから資格情報を取得する際に不正な IMDS リクエストを使用します。オプションで、デフォルト値は false です。
  • expiration_window_seconds — 有効期限ベースの資格情報が期限切れかどうかを確認するための猶予期間。オプションで、デフォルト値は 120 です。
  • no_sign_request - すべての資格情報を無視し、リクエストが署名されないようにします。パブリックバケットにアクセスするのに便利です。
  • header — 指定された HTTP ヘッダーを指定されたエンドポイントへのリクエストに追加します。オプションで、複数回指定できます。
  • access_header - 他のソースからの資格情報がない場合に、指定された HTTP ヘッダーを指定されたエンドポイントへのリクエストに追加します。
  • server_side_encryption_customer_key_base64 — 指定された場合、SSE-C 暗号化で S3 オブジェクトにアクセスするために必要なヘッダーが設定されます。オプションです。
  • server_side_encryption_kms_key_id - 指定された場合、SSE-KMS 暗号化 で S3 オブジェクトにアクセスするために必要なヘッダーが設定されます。空の文字列が指定された場合、AWS 管理の S3 キーが使用されます。オプションです。
  • server_side_encryption_kms_encryption_context - server_side_encryption_kms_key_id と一緒に指定された場合、SSE-KMS 用の暗号化コンテキストヘッダーが設定されます。オプションです。
  • server_side_encryption_kms_bucket_key_enabled - server_side_encryption_kms_key_id と一緒に指定された場合、SSE-KMS のための S3 バケットキーを有効にするためのヘッダーが設定されます。オプションで、true または false に設定でき、デフォルトでは何も設定されません(バケットレベルの設定に一致します)。
  • max_single_read_retries — シングルリード中の最大試行回数。デフォルト値は 4 です。オプションです。
  • max_put_rps, max_put_burst, max_get_rps および max_get_burst - 特定のエンドポイントに対して使用するスロットリング設定(上記の説明を参照)。オプションです。

例:

<s3>
    <endpoint-name>
        <endpoint>https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/</endpoint>
        <!-- <access_key_id>ACCESS_KEY_ID</access_key_id> -->
        <!-- <secret_access_key>SECRET_ACCESS_KEY</secret_access_key> -->
        <!-- <region>us-west-1</region> -->
        <!-- <use_environment_credentials>false</use_environment_credentials> -->
        <!-- <use_insecure_imds_request>false</use_insecure_imds_request> -->
        <!-- <expiration_window_seconds>120</expiration_window_seconds> -->
        <!-- <no_sign_request>false</no_sign_request> -->
        <!-- <header>Authorization: Bearer SOME-TOKEN</header> -->
        <!-- <server_side_encryption_customer_key_base64>BASE64-ENCODED-KEY</server_side_encryption_customer_key_base64> -->
        <!-- <server_side_encryption_kms_key_id>KMS_KEY_ID</server_side_encryption_kms_key_id> -->
        <!-- <server_side_encryption_kms_encryption_context>KMS_ENCRYPTION_CONTEXT</server_side_encryption_kms_encryption_context> -->
        <!-- <server_side_encryption_kms_bucket_key_enabled>true</server_side_encryption_kms_bucket_key_enabled> -->
        <!-- <max_single_read_retries>4</max_single_read_retries> -->
    </endpoint-name>
</s3>

アーカイブでの作業

次の URI にいくつかのアーカイブファイルが S3 にあります:

これらのアーカイブからデータを抽出するには、:: を使用します。グロブは、URL 部分だけでなく、:: の後の部分(アーカイブ内のファイルの名前を担当)でも使用できます。

SELECT *
FROM s3(
   'https://s3-us-west-1.amazonaws.com/umbrella-static/top-1m-2018-01-1{0..2}.csv.zip :: *.csv'
);
注記

ClickHouse は次の 3 つのアーカイブ形式をサポートしています: ZIP TAR 7Z ZIP および TAR アーカイブは、サポートされている任意のストレージ場所からアクセスできますが、7Z アーカイブは ClickHouse がインストールされているローカルファイルシステムからのみ読み取ることができます。

パブリックバケットへのアクセス

ClickHouse は多くの異なるタイプのソースから資格情報を取得しようとします。 時々、一部のパブリックバケットにアクセスする際に問題が発生し、クライアントが 403 エラーコードを返すことがあります。 この問題は、NOSIGN キーワードを使用し、クライアントがすべての資格情報を無視し、リクエストを署名しないように強制することで回避できます。

CREATE TABLE big_table (name String, value UInt32)
    ENGINE = S3('https://datasets-documentation.s3.eu-west-3.amazonaws.com/aapl_stock.csv', NOSIGN, 'CSVWithNames');

パフォーマンスの最適化

s3 関数のパフォーマンスを最適化する詳細については、当社の詳細ガイド をご覧ください。

その他