S3とClickHouseの統合
S3からClickHouseにデータを挿入することができ、またS3をエクスポート先として使用することで、「データレイク」アーキテクチャとの相互作用を実現します。さらに、S3は「コールド」ストレージ層を提供し、ストレージと計算を分離するのに役立ちます。以下のセクションでは、ニューヨーク市のタクシーデータセットを使用して、S3とClickHouse間のデータ移動プロセスを示し、主要な構成パラメータを特定し、パフォーマンスを最適化するためのヒントを提供します。
S3テーブル関数
s3
テーブル関数を使用すると、S3互換ストレージからファイルの読み書きができます。この構文の概要は以下の通りです:
ここで、
- path — ファイルへのパスを含むバケットURL。以下のワイルドカードを読み取り専用モードでサポートします:
*
、?
、{abc,def}
および{N..M}
(ここでN
とM
は数値、'abc'
と'def'
は文字列)。詳細については、パスにおけるワイルドカードの使用のドキュメントを参照してください。 - format — ファイルのフォーマット。
- structure — テーブルの構造。形式
'column1_name column1_type, column2_name column2_type, ...'
。 - compression — パラメータはオプションです。サポートされる値:
none
、gzip/gz
、brotli/br
、xz/LZMA
、zstd/zst
。デフォルトでは、ファイル拡張子によって圧縮を自動検出します。
パス式でワイルドカードを使用することで、複数のファイルを参照し、並列処理の扉を開きます。
準備
ClickHouseでテーブルを作成する前に、S3バケット内のデータを詳しく見ることをお勧めします。これは、DESCRIBE
ステートメントを使用してClickHouseから直接行うことができます:
DESCRIBE TABLE
ステートメントの出力は、ClickHouseがこのデータをどのように自動的に推論するかを示します。S3バケットで表示された内容に留意してください。また、gzip圧縮形式を自動的に認識し、解凍することも確認してください:
私たちのS3ベースのデータセットと対話するために、標準のMergeTree
テーブルを目的地として準備します。以下のステートメントは、デフォルトデータベースにtrips
という名前のテーブルを作成します。特に推論されたデータ型の一部を変更することに注意してください。特に、余分なストレージデータを引き起こす可能性のあるNullable()
データ型修飾子を使用しないことを選択しました:
pickup_date
フィールドのパーティショニングの使用に注意してください。通常、パーティションキーはデータ管理用ですが、後でこのキーを使用してS3への書き込みを並列化します。
タクシーデータセット内の各エントリはタクシートリップを含みます。この匿名化されたデータは、S3バケットに圧縮された2000万件のレコードで構成されています。バケットは https://datasets-documentation.s3.eu-west-3.amazonaws.com/ で、フォルダは nyc-taxi です。データはTSV形式で、各ファイルに約100万行含まれています。
S3からのデータ読み取り
S3データをソースとしてクエリし、ClickHouseの永続性を必要とせずに使用できます。以下のクエリでは、10行をサンプリングします。バケットが公開アクセス可能であるため、ここでは認証情報が不要です:
TabSeparatedWithNames
フォーマットは、最初の行にカラム名をエンコードしているため、カラムをリストする必要はないことに注意してください。他のフォーマット(例:CSV
やTSV
)は、このクエリに対して自動生成されたカラムを返します。例: c1
、c2
、c3
など。
クエリは、バケットパスやファイル名に関する情報を提供する仮想カラムをサポートしています。例えば:
このサンプルデータセット内の行数を確認します。ファイル展開のためワイルドカードを使用しているため、すべての20ファイルを考慮します。このクエリは、ClickHouseインスタンスのコア数によって約10秒かかります:
これは、データのサンプリングや即席の探索的クエリを実行する際には便利ですが、S3からデータを直接読み取ることは定期的に行うべきではありません。真剣にデータを扱うときは、データをClickHouseのMergeTree
テーブルにインポートします。
clickhouse-localの使用
clickhouse-local
プログラムを使用すると、ClickHouseサーバーをデプロイおよび構成せずにローカルファイルの高速処理を行うことができます。s3
テーブル関数を使用するクエリは、このユーティリティを使って実行できます。例えば:
S3からのデータ挿入
ClickHouseの機能を最大限に活用するために、次にデータを読み取り、インスタンスに挿入します。これを達成するために、s3
関数とシンプルなINSERT
ステートメントを組み合わせます。ターゲットテーブルが必要な構造を提供するため、カラムをリストする必要はありません。カラムはSELECT
句の位置に従ってマッピングされます。10M行の挿入には数分かかる場合がありますが、下の例では即時の応答を得るために100万行を挿入します。必要に応じて、LIMIT
句やカラム選択を調整して部分インポートを行います:
ClickHouse Localを使用したリモート挿入
ネットワークセキュリティポリシーにより、ClickHouseクラスターが外向き接続を行えない場合、clickhouse-local
を使用してS3データを挿入することができます。以下の例では、S3バケットから読み取り、remote
関数を使用してClickHouseに挿入します:
これを安全なSSL接続で実行するには、remoteSecure
関数を利用してください。
データのエクスポート
s3
テーブル関数を使用してS3にファイルを書き込むことができます。これには適切な権限が必要です。リクエスト内で必要な認証情報を渡しますが、詳細については認証情報の管理ページを参照してください。
単純な例では、テーブル関数をソースではなく目的地として使用します。ここでは、trips
テーブルからバケットに10000行をストリーミングし、lz4
圧縮および出力タイプとしてCSV
を指定します:
ここで、ファイルの形式は拡張子から推測されることに注意してください。また、s3
関数内でカラムを指定する必要はありません。これもSELECT
から推測されます。
大きなファイルを分割する
データを単一のファイルとしてエクスポートすることはほとんどないでしょう。ClickHouseを含むほとんどのツールは、並列処理の可能性により、複数のファイルに対して読み書きすることでより高いスループットパフォーマンスを達成します。INSERT
コマンドを複数回実行し、データのサブセットをターゲットにすることができます。ClickHouseは、PARTITION
キーを使用してファイルを自動的に分割する手段を提供します。
以下の例では、rand()
関数の剰余を使用して10ファイルを作成します。結果のパーティションIDがファイル名に参照されていることに注意してください。これにより、数値の接尾辞を持つ10ファイル(例:trips_0.csv.lz4
, trips_1.csv.lz4
など)が生成されます:
あるいは、データ内のフィールドを参照することもできます。このデータセットの場合、payment_type
が自然なパーティショニングキーを提供し、その基数は5です。
クラスターの利用
上記の関数はすべて単一ノードでの実行に制限されています。読み取り速度はCPUコアとともに線形にスケールし、他のリソース(通常はネットワーク)が飽和するまで、ユーザーは垂直にスケールすることができます。しかし、このアプローチには限界があります。ユーザーは、INSERT INTO SELECT
クエリを実行する際に分散テーブルに挿入することでリソース圧力を軽減できますが、依然として単一ノードがデータを読み込み、解析し、処理しています。この課題に対処し、読み取りを水平方向にスケールするために、s3Cluster関数があります。
クエリを受け取ったノード(イニシエーター)は、クラスタ内のすべてのノードへの接続を作成します。どのファイルを読み取る必要があるかを決定するためにグロブパターンが解決され、一連のファイルに展開されます。イニシエーターは、クラスタ内のノードにファイルを配布します。これらのノードは、読み取りを完了するたびに処理するファイルを要求します。このプロセスにより、読み取りを水平方向にスケールすることができます。
s3Cluster
関数は、単一ノードバリアントと同じ形式を取り、ただしターゲットクラスタを指定する必要があります:
cluster_name
— リモートおよびローカルサーバーへのアドレスと接続パラメータのセットを構築するために使用されるクラスタの名前。source
— ファイルまたはファイルのグループへのURL。以下のワイルドカードを読み取り専用モードでサポートします:*
、?
、{'abc','def'}
および{N..M}
(ここで N, M は数値、abc, def は文字列)。詳細はパスにおけるワイルドカードを参照してください。access_key_id
およびsecret_access_key
— 指定されたエンドポイントで使用するための認証情報を指定するキー。オプションです。format
— ファイルのフォーマット。structure
— テーブルの構造。形式 'column1_name column1_type, column2_name column2_type, ...'。
s3
関数と同様に、バケットが安全でない場合、または環境を通じてセキュリティを定義する場合(例:IAMロール)、認証情報はオプションです。しかし、22.3.1以降、s3Cluster
関数では構造をリクエスト内で指定する必要があります。すなわち、スキーマは推測されません。
この関数は、ほとんどの場合INSERT INTO SELECT
の一部として使用されます。この場合、ユーザーは分散テーブルに挿入することがよくあります。以下に、trips_all
が分散テーブルである簡単な例を示します。このテーブルはevents
クラスタを使用していますが、読み込みと書き込みに使用されるノードの一貫性は必須ではありません:
挿入はイニシエーターノードに対して発生します。これは、各ノードで読み取る一方で、結果の行がイニシエーターにルーティングされて配布されることを意味します。高スループットのシナリオでは、これがボトルネックとなる可能性があります。これに対処するために、s3cluster
関数のためのparallel_distributed_insert_selectパラメータを設定してください。
S3テーブルエンジン
s3
関数はS3に保存されたデータに対して即席クエリを実行することを可能にしますが、構文が冗長です。S3
テーブルエンジンを使用すると、バケットのURLや認証情報を何度も指定する必要がなくなります。これに対処するために、ClickHouseはS3テーブルエンジンを提供しています。
path
— ファイルへのパスを含むバケットURL。以下のワイルドカードを読み取り専用モードで支援:*
、?
、{abc,def}
および{N..M}
(ここで N, M は数値、'abc'、'def' は文字列)。詳細についてはこちらを参照してください。format
— ファイルのフォーマット。aws_access_key_id
,aws_secret_access_key
- AWSアカウントユーザーの長期的な認証情報。これを使用してリクエストを認証できます。このパラメータはオプションです。認証情報が指定されていない場合、構成ファイルでの値が使用されます。詳細は認証情報の管理を参照してください。compression
— 圧縮タイプ。サポートされる値:none、gzip/gz、brotli/br、xz/LZMA、zstd/zst。このパラメータはオプションです。デフォルトでは、ファイル拡張子によって圧縮を自動検出します。
データの読み取り
以下の例では、https://datasets-documentation.s3.eu-west-3.amazonaws.com/nyc-taxi/
バケット内の最初の10個のTSVファイルを使用して、trips_raw
という名のテーブルを作成します。これらはそれぞれ100万行を含みます:
最初の10ファイルに制限するために{0..9}
パターンを使用していることに注意してください。一度作成されると、このテーブルは他のテーブルと同様にクエリできます:
データの挿入
S3
テーブルエンジンは並列読み取りをサポートしています。テーブル定義にグロブパターンが含まれていない場合、書き込みのみがサポートされます。したがって、上記のテーブルは書き込みをブロックします。
書き込みを示すために、書き込み可能なS3バケットを指すテーブルを作成します:
行は新しいファイルにのみ挿入できることに注意してください。マージサイクルやファイル分割操作はありません。ファイルが書き込まれると、その後の挿入は失敗します。ユーザーには以下の2つのオプションがあります:
- 設定
s3_create_new_file_on_insert=1
を指定してください。これにより、各挿入時に新しいファイルが作成されます。各挿入操作のたびに、数値の接尾辞が各ファイルの末尾に追加されます。上記の例では、次回の挿入により、trips_1.bin
ファイルが作成されます。 - 設定
s3_truncate_on_insert=1
を指定してください。これにより、ファイルが切り詰められ、つまり完了後は新たに挿入された行のみが含まれることになります。
これらの設定はデフォルトで0になります。したがって、ユーザーはそのいずれかを設定する必要があります。両方が設定されている場合は、s3_truncate_on_insert
が優先されます。
S3
テーブルエンジンに関するいくつかの注意点:
- 従来の
MergeTree
ファミリテーブルとは異なり、S3
テーブルを削除しても、基になるデータは削除されません。 - このテーブルタイプの完全な設定はこちらで確認できます。
- このエンジンを使用する際に注意すべき点は以下の通りです:
- ALTERクエリはサポートされていません
- SAMPLE操作はサポートされていません
- プライマリーまたはスキップのインデックスという概念はありません。
認証情報の管理
前の例では、s3
関数またはS3
テーブル定義内に認証情報を渡しました。これは、稀に使用される場合には受け入れられるかもしれませんが、プロダクションではユーザーには明示的な認証メカニズムが求められる必要があります。これに対処するために、ClickHouseは複数のオプションを提供しています。
-
config.xmlまたはconf.dの下にある同等の設定ファイルに接続の詳細を指定します。デビアンパッケージを使用したインストールを前提とした例ファイルの内容は以下の通りです。
これらの認証情報は、上記のエンドポイントがリクエストされたURLの正確な接頭辞一致である場合、任意のリクエストに使用されます。また、この例では、アクセスキーおよびシークレットキーの代替として認証ヘッダーを宣言する能力に注意してください。サポートされている設定の完全なリストはこちらで確認できます。
-
上記の例は、設定パラメータ
use_environment_credentials
の使用可能性を強調しています。この設定パラメータは、s3
レベルでグローバルに設定することもできます:この設定は、環境からS3の認証情報を取得しようとする試みをオンにし、IAMロールを介してアクセス可能にします。具体的には、以下の取得順に従って実施されます:
- 環境変数
AWS_ACCESS_KEY_ID
、AWS_SECRET_ACCESS_KEY
およびAWS_SESSION_TOKEN
の検索 - $HOME/.awsにおけるチェック
- AWSセキュリティトークンサービスを通じて取得された一時的な認証情報 - すなわち
AssumeRole
APIを介して。 - ECS環境変数
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
またはAWS_CONTAINER_CREDENTIALS_FULL_URI
およびAWS_ECS_CONTAINER_AUTHORIZATION_TOKEN
での認証情報のチェック。 - これらの認証情報の取得は、AWS EC2インスタンスメタデータを介して行われ、AWS_EC2_METADATA_DISABLEDがtrueに設定されていない場合。
同様の設定を特定のエンドポイントに対して、同じ接頭辞一致ルールを使用して設定することもできます。
- 環境変数
パフォーマンスの最適化
S3関数を使用した読み取りおよび挿入の最適化方法については、専用のパフォーマンスガイドを参照してください。
S3ストレージの調整
内部的に、ClickHouseのマージツリーは、Wide
およびCompact
の2つの主要ストレージフォーマットを使用します。現在の実装は、ClickHouseのデフォルトの動作(設定 min_bytes_for_wide_part
と min_rows_for_wide_part
を通じて制御される)を使用していますが、将来的なリリースでは、S3のために動作が異なることが予想されます。例えば、min_bytes_for_wide_part
のデフォルト値が大きくなり、よりCompact
形式を推奨し、結果としてファイル数が少なくなることが期待されます。ユーザーは、専らS3ストレージを使用する場合にこれらの設定を調整することを望むかもしれません。
S3バックにあるMergeTree
s3
関数と関連するテーブルエンジンにより、ユーザーはClickHouseの慣れ親しんだ構文を用いてS3内のデータをクエリできます。しかし、データ管理機能やパフォーマンスに関しては、限界があります。プライマリーインデックスのサポートはなく、キャッシュサポートもありません。ファイルの挿入はユーザーによって管理する必要があります。
ClickHouseは、S3が特に「コールド」データに対するクエリパフォーマンスがそれほど重要ではない状況で、ストレージソリューションとして魅力的であり、ユーザーがストレージと計算を分離することを望んでいることを認識しています。この実現を支援するために、MergeTreeエンジンのストレージとしてS3を使用するサポートが提供されます。これにより、ユーザーはS3のスケーラビリティとコストの利点を活用し、MergeTreeエンジンの挿入およびクエリパフォーマンスを享受できます。
ストレージ層
ClickHouseストレージボリュームは、物理ディスクをMergeTreeテーブルエンジンから抽象化できます。単一のボリュームは、順序付きのディスクセットで構成されることがあります。データストレージのために複数のブロックデバイスを潜在的に使用できることを主に許可するこの抽象化は、S3などの他のストレージタイプも許可します。ClickHouseのデータパーツは、ストレージポリシーに応じてボリューム間で移動され、充填率が管理され、これによりストレージ層の概念が作成されます。
ストレージ層は、最近のデータをホットコールドアーキテクチャで解除し、通常は最も多くクエリされるデータが高性能ストレージ(例:NVMe SSD)にわずかな空間を必要とすることを可能にします。データが古くなるにつれて、クエリタイムのSLAが増加し、クエリの頻度も高くなります。このデータのファットテールは、HDDやS3などのオブジェクトストレージのような遅い、性能が低いストレージに保存できます。
このディスク宣言に関連する設定の完全なリストはこちらで確認できます。資格情報は、資格情報の管理で説明されているのと同じアプローチを使用してここで管理できます。すなわち、上記の設定ブロックでuse_environment_credentialsをtrueに設定することでIAMロールを使用できます。
ストレージポリシーの作成
設定が完了すると、この「ディスク」はポリシー内で宣言されたストレージボリュームで使用できます。以下の例では、s3が唯一のストレージであると仮定します。これは、TTLや充填率に基づいてデータを移動できるより複雑なホットコールドアーキテクチャを無視しています。
テーブルの作成
ディスクに書き込みアクセスのあるバケットを使用するように設定されている場合、以下の例のようなテーブルを作成できるはずです。簡潔さを持たせるために、NYCタクシーのカラムのサブセットを使用し、データを直接s3バックテーブルにストリーミングします。
ハードウェアによっては、この1m行の挿入に数分かかる場合があります。進捗はsystem.processesテーブルを介して確認できます。行数を最大10mまで調整し、いくつかのサンプルクエリを試してください。
テーブルの変更
ユーザーは特定のテーブルのストレージポリシーを変更する必要がある場合があります。これは可能ですが、制限があります。新しいターゲットポリシーには、以前のポリシーのすべてのディスクとボリュームが含まれている必要があります。すなわち、ポリシーの変更を満たすためにデータは移行されないということです。これらの制約を検証する際には、ボリュームとディスクは名前で識別され、違反しようとするとエラーが発生します。ただし、前の例を使用していると仮定すると、以下の変更は有効です。
ここでは、新しいs3_tieredポリシーにメインボリュームを再利用し、新しいホットボリュームを導入します。これは、<path>
パラメーターを介して設定された1つのディスクで構成されたデフォルトディスクを使用しています。ボリューム名とディスクは変更されません。新たにテーブルに挿入されるものは、デフォルトディスクに残り、そのサイズがmove_factor * disk_sizeに達した時点でデータはS3へ移動されます。
レプリケーションの処理
S3ディスクとのレプリケーションは、ReplicatedMergeTree
テーブルエンジンを使用することで実現できます。詳細については二つのAWSリージョンにまたがる単一シャードをS3オブジェクトストレージで複製するガイドを参照してください。
読み書き
以下のノートは、ClickHouseとS3のインタラクションの実装に関するものです。一般的には情報提供を目的としていますが、パフォーマンスの最適化を行う際に読者に役立つかもしれません:
- デフォルトでは、クエリ処理パイプラインの任意のステージで使用される最大クエリ処理スレッド数は、コアの数と等しくなっています。一部のステージは他のステージよりも並行処理が可能であるため、この値は上限を提供します。複数のクエリステージは同時に実行される場合があります。データはディスクからストリームされるため、クエリに使用されるスレッド数はこの上限を超える可能性があります。max_threadsの設定を通じて変更してください。
- S3からの読み取りはデフォルトで非同期です。この動作は、
remote_filesystem_read_method
を設定することで決まります。デフォルトではこの値はthreadpool
に設定されています。リクエストを処理する際、ClickHouseはグラニュールをストライプで読み取ります。これらのストライプは多くのカラムを含む可能性があります。スレッドはそれぞれのグラニュールのカラムを一つずつ読み取ります。この処理は同期的には行われず、データを待つ前にすべてのカラムのプレフェッチが行われます。これにより、各カラムに対する同期的待機よりも大幅なパフォーマンス向上が得られます。ほとんどの場合、この設定を変更する必要はありません - 最適化パフォーマンスを参照してください。 - 書き込みは並行して行われ、最大100の同時ファイル書き込みスレッドがあります。
max_insert_delayed_streams_for_parallel_write
はデフォルトで1000の値に設定されており、並行して書き込まれるS3ブロブの数を制御します。各ファイルの書き込みにはバッファが必要で(約1MB)、これによりINSERTのメモリ消費が効果的に制限されます。サーバーのメモリが少ないシナリオでは、この値を下げるのが適切かもしれません。
ClickHouse用にS3オブジェクトストレージをディスクとして使用する
バケットとIAMロールを作成するためのステップバイステップの指示が必要な場合は、S3バケットとIAMロールの作成を展開し、手順に従ってください:
S3バケットとIAMユーザーの作成
この記事では、AWS IAMユーザーの基本設定、S3バケットの作成、およびClickHouseをそのバケットをS3ディスクとして使用するように設定する方法を示します。使用する権限についてはセキュリティチームと相談し、これらを出発点として考慮してください。
AWS IAMユーザーの作成
この手順では、ログインユーザーではなく、サービスアカウントユーザーを作成します。
-
AWS IAM管理コンソールにログインします。
-
「ユーザー」でユーザーの追加を選択します。

- ユーザー名を入力し、認証情報の種類をアクセスキー - プログラムによるアクセスに設定し、次へ: 権限を選択します。

- ユーザーをいかなるグループにも追加せず、次へ: タグを選択します。

- タグを追加する必要がない限り、次へ: 確認を選択します。

-
ユーザーの作成を選択します。
注記ユーザーに権限がないという警告メッセージは無視できます。権限は次のセクションでバケットに対してユーザーに付与されます。

- ユーザーが作成されました。表示をクリックし、アクセスキーとシークレットキーをコピーします。
キーは他の場所に保存してください。これはシークレットアクセスキーが利用可能な唯一の時点です。

- 閉じるをクリックし、ユーザーの画面でユーザーを見つけます。
- ARN(Amazonリソースネーム)をコピーし、バケットのアクセスポリシーを設定する際に使用するために保存します。

S3バケットの作成
- S3バケットセクションで、バケットの作成を選択します。

- バケット名を入力し、他のオプションはデフォルトのままにします。
バケット名はAWS全体で一意である必要があります。同一の組織内だけではエラーが発生します。
すべてのパブリックアクセスをブロック
を有効なままにします。公共のアクセスは必要ありません。

- ページの下部でバケットの作成を選択します。

-
リンクを選択し、ARNをコピーし、バケットのアクセスポリシーを設定する際に使用するために保存します。
-
バケットが作成されたら、S3バケットリストで新しいS3バケットを見つけ、リンクを選択します。

- フォルダーの作成を選択します。

- ClickHouse S3ディスクのターゲットとなるフォルダー名を入力し、フォルダーの作成を選択します。

- フォルダーは現在バケットリストに表示されるはずです。

- 新しいフォルダーのチェックボックスを選択し、URLをコピーをクリックします。コピーされたURLを、次のセクションでClickHouseストレージ構成に使用するために保存します。

- Permissionsタブを選択し、バケットポリシーセクションの編集ボタンをクリックします。

- 以下のようにバケットポリシーを追加します:
使用する权限の決定はセキュリティチームと相談してください。これを出発点と考えて実施してください。 ポリシーおよび設定についての詳細はAWSのドキュメントを参照してください: https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-policy-language-overview.html
- ポリシー設定を保存します。
S3バケットをディスクとして使用するようにClickHouseを設定する
以下の例は、デフォルトのClickHouseディレクトリでサービスとしてインストールされたLinux Debパッケージに基づいています。
- ClickHouseの
config.d
ディレクトリに新しいファイルを作成して、ストレージ設定を保存します。
- ストレージ設定のために、先ほどの手順からバケットパス、アクセスキー、およびシークレットキーに置き換えた以下を追加します。
<disks>
タグ内のs3_disk
およびs3_cache
タグは任意のラベルです。これらは他の名前に設定できますが、<policies>
タブ内の<disk>
タブで同じラベルを使用してディスクを参照しなければなりません。
<S3_main>
タグも任意で、ClickHouseでリソースを作成する際に参照されるストレージターゲットの識別子として使用されるポリシーの名前となります。
上記の設定は、ClickHouseバージョン22.8以上用です。古いバージョンを使用している場合は、データを保存するドキュメントを参照してください。
S3を使用するための詳細については: 統合ガイド: S3バックのMergeTree
- ファイルの所有者を
clickhouse
ユーザーおよびグループに更新します。
- 変更を有効にするためにClickHouseインスタンスを再起動します。
テスト
- ClickHouseクライアントにログインします。以下のようにします。
- 新しいS3ストレージポリシーを指定してテーブルを作成します。
- テーブルが正しいポリシーで作成されたことを示します。
- テスト行をテーブルに挿入します。
- 行を表示します。
- AWSコンソールで、バケットに移動し、新しいバケットとフォルダーを選択します。 以下のようなものが表示されるはずです。

S3オブジェクトストレージを使用して単一のシャードを二つのAWSリージョンで複製する
ClickHouse Cloudではデフォルトでオブジェクトストレージが使用されます。ClickHouse Cloudで実行している場合、この手順を実行する必要はありません。
配備の計画
このチュートリアルは、AWS EC2上の二つのClickHouse Serverノードと三つのClickHouse Keeperノードをスピーディに展開することに基づいています。ClickHouseサーバーのデータストアはS3です。それぞれのリージョンにClickHouse ServerとS3バケットが1つ用意されており、災害復旧をサポートします。
ClickHouseテーブルは、二つのサーバー間で複製され、したがって二つのリージョン acrossで複製されます。
ソフトウェアのインストール
ClickHouseサーバーノード
ClickHouseサーバーノードに対するデプロイメント手順を実行する際は、インストール手順を参照してください。
ClickHouseをデプロイする
二つのホストにClickHouseをデプロイします。このサンプル設定ではこれらはchnode1
とchnode2
と呼ばれています。
chnode1
を一つのAWSリージョンに配置し、chnode2
を第二のリージョンに配置します。
ClickHouse Keeperをデプロイする
三つのホストにClickHouse Keeperをデプロイします。このサンプル設定では、これらはkeepernode1
、keepernode2
、およびkeepernode3
と呼ばれています。 keepernode1
はchnode1
と同じリージョンにデプロイできます、keepernode2
はchnode2
と一緒に、そしてkeepernode3
はどちらのリージョンにもデプロイできますが、そのリージョンのClickHouseノードとは異なる可用性ゾーンになります。
ClickHouse Keeperノードのデプロイメント手順を実行する際にはインストール手順を参照してください。
S3バケットを作成する
二つのS3バケットを作成します。一つはchnode1
が配置されているリージョンに、もう一つはchnode2
が配置されているリージョンに作成します。
バケットとIAMロールを作成するためのステップバイステップの指示が必要な場合は、S3バケットとIAMロールの作成を展開し、手順に従ってください:
S3バケットとIAMユーザーの作成
この記事では、AWS IAMユーザーの基本設定、S3バケットの作成、およびClickHouseをそのバケットをS3ディスクとして使用するように設定する方法を示します。使用する権限についてはセキュリティチームと相談し、これらを出発点として考慮してください。
AWS IAMユーザーの作成
この手順では、ログインユーザーではなく、サービスアカウントユーザーを作成します。
-
AWS IAM管理コンソールにログインします。
-
「ユーザー」でユーザーの追加を選択します。

- ユーザー名を入力し、認証情報の種類をアクセスキー - プログラムによるアクセスに設定し、次へ: 権限を選択します。

- ユーザーをいかなるグループにも追加せず、次へ: タグを選択します。

- タグを追加する必要がない限り、次へ: 確認を選択します。

-
ユーザーの作成を選択します。
注記ユーザーに権限がないという警告メッセージは無視できます。権限は次のセクションでバケットに対してユーザーに付与されます。

- ユーザーが作成されました。表示をクリックし、アクセスキーとシークレットキーをコピーします。
キーは他の場所に保存してください。これはシークレットアクセスキーが利用可能な唯一の時点です。

- 閉じるをクリックし、ユーザーの画面でユーザーを見つけます。
- ARN(Amazonリソースネーム)をコピーし、バケットのアクセスポリシーを設定する際に使用するために保存します。

S3バケットの作成
- S3バケットセクションで、バケットの作成を選択します。

- バケット名を入力し、他のオプションはデフォルトのままにします。
バケット名はAWS全体で一意である必要があります。同一の組織内だけではエラーが発生します。
すべてのパブリックアクセスをブロック
を有効なままにします。公共のアクセスは必要ありません。

- ページの下部でバケットの作成を選択します。

-
リンクを選択し、ARNをコピーし、バケットのアクセスポリシーを設定する際に使用するために保存します。
-
バケットが作成されたら、S3バケットリストで新しいS3バケットを見つけ、リンクを選択します。

- フォルダーの作成を選択します。

- ClickHouse S3ディスクのターゲットとなるフォルダー名を入力し、フォルダーの作成を選択します。

- フォルダーは現在バケットリストに表示されるはずです。

- 新しいフォルダーのチェックボックスを選択し、URLをコピーをクリックします。コピーされたURLを、次のセクションでClickHouseストレージ構成に使用するために保存します。

- Permissionsタブを選択し、バケットポリシーセクションの編集ボタンをクリックします。

- 以下のようにバケットポリシーを追加します:
使用する权限の決定はセキュリティチームと相談してください。これを出発点と考えて実施してください。 ポリシーおよび設定についての詳細はAWSのドキュメントを参照してください: https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-policy-language-overview.html
- ポリシー設定を保存します。
その後、設定ファイルは/etc/clickhouse-server/config.d/
に配置されます。このバケットのためのサンプル設定ファイルは以下の通りで、もう一つは、三つのハイライトされた行が異なる類似のものです。
このガイドの多くのステップでは、/etc/clickhouse-server/config.d/
に設定ファイルを配置するように求められます。これはLinuxシステムで設定上書きファイルのデフォルトの場所です。これらのファイルをそのディレクトリに置くと、ClickHouseはコンテンツを使用してデフォルトの設定を上書きします。これらのファイルを上書きディレクトリに配置することで、アップグレード中に設定が失われるのを避けることができます。
ClickHouse Keeperを設定する
ClickHouse Keeperをスタンドアロンで実行する(ClickHouseサーバーとは別に)場合の設定は、単一のXMLファイルです。このチュートリアルでは、ファイルは/etc/clickhouse-keeper/keeper_config.xml
です。すべての三つのKeeperサーバーは、以下の例のように同じ設定を使用しますが、1つの設定が異なります;<server_id>
です。
server_id
は、設定ファイルが使用されるホストに割り当てるIDを示します。以下の例では、server_id
は3
で、ファイル内の<raft_configuration>
セクションも見てみると、サーバー3にホスト名keepernode3
が指定されています。これがClickHouse Keeperプロセスがリーダーを選択する際にどのサーバーに接続するかを知る方法です。
ClickHouse Keeperの設定ファイルをコピーします(<server_id>
を設定するのを忘れずに):
ClickHouseサーバーを設定する
クラスターの定義
ClickHouseのクラスターは、設定ファイルの<remote_servers>
セクションで定義されます。このサンプルでは、cluster_1S_2R
という1つのクラスターが定義されており、これは一つのシャードと二つのレプリカで構成されています。レプリカは、ホストchnode1
とchnode2
に位置しています。
クラスターを使用する際は、DDLクエリにクラスター、シャード、およびレプリカの設定を埋め込むためのマクロを定義すると便利です。このサンプルでは、shard
およびreplica
の詳細を提供せずにレプリケーテッドテーブルエンジンを使用することを指定できます。テーブルを作成すると、shard
とreplica
のマクロがsystem.tables
をクエリすることでどのように使用されるかを見ることができます。
上記のマクロはchnode1
用のものです。chnode2
ではreplica
をreplica_2
に設定してください。
ゼロコピーのレプリケーションを無効にする
ClickHouseバージョン22.7以下では、allow_remote_fs_zero_copy_replication
設定は、デフォルトでS3およびHDFSディスクに対してtrue
に設定されています。この設定は、この災害復旧シナリオではfalse
に設定する必要があります。バージョン22.8以降では、デフォルトでfalse
に設定されています。
この設定は以下の二つの理由からfalse
にする必要があります。1) この機能は製品版ではない。2) 災害復旧シナリオでは、データとメタデータの両方を複数のリージョンに保存する必要があります。allow_remote_fs_zero_copy_replication
をfalse
に設定します。
ClickHouse Keeperは、ClickHouseノード間でのデータのレプリケーションを調整する責任があります。ClickHouseにClickHouse Keeperノードを伝えるために、各ClickHouseノードに設定ファイルを追加します。
ネットワーキングの設定
AWSでサーバーが互いに通信できるようにするためのセキュリティ設定を構成する際は、ネットワークポートリストを確認してください。
すべての三つのサーバーは、ネットワーク接続をリッスンしてできるようにする必要があります。それにより、サーバー間とS3との通信が行われます。ClickHouseはデフォルトではループバックアドレス上でのみリッスンするため、これを変更する必要があります。これらの設定は/etc/clickhouse-server/config.d/
に構成されます。以下は、ClickHouseとClickHouse KeeperがすべてのIP v4インターフェースでリッスンするように設定するサンプルです。詳細については、ドキュメントまたはデフォルト設定ファイル/etc/clickhouse/config.xml
を参照してください。
サーバーの起動
ClickHouse Keeperを実行する
各Keeperサーバーで、オペレーティングシステムに応じてコマンドを実行します。例:
ClickHouse Keeperのステータスを確認する
netcat
を使ってClickHouse Keeperにコマンドを送ります。例えば、mntr
はClickHouse Keeperクラスターの状態を返します。各Keeperノードでこのコマンドを実行すると、1つがリーダーであり、他の2つがフォロワーであることがわかります。
ClickHouseサーバーを実行する
各ClickHouseサーバーで実行します。
ClickHouseサーバーを確認する
クラスター設定を追加した際に、二つのClickHouseノードにまたがる単一シャードが複製されるようになりました。この確認ステップでは、ClickHouseが起動した時にクラスタが構築されたことを確認し、そのクラスターを使用して複製されたテーブルを作成します。
-
クラスタが存在することを確認します:
-
ReplicatedMergeTree
テーブルエンジンを使用してクラスター内にテーブルを作成します: -
先に定義されたマクロの使用を理解する
マクロ
shard
とreplica
は前述の通りで定義されており、ハイライトされた行でクリックハウスノードごとに値が置き換えられるのがわかります。さらに、値uuid
が使用されます。uuid
はシステムによって生成されるため、マクロには定義されません。注記上記に示されるzookeeperのパス
'clickhouse/tables/{uuid}/{shard}
は、default_replica_path
およびdefault_replica_name
を設定することでカスタマイズできます。詳細はこちらをご覧ください。
テスト
これらのテストは、データが二つのサーバー間で複製されていること、そしてそれがローカルディスクではなくS3バケットに格納されていることを確認します。
-
ニューヨーク市タクシーデータセットからデータを追加します:
-
データがS3に保存されていることを確認します。
このクエリはディスク上のデータのサイズと、どのディスクが使用されるかを決定するポリシーを表示します。
ローカルディスク上のデータのサイズを確認します。上記から、保存されたミリオンズ行のディスク上のサイズは36.42 MiBです。これはS3に保存されているはずで、ローカルディスクには保存されていません。このクエリは、ローカルディスクでデータとメタデータが保存されている場所も教えてくれます。ローカルデータを確認します:
各S3バケット内のS3データを確認します(合計は表示されませんが、両方のバケットには約36 MiBが保存されるはずです)。


S3Express
S3Expressは、Amazon S3の新しい高性能シングルアベイラビリティゾーンストレージクラスです。
このブログでは、ClickHouseでのS3Expressテストについての私たちの経験を読めます。
S3Expressは、単一のAZ内にデータを保存します。つまり、AZの停止の場合、データが利用できなくなります。
S3ディスク
S3Expressバケットでストレージをサポートするテーブルを作成するには、以下の手順が必要です。
Directory
タイプのバケットを作成します。- S3ユーザーに必要なすべての権限を付与するために適切なバケットポリシーをインストールします(例えば、
"Action": "s3express:*"
を指定して無制限のアクセスを許可する)。 - ストレージポリシーを設定する際には、
region
パラメータを指定してください。
ストレージ構成は通常のS3と同じで、例えば次のようになります。
その後、新しいストレージにテーブルを作成します。
S3ストレージ
S3ストレージもサポートされていますが、Object URL
パスのみ対応しています。例:
設定ではバケットのリージョンも指定する必要があります。
バックアップ
上記で作成したディスクにバックアップを保存することが可能です。