Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

ClickHouse Keeper

ClickHouse Cloud ではサポートされていません

ClickHouse Keeper は、データのレプリケーションおよびdistributed DDLクエリの実行に必要な協調システムを提供します。ClickHouse Keeper は ZooKeeper と互換性があります。

実装の詳細

ZooKeeper は、初期に登場した著名なオープンソースの協調システムの 1 つです。Java で実装されており、シンプルで強力なデータモデルを備えています。ZooKeeper の協調アルゴリズムである ZooKeeper Atomic Broadcast (ZAB) は、各 ZooKeeper ノードが読み取りをローカルで処理するため、読み取りの線形化可能性を保証しません。ZooKeeper とは異なり、ClickHouse Keeper は C++ で書かれており、RAFTアルゴリズム実装を使用しています。このアルゴリズムは、読み取りと書き込みの両方で線形化可能性を実現し、さまざまな言語による複数のオープンソース実装があります。

デフォルトでは、ClickHouse Keeper は ZooKeeper と同じ保証を提供します。つまり、書き込みは線形化可能で、読み取りは非線形化可能です。クライアント・サーバープロトコルに互換性があるため、標準的な ZooKeeper クライアントであれば ClickHouse Keeper とやり取りできます。スナップショットとログのフォーマットは ZooKeeper と互換性がありませんが、clickhouse-keeper-converter ツールを使用すると、ZooKeeper のデータを ClickHouse Keeper のスナップショットに変換できます。ClickHouse Keeper のサーバー間プロトコルも ZooKeeper とは互換性がないため、ZooKeeper と ClickHouse Keeper が混在するクラスターを構成することはできません。

ClickHouse Keeper は、ZooKeeper と同様にアクセス制御リスト (ACL) をサポートしています。ClickHouse Keeper は同じ権限セットをサポートしており、組み込みのスキームも worldauthdigest の 3 つで完全に同一です。digest 認証スキームでは username:password の組を使用し、パスワードは Base64 でエンコードされます。

設定

ClickHouse Keeper は、ZooKeeper のスタンドアロンの代替として、または ClickHouse server の内部コンポーネントとして使用できます。いずれの場合も、設定はほぼ同じ .xml ファイルで行います。

Keeper 設定項目

ClickHouse Keeper のメイン設定タグは <keeper_server> で、以下のパラメータを使用できます。

Parameter Description Default
tcp_port クライアント接続用のポート。 2181
tcp_port_secure クライアントと keeper-server 間の SSL 接続用セキュアポート。 -
server_id 一意の server id。ClickHouse Keeper クラスターの各参加ノードには、一意の番号 (1、2、3…) が必要です。 -
log_storage_path 協調ログのパス。ZooKeeper と同様に、ログは負荷の低いノードに保存するのが最適です。 -
snapshot_storage_path 協調スナップショットのパス。 -
enable_reconfiguration reconfig による動的なクラスター再構成を有効にします。 False
max_memory_usage_soft_limit keeper の最大メモリ使用量のソフトリミット (バイト単位) 。 max_memory_usage_soft_limit_ratio * physical_memory_amount
max_memory_usage_soft_limit_ratio max_memory_usage_soft_limit が未設定、または 0 に設定されている場合、この値を使ってデフォルトのソフトリミットを決定します。 0.9
cgroups_memory_observer_wait_time max_memory_usage_soft_limit が未設定、または 0 に設定されている場合、この間隔で物理メモリ量を監視します。メモリ量が変化すると、max_memory_usage_soft_limit_ratio に基づいて Keeper のメモリソフトリミットを再計算します。 15
http_control HTTP control インターフェイスの設定。 -
digest_enabled リアルタイムのデータ整合性チェックを有効にします。 True
create_snapshot_on_exit シャットダウン時にスナップショットを作成します。 -
hostname_checks_enabled クラスター設定に対する hostname の妥当性チェックを有効にします (例: リモート endpoint に対して localhost が使用されている場合) 。 True
four_letter_word_white_list 4lw コマンドのホワイトリスト。 conf, cons, crst, envi, ruok, srst, srvr, stat, wchs, dirs, mntr, isro, rcvr, apiv, csnp, lgif, rqld, ydld
enable_ipv6 IPv6 を有効にします。 True

その他の一般的なパラメータは、ClickHouse server の設定 (listen_hostlogger など) から継承されます。

内部協調設定

内部協調設定は <keeper_server>.<coordination_settings> セクションにあり、次のパラメータがあります。

パラメータ 説明 デフォルト
operation_timeout_ms 1 回のクライアント操作のタイムアウト (ms) 10000
min_session_timeout_ms クライアントセッションの最小タイムアウト (ms) 10000
session_timeout_ms クライアントセッションの最大タイムアウト (ms) 100000
dead_session_check_period_ms ClickHouse Keeper が切れたセッションをチェックして削除する間隔 (ms) 500
heart_beat_interval_ms ClickHouse Keeper のリーダーがフォロワーにハートビートを送信する間隔 (ms) 500
election_timeout_lower_bound_ms フォロワーがこの時間内にリーダーからハートビートを受信しなかった場合、リーダー選出を開始できます。election_timeout_upper_bound_ms 以下である必要があります。理想的には、両者は同じ値にしないでください。 1000
election_timeout_upper_bound_ms フォロワーがこの時間内にリーダーからハートビートを受信しなかった場合、リーダー選出を開始しなければなりません。 2000
rotate_log_storage_interval 1 つのファイルに保存するログレコード数。 100000
reserved_log_items compaction を実行するまでに保持する協調ログレコード数。 100000
snapshot_distance ClickHouse Keeper が新しいスナップショットを作成する間隔 (ログ内のレコード数ベース) 。 100000
snapshots_to_keep 保持するスナップショットの数。 3
stale_log_gap リーダーがフォロワーを stale と見なし、ログの代わりにスナップショットを送信するしきい値。 10000
fresh_log_gap ノードが fresh と見なされるしきい値。 200
max_requests_batch_size RAFT に送信する前の、リクエスト数ベースの Batch の最大サイズ。 100
force_sync 協調ログへの書き込みごとに fsync を呼び出します。 true
quorum_reads 読み取りリクエストを、同程度の速度で RAFT コンセンサス全体を通る書き込みとして実行します。 false
raft_logs_level 協調に関するテキストログのログレベル (trace、debug など) 。 system default
auto_forwarding フォロワーからリーダーへの書き込みリクエストの転送を許可します。 true
shutdown_timeout 内部接続の終了とシャットダウンの完了を待機する時間 (ms) 。 5000
startup_timeout サーバーが指定されたタイムアウト内に他のクォーラム参加者に接続できない場合、終了します (ms) 。 30000
async_replication 非同期レプリケーションを有効にします。書き込みと読み取りの保証はすべて維持したまま、より高いパフォーマンスを実現します。後方互換性を損なわないよう、この設定はデフォルトで無効になっています false
latest_logs_cache_size_threshold 最新の log entries を保持するインメモリ cache の合計最大サイズ 1GiB
commit_logs_cache_size_threshold 非推奨。この設定自体が設定されていない場合、log_readahead_commit_window_bytes に使用されます。 -
commit_logs_cache_entry_count_threshold 非推奨。効果はありません。代わりに log_readahead_commit_window_bytes を使用してください。 -
log_readahead_enabled changelog の catch-up 読み取り (フォロワーレプリケーション) 向けに、ピアごとのデコード済み先読みを有効にします。 false
log_readahead_window_bytes ピア reader ごとにバッファリングするデコード済みエントリの最大バイト数。通常の append-entries Batch 以上にする必要があります。 64MiB
log_readahead_max_peer_readers 同時実行するピアごとの先読み reader の最大数。 8
log_readahead_eviction_timeout_ms 非アクティブなピアごとの先読み reader または commit reader を追い出すまでのアイドルタイムアウト (後続のミスで再作成されます) 。 30000
log_readahead_pool_threads 専用の先読み thread pool 内のスレッド数。0 の場合は log_readahead_max_peer_readers から値を導出します。 0
log_readahead_serve_wait_timeout_ms 直接読み取りにフォールバックする前に、バックグラウンドでの先読みの充填を待機する最大時間。 200
log_readahead_chunk_size 先読み補完タスクで chunk ごとにデコードする log entries の数。 16
log_readahead_commit_window_bytes commit スレッドに先行して buffer するデコード済み log entries の合計最大サイズ。0 は commit の先読みを無効にします (commit はエントリをディスクから 1 件ずつ読み取ります)。 500MiB
log_startup_read_max_streams Keeper の起動時に同時に読み取る changelog ファイルの最大数。0 = CPU コア数を自動的に使用します。1 = 直列 (並列化前) の起動時読み取りを使用します。有効な並列度は読み取る必要がある changelog ファイル数によって制限されます。seek 制約のあるストレージ (HDD、IOPS が制限された volume) では値を下げることを検討してください。 0
log_startup_read_buffer_size Keeper の起動時に changelog を読み取る際に使用する、stream ごとの読み取りバッファサイズ (バイト)。0 より大きくする必要があります。バッファはさらにファイルサイズまでに制限されます。 8MiB
disk_move_retries_wait_ms ファイルをディスク間で移動中に失敗した場合、再試行までに待機する時間 1000
disk_move_retries_during_init 初期化中にファイルをディスク間で移動中に失敗した場合の再試行回数 100
experimental_use_rocksdb バックエンドストレージとして rocksdb を使用します 0

クォーラムの設定は <keeper_server>.<raft_configuration> セクションにあり、サーバーの定義が含まれます。

クォーラム全体に対する唯一のパラメーターは secure で、クォーラム参加者間の通信に暗号化接続を有効にします。ノード間の内部通信に SSL 接続が必要な場合は、このパラメーターを true に設定します。それ以外の場合は指定する必要はありません。

<server> の主なパラメーターは次のとおりです。

  • id — クォーラム内でのサーバー識別子。
  • hostname — このサーバーが配置されているホスト名。
  • port — このサーバーが接続を待ち受けるポート。
  • can_become_leader — サーバーを learner として構成するには false に設定します。省略した場合の値は true です。

3 ノードのクォーラム向けの設定例は、test_keeper_ プレフィックスを持つ 結合テスト にあります。サーバー #1 の設定例:

<keeper_server>
    <tcp_port>2181</tcp_port>
    <server_id>1</server_id>
    <log_storage_path>/var/lib/clickhouse/coordination/log</log_storage_path>
    <snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>

    <coordination_settings>
        <operation_timeout_ms>10000</operation_timeout_ms>
        <session_timeout_ms>30000</session_timeout_ms>
        <raft_logs_level>trace</raft_logs_level>
    </coordination_settings>

    <raft_configuration>
        <server>
            <id>1</id>
            <hostname>zoo1</hostname>
            <port>9234</port>
        </server>
        <server>
            <id>2</id>
            <hostname>zoo2</hostname>
            <port>9234</port>
        </server>
        <server>
            <id>3</id>
            <hostname>zoo3</hostname>
            <port>9234</port>
        </server>
    </raft_configuration>
</keeper_server>

実行方法

ClickHouse Keeper は ClickHouse server パッケージに同梱されているため、/etc/your_path_to_config/clickhouse-server/config.xml<keeper_server> の設定を追加し、通常どおり ClickHouse server を起動するだけです。スタンドアロンの ClickHouse Keeper を実行する場合も、同様に次のように起動できます。

clickhouse-keeper --config /etc/your_path_to_config/config.xml

シンボリックリンク (clickhouse-keeper) がない場合は、それを作成するか、clickhouse の引数として keeper を指定できます。

clickhouse keeper --config /etc/your_path_to_config/config.xml

4文字コマンド

ClickHouse Keeper は、ZooKeeper とほぼ同じ 4lw コマンドも提供しています。各コマンドは mntrstat などのように 4 文字で構成されています。さらに、いくつかの便利なコマンドがあります。stat は server と接続中のクライアントに関する一般的な情報を返し、srvr は server の詳細情報を返し、cons は connections の詳細情報を返します。

4lw コマンドには four_letter_word_white_list というホワイトリスト設定があり、そのデフォルト値は conf,cons,crst,envi,ruok,srst,srvr,stat,wchs,dirs,mntr,isro,rcvr,apiv,csnp,lgif,rqld,ydld です。

これらのコマンドは、クライアントポートに対して telnet または nc 経由で ClickHouse Keeper に送信できます。

echo mntr | nc localhost 9181

以下に、4lw コマンドの詳細を示します。

  • ruok: サーバーがエラーのない状態で稼働しているかどうかをテストします。稼働している場合、サーバーは imok を返します。そうでない場合は、まったく応答しません。imok という応答は、サーバーがクォーラムに参加していることを必ずしも意味せず、サーバープロセスがアクティブで、指定されたクライアントポートにバインドされていることを示すだけです。クォーラムに関する状態やクライアント接続情報の詳細については、"stat" を使用してください。
imok
  • mntr: クラスターの健全性の監視に使用できる変数の一覧を出力します。
zk_version      v21.11.1.1-prestable-7a4a0b0edef0ad6e0aa662cd3b90c3f4acf796e7
zk_avg_latency  0
zk_max_latency  0
zk_min_latency  0
zk_packets_received     68
zk_packets_sent 68
zk_num_alive_connections        1
zk_outstanding_requests 0
zk_server_state leader
zk_znode_count  4
zk_watch_count  1
zk_ephemerals_count     0
zk_approximate_data_size        723
zk_open_file_descriptor_count   310
zk_max_file_descriptor_count    10240
zk_leader_uptime        1234
zk_sum_leader_unavailable_time 1234
zk_cnt_leader_unavailable_time 1
zk_sum_election_time 1234
zk_cnt_election_time 1
zk_followers    0
zk_synced_followers     0

zk_sum_leader_unavailable_timezk_cnt_leader_unavailable_timezk_sum_election_timezk_cnt_election_time は、リーダー 専用の累積メトリクスです。これらはサーバーごとの観測値であり、クラスター全体の可用性を示す測定値ではありません。追跡は、そのサーバーが稼働中の リーダー を観測しなくなった時点で開始されます。ネットワークパーティション中は、古い リーダー が別のパーティションで稼働し続けている時間も含まれる場合があります。選出メトリクスには、このようにローカルで観測された リーダー 不在期間の後に成功した選出のみが記録されます。サンプリング時に リーダー 不在状態が検出されないリーダーシップの移行は、意図的にカウントされません。

Keeper はローカルの NuRaft リーダー 状態を heart_beat_interval_ms ごとにサンプリングしますが、その頻度は最大でも 100 ミリ秒ごとです。各期間の境界は、ローカル状態の遷移時点から有効間隔分までずれる可能性があり、その間隔より短い期間は見逃される可能性があります。Keeper は NuRaft の BecomeLeader 時にローカルでの選出完了を記録します。srst は 4 つすべての値をリセットします。

各種類について直近にローカルで観測された期間の長さも、system.asynchronous_metricsKeeperLastLeaderElectionTime および KeeperLastLeaderUnavailableTime としてミリ秒単位でエクスポートされます。KeeperLastLeaderElectionTimezk_sum_election_time と同じ リーダー 不在期間の定義に従います。どちらも リーダー 専用です。アクティブな リーダー ではないノード、またはまだ期間を完了していないノードは、0 を報告します。srst は累積カウンターとともにこれらもリセットします。

  • srvr: サーバーの詳細情報を一覧表示します。
ClickHouse Keeper version: v21.11.1.1-prestable-7a4a0b0edef0ad6e0aa662cd3b90c3f4acf796e7
Latency min/avg/max: 0/0/0
Received: 2
Sent : 2
Connections: 1
Outstanding: 0
Zxid: 34
Mode: leader
Node count: 4
  • stat: サーバーと接続中のクライアントの概要を一覧表示します。
ClickHouse Keeper version: v21.11.1.1-prestable-7a4a0b0edef0ad6e0aa662cd3b90c3f4acf796e7
Clients:
 192.168.1.1:52852(recved=0,sent=0)
 192.168.1.1:52042(recved=24,sent=48)
Latency min/avg/max: 0/0/0
Received: 4
Sent : 4
Connections: 1
Outstanding: 0
Zxid: 36
Mode: leader
Node count: 4
  • srst: サーバー統計をリセットします。このコマンドは srvrmntrstat の結果に影響します。
Server stats reset.
  • conf: サーバー構成の詳細を表示します。
server_id=1
tcp_port=2181
four_letter_word_white_list=*
log_storage_path=./coordination/logs
snapshot_storage_path=./coordination/snapshots
max_requests_batch_size=100
session_timeout_ms=30000
operation_timeout_ms=10000
dead_session_check_period_ms=500
heart_beat_interval_ms=500
election_timeout_lower_bound_ms=1000
election_timeout_upper_bound_ms=2000
reserved_log_items=1000000000000000
snapshot_distance=10000
auto_forwarding=true
shutdown_timeout=5000
startup_timeout=240000
raft_logs_level=information
snapshots_to_keep=3
rotate_log_storage_interval=100000
stale_log_gap=10000
fresh_log_gap=200
max_requests_batch_size=100
quorum_reads=false
force_sync=false
compress_logs=true
compress_snapshots_with_zstd_format=true
configuration_change_tries_count=20
  • cons: このサーバーに接続しているすべてのクライアントの接続/セッションの詳細を一覧表示します。受信/送信したパケット数、セッション ID、操作レイテンシ、最後に実行された操作などの情報が含まれます…
 192.168.1.1:52163(recved=0,sent=0,sid=0xffffffffffffffff,lop=NA,est=1636454787393,to=30000,lzxid=0xffffffffffffffff,lresp=0,llat=0,minlat=0,avglat=0,maxlat=0)
 192.168.1.1:52042(recved=9,sent=18,sid=0x0000000000000001,lop=List,est=1636454739887,to=30000,lcxid=0x0000000000000005,lzxid=0x0000000000000005,lresp=1636454739892,llat=0,minlat=0,avglat=0,maxlat=0)
  • crst: すべての接続の connection/session 統計をリセットします。
Connection stats reset.
  • envi: 実行環境の詳細を表示
Environment:
clickhouse.keeper.version=v21.11.1.1-prestable-7a4a0b0edef0ad6e0aa662cd3b90c3f4acf796e7
host.name=ZBMAC-C02D4054M.local
os.name=Darwin
os.arch=x86_64
os.version=19.6.0
cpu.count=12
user.name=root
user.home=/Users/JackyWoo/
user.dir=/Users/JackyWoo/project/jd/clickhouse/cmake-build-debug/programs/
user.tmp=/var/folders/b4/smbq5mfj7578f2jzwn602tt40000gn/T/
  • dirs: スナップショットおよびログファイルの合計サイズをバイト単位で表示
snapshot_dir_size: 0
log_dir_size: 3875
  • isro: サーバーが読み取り専用モードで稼働しているかどうかを確認します。読み取り専用モードの場合、サーバーは ro を返し、そうでない場合は rw を返します。
rw
  • wchs: サーバーのウォッチに関する概要を一覧表示します。
1 connections watching 1 paths
Total watches:1
  • wchc: サーバーのウォッチに関する詳細情報を、セッションごとに一覧表示します。ウォッチ (パス) に関連付けられたセッション (接続) の一覧が出力されます。なお、ウォッチ数によってはこの操作の負荷が高くなり、サーバーのパフォーマンスに影響する可能性があるため、注意して使用してください。
0x0000000000000001
    /clickhouse/task_queue/ddl
  • wchp: サーバーのウォッチに関する詳細情報を、パスごとに一覧表示します。関連するセッションとともに、パス (znode) の一覧が出力されます。なお、ウォッチ数によってはこの操作のコストが高くなり (つまり、サーバーのパフォーマンスに影響する可能性があり) 、慎重に使用してください。
/clickhouse/task_queue/ddl
    0x0000000000000001
  • dump: 残っているセッションとエフェメラルノードを一覧表示します。これはリーダーでのみ機能します。
Sessions dump (2):
0x0000000000000001
0x0000000000000002
Sessions with Ephemerals (1):
0x0000000000000001
 /clickhouse/task_queue/ddl
  • csnp: スナップショット作成タスクをスケジュールします。成功した場合は、スケジュールされたスナップショットの最後にコミットされたログインデックスを返し、失敗した場合は Failed to schedule snapshot creation task. を返します。スナップショットが完了したかどうかは、lgif コマンドで確認できます。
100
  • lgif: Keeper のログ情報。first_log_idx : ログストア内の最初のログインデックス; first_log_term : 最初のログターム; last_log_idx : ログストア内の最後のログインデックス; last_log_term : 最後のログターム; last_committed_log_idx : ステートマシン内で最後にコミットされたログインデックス; leader_committed_log_idx : 自分から見たリーダーのコミット済みログインデックス; target_committed_log_idx : コミットされるべき対象のログインデックス; last_snapshot_idx : 最後のスナップショットにおける、コミット済みログインデックスの最大値。
first_log_idx   1
first_log_term  1
last_log_idx    101
last_log_term   1
last_committed_log_idx  100
leader_committed_log_idx    101
target_committed_log_idx    101
last_snapshot_idx   50
  • rqld: 新しいリーダーになるためのリクエストを送信します。リクエストが送信された場合は Sent leadership request to leader. を返し、送信されなかった場合は Failed to send leadership request to leader. を返します。ノードがすでにリーダーの場合も、リクエストが送信された場合と同じ結果になります。
Sent leadership request to leader.
  • ftfl: すべての 機能フラグ と、それらが Keeper インスタンスで enabled かどうかを一覧表示します。
filtered_list   1
multi_read  1
check_not_exists    0
  • ydld: リーダー権限を譲り、フォロワーになるようリクエストします。リクエストを受信したサーバーがリーダーの場合、まず書き込み操作を一時停止し、後継ノード (現在のリーダーが後継ノードになることはありません) が最新のログへの追いつきを完了するまで待ってから、リーダーを辞任します。後継ノードは自動的に選択されます。リクエストが送信された場合は Sent yield leadership request to leader. を、送信されなかった場合は Failed to send yield leadership request to leader. を返します。ノードがすでにフォロワーの場合も、リクエストが送信された場合と同じ結果になります。
Sent yield leadership request to leader.
  • pfev: 収集されたすべてのイベントについて、イベント名、イベント値、イベントの説明を返します。
FileOpen        62      Number of files opened.
Seek    4       Number of times the 'lseek' function was called.
ReadBufferFromFileDescriptorRead        126     Number of reads (read/pread) from a file descriptor. Does not include sockets.
ReadBufferFromFileDescriptorReadFailed  0       Number of times the read (read/pread) from a file descriptor have failed.
ReadBufferFromFileDescriptorReadBytes   178846  Number of bytes read from file descriptors. If the file is compressed, this will show the compressed data size.
WriteBufferFromFileDescriptorWrite      7       Number of writes (write/pwrite) to a file descriptor. Does not include sockets.
WriteBufferFromFileDescriptorWriteFailed        0       Number of times the write (write/pwrite) to a file descriptor have failed.
WriteBufferFromFileDescriptorWriteBytes 153     Number of bytes written to file descriptors. If the file is compressed, this will show compressed data size.
FileSync        2       Number of times the F_FULLFSYNC/fsync/fdatasync function was called for files.
DirectorySync   0       Number of times the F_FULLFSYNC/fsync/fdatasync function was called for directories.
FileSyncElapsedMicroseconds     12756   Total time spent waiting for F_FULLFSYNC/fsync/fdatasync syscall for files.
DirectorySyncElapsedMicroseconds        0       Total time spent waiting for F_FULLFSYNC/fsync/fdatasync syscall for directories.
ReadCompressedBytes     0       Number of bytes (the number of bytes before decompression) read from compressed sources (files, network).
CompressedReadBufferBlocks      0       Number of compressed blocks (the blocks of data that are compressed independent of each other) read from compressed sources (files, network).
CompressedReadBufferBytes       0       Number of uncompressed bytes (the number of bytes after decompression) read from compressed sources (files, network).
AIOWrite        0       Number of writes with Linux or FreeBSD AIO interface
AIOWriteBytes   0       Number of bytes written with Linux or FreeBSD AIO interface
...

HTTP 制御

ClickHouse Keeper は、レプリカがトラフィックを受け付ける準備ができているかどうかを確認するための HTTP インターフェイスを提供します。これは、Kubernetes などのクラウド環境で利用できます。

/ready エンドポイントを有効にする設定例:

<clickhouse>
    <keeper_server>
        <http_control>
            <port>9182</port>
            <readiness>
                <endpoint>/ready</endpoint>
            </readiness>
        </http_control>
    </keeper_server>
</clickhouse>

機能フラグ

Keeper は ZooKeeper およびそのクライアントと完全な互換性がありますが、ClickHouse client で利用できる独自の機能やリクエストタイプもいくつか導入しています。 これらの機能は後方互換性を持たない変更を引き起こす可能性があるため、その多くはデフォルトで無効になっており、keeper_server.feature_flags 設定で有効にできます。 すべての機能を明示的に無効にすることもできます。 Keeper クラスターで新しい機能を有効にする場合は、まずクラスター内のすべての Keeper インスタンスをその機能をサポートするバージョンに更新してから、機能自体を有効にすることを推奨します。

multi_read を無効にし、check_not_exists を有効にする機能フラグ設定の例:

<clickhouse>
    <keeper_server>
        <feature_flags>
            <multi_read>0</multi_read>
            <check_not_exists>1</check_not_exists>
        </feature_flags>
    </keeper_server>
</clickhouse>

以下の機能が利用できます。

Feature Description Default
multi_read 複数の読み取りリクエストをサポート 1
filtered_list ノードの種類 (ephemeral または persistent) で結果を絞り込む list リクエストをサポート 1
check_not_exists ノードが存在しないことを確認する CheckNotExists リクエストをサポート 1
create_if_not_exists CreateIfNotExists リクエストをサポートします。ノードが存在しない場合は作成を試み、存在する場合は変更を加えずに ZOK を返します。 1
remove_recursive ノードとそのサブツリーをまとめて削除する RemoveRecursive リクエストをサポート 1

ZooKeeper からの移行

ZooKeeper から ClickHouse Keeper へのシームレスな移行はできません。ZooKeeper クラスターを停止し、データを変換したうえで、ClickHouse Keeper を起動する必要があります。clickhouse-keeper-converter ツールは、ZooKeeper のログとスナップショットを ClickHouse Keeper のスナップショットに変換します。ZooKeeper 3.4 以降が必要です。

移行前の準備

移行を行うには、データのインジェストを停止する必要があります。開始前にメンテナンスウィンドウを確保してください。

ZooKeeper を停止する前に、協調用メタデータを変更する ClickHouse のバックグラウンドタスクを停止してください。例えば:

SYSTEM STOP MERGES;

移行後に整合性を確認できるよう、移行前に比較用のメトリクスを記録しておきます。

移行手順

  1. すべての ClickHouse ノードへのデータのインジェストを停止します。

  2. すべての ClickHouse ノードで、すべてのバックグラウンドタスクを停止します (上記を参照) 。

  3. すべての ZooKeeper ノードを停止します。

  4. 任意ですが、推奨します: ZooKeeper のリーダーノードを特定し、起動してから再度停止します。これにより、変換前に ZooKeeper が整合性のあるスナップショットをディスクに書き込むよう強制できます。

  5. リーダーノードで clickhouse-keeper-converter を実行します。ClickHouse の完全なバイナリがインストールされている場合は、代わりに keeper-converter サブコマンド (clickhouse keeper-converter) を使用します。どちらも利用できない場合は、バイナリをダウンロードしてください。

clickhouse-keeper-converter \
  --zookeeper-logs-dir /var/lib/zookeeper/version-2 \
  --zookeeper-snapshots-dir /var/lib/zookeeper/version-2 \
  --output-dir /path/to/clickhouse/keeper/snapshots
  1. スナップショットをすべての ClickHouse Keeper ノードにコピーします。どのノードも起動する前に、すべてのノードにスナップショットが存在している必要があります。スナップショットがないままノードが起動すると、空の状態で自らをリーダーに選出してしまう可能性があります。

  2. 新しい Keeper クラスターを参照するように ClickHouse の設定を更新します。

  3. すべてのノードで ClickHouse Keeper を起動し、その後 ClickHouse を再起動します。

  4. 整合性を確認するため、移行前のベースラインとメトリクスを比較します。

  5. バックグラウンドタスクを再開し、データのインジェストを再開します。

複数の ZooKeeper クラスターの統合

複数の ZooKeeper クラスター (たとえば分片グループごとに 1 つ) を運用している場合は、それらを 1 つの ClickHouse Keeper クラスターに統合できます。公式の clickhouse-keeper-converter ツールがサポートしているのは 1 対 1 の変換 (1 つの ZooKeeper クラスターから 1 つの Keeper スナップショットへの変換) のみであるため、統合するには converter のソースコードを修正し、複数のスナップショットをマージする必要があります。

  1. 各 ZooKeeper クラスターに対して clickhouse-keeper-converter を個別に実行し、それぞれの出力を別々のディレクトリに書き込みます。
  2. スナップショットファイルを順番にデシリアライズします。マージ時には、異なるソースクラスターのネームスペース間でノード ID の競合が発生しないよう、numChildren の値を再計算します。
  3. マージした出力を、対象の ClickHouse Keeper スナップショット用ディレクトリに書き込みます。

暗号化とACLの取り扱い

ClickHouse Keeper は、ZooKeeper と同じ ACL スキーム (worldauthdigest) をサポートしています。変換時に ACL をどのように扱うかは、ZooKeeper の構成によって異なります。

  • 完全に暗号化されている、またはまったく暗号化されていない: そのまま変換できます。コンバーターは既存の ACL 情報を保持します。
  • 部分的に暗号化されている: 変換前にスーパー管理者アカウントに権限を付与し、影響を受けるパスで setAcl -R を使って ACL をクリアします。変換後、必要に応じて ClickHouse Keeper で暗号化を再度有効にしてください。

移行の検証

ClickHouse Keeper を起動し、ClickHouse を再起動したら、移行が正常に完了したことを確認するために、主要なメトリクスを移行前のベースラインと比較します。

複数の ZooKeeper クラスターを統合する場合は、次の違いを区別してください。

  • 共通パス: 複数のソースクラスターに同一データで存在するパス。これらは、マージ後の出力で重複排除する必要があります。
  • 固有のパス: 特定のクラスター配下にのみ存在するパス (例: 各分片グループの /clickhouse/tables 配下) 。これらは、正しいソースのものを保持する必要があります。

比較のために大規模な ZooKeeper ツリーを直接走査するのは避けてください。代わりに、変換時に変換したすべてのパスをファイルに出力してください。

移行後のチューニング

移行後は、より大規模なクラスターや、より高いスループットが必要な場合に備えて、以下の設定を調整することを検討してください。

設定 デフォルト 推奨値 注記
max_requests_batch_size 100 10000 パート数や分片数が多いクラスターでは値を増やしてください
force_sync true false ログ書き込みを非同期にすると、スループットが向上します
compress_logs false true Raft のログファイルを圧縮して、ディスク I/O を削減します
compress_snapshots_with_zstd_format true 既定で有効になっており、zstd でスナップショットを圧縮します

これらの設定は、Keeper の設定coordination_settings で構成します。

クォーラム喪失後の復旧

ClickHouse Keeper は Raft を使用しているため、クラスターのサイズに応じて一定数のノード障害に耐えられます。 たとえば、3 ノードのクラスターであれば、1 ノードだけが停止しても正常に動作を継続できます。

クラスター構成は動的に変更できますが、いくつか制約があります。再構成も Raft に依存しているため、 クラスターにノードを追加または削除するにはクォーラムが必要です。クラスター内で同時に多くのノードを失い、 しかもそれらを再起動できる見込みがない場合、Raft は動作を停止し、通常の方法ではクラスターを再構成できなくなります。

それでも、ClickHouse Keeper には、1 ノードだけでクラスターを強制的に再構成できる復旧モードがあります。 これは、ノードを再起動できない場合や、同じエンドポイントで新しいインスタンスを起動できない場合の最終手段としてのみ使用してください。

続行する前に、次の重要な点に注意してください。

  • 障害が発生したノードが再びクラスターに接続できないことを確認してください。
  • 手順で指示があるまでは、新しいノードをいずれも起動しないでください。

上記を確認したら、次の作業を行ってください。

  1. 新しいリーダーとする Keeper ノードを 1 つ選びます。そのノードのデータがクラスター全体で使われるため、できるだけ最新の状態を持つノードを使用することを推奨します。
  2. ほかの作業を行う前に、選択したノードの log_storage_path および snapshot_storage_path フォルダーのバックアップを作成します。
  3. 使用する予定のすべてのノードでクラスターを再構成します。
  4. 選択したノードに 4 文字コマンド rcvr を送信してそのノードを復旧モードに移行するか、または選択したノード上の Keeper インスタンスを停止し、--force-recovery 引数を付けて再起動します。
  5. 新しいノード上で Keeper インスタンスを 1 つずつ起動し、次のノードを起動する前に mntrzk_server_state に対して follower を返すことを確認します。
  6. 復旧モード中、リーダーノードは新しいノードとのクォーラムが成立するまで、mntr コマンドに対してエラーメッセージを返し、クライアントおよびフォロワーからのあらゆるリクエストを拒否します。
  7. クォーラムが成立すると、リーダーノードは通常動作モードに戻り、すべてのリクエストを受け付けます。mntr で確認すると、zk_server_state に対して leader が返るはずです。

Keeper でディスクを使用する

Keeper は、スナップショット、ログファイル、状態ファイルの保存先として、外部ディスク の一部をサポートしています。

サポートされているディスクの種類は次のとおりです。

  • s3_plain
  • s3
  • local

以下は、設定に含まれるディスク定義の例です。

<clickhouse>
    <storage_configuration>
        <disks>
            <log_local>
                <type>local</type>
                <path>/var/lib/clickhouse/coordination/logs/</path>
            </log_local>
            <log_s3_plain>
                <type>s3_plain</type>
                <endpoint>https://some_s3_endpoint/logs/</endpoint>
                <access_key_id>ACCESS_KEY</access_key_id>
                <secret_access_key>SECRET_KEY</secret_access_key>
            </log_s3_plain>
            <snapshot_local>
                <type>local</type>
                <path>/var/lib/clickhouse/coordination/snapshots/</path>
            </snapshot_local>
            <snapshot_s3_plain>
                <type>s3_plain</type>
                <endpoint>https://some_s3_endpoint/snapshots/</endpoint>
                <access_key_id>ACCESS_KEY</access_key_id>
                <secret_access_key>SECRET_KEY</secret_access_key>
            </snapshot_s3_plain>
            <state_s3_plain>
                <type>s3_plain</type>
                <endpoint>https://some_s3_endpoint/state/</endpoint>
                <access_key_id>ACCESS_KEY</access_key_id>
                <secret_access_key>SECRET_KEY</secret_access_key>
            </state_s3_plain>
        </disks>
    </storage_configuration>
</clickhouse>

ログ用にディスクを使用するには、keeper_server.log_storage_disk 設定にディスク名を指定する必要があります。 スナップショット用にディスクを使用するには、keeper_server.snapshot_storage_disk 設定にディスク名を指定する必要があります。 さらに、最新のログには keeper_server.latest_log_storage_disk、最新のスナップショットには keeper_server.latest_snapshot_storage_disk を使用できます。 その場合、新しいログまたはスナップショットが作成されると、Keeper は自動的にファイルを適切なディスクに移動します。 state ファイル用にディスクを使用するには、keeper_server.state_storage_disk 設定にディスク名を指定する必要があります。

ディスク間でのファイル移動は安全で、転送の途中で Keeper が停止してもデータが失われることはありません。 ファイルが新しいディスクに完全に移動されるまでは、元のディスクから削除されません。

keeper_server.coordination_settings.force_synctrue に設定した Keeper (デフォルトは true) では、すべての種類のディスクに対して一部の保証を満たせません。 現時点で永続 sync をサポートしているのは、local 型のディスクのみです。 force_sync を使用する場合、latest_log_storage_disk を使用しないのであれば、log_storage_disklocal ディスクである必要があります。 latest_log_storage_disk を使用する場合は、常に local ディスクである必要があります。 force_sync を無効にすると、どの種類のディスクでも、どの構成でも使用できます。

Keeper インスタンスのストレージ構成例は、次のようになります。

<clickhouse>
    <keeper_server>
        <log_storage_disk>log_s3_plain</log_storage_disk>
        <latest_log_storage_disk>log_local</latest_log_storage_disk>

        <snapshot_storage_disk>snapshot_s3_plain</snapshot_storage_disk>
        <latest_snapshot_storage_disk>snapshot_local</latest_snapshot_storage_disk>
    </keeper_server>
</clickhouse>

このインスタンスでは、最新のログを除くすべてのログはディスク log_s3_plain に保存され、最新のログはディスク log_local に保存されます。 同様に、スナップショットについても、最新のスナップショットを除くすべてのスナップショットは snapshot_s3_plain に保存され、最新のスナップショットはディスク snapshot_local に保存されます。

ディスク構成の変更

階層化されたディスク構成が定義されている場合 (最新のファイル用に別のディスクを使用する場合) 、Keeper は起動時にファイルを適切なディスクへ自動的に移動しようとします。 従来と同じ保証が適用されます。ファイルが新しいディスクへの移動を完全に終えるまでは古いディスクから削除されないため、複数回再起動しても 安全です。

ファイルをまったく新しいディスクに移動する必要がある場合 (または 2 ディスク構成から単一ディスク構成に移行する場合) は、keeper_server.old_snapshot_storage_diskkeeper_server.old_log_storage_disk を複数定義できます。

次の設定は、以前の 2 ディスク構成から、まったく新しい単一ディスク構成へ移行する方法を示しています。

<clickhouse>
    <keeper_server>
        <old_log_storage_disk>log_local</old_log_storage_disk>
        <old_log_storage_disk>log_s3_plain</old_log_storage_disk>
        <log_storage_disk>log_local2</log_storage_disk>

        <old_snapshot_storage_disk>snapshot_s3_plain</old_snapshot_storage_disk>
        <old_snapshot_storage_disk>snapshot_local</old_snapshot_storage_disk>
        <snapshot_storage_disk>snapshot_local2</snapshot_storage_disk>
    </keeper_server>
</clickhouse>

起動時に、すべてのログファイルは log_locallog_s3_plain から log_local2 ディスクに移動されます。 また、すべてのスナップショットファイルは snapshot_localsnapshot_s3_plain から snapshot_local2 ディスクに移動されます。

ログキャッシュの設定

ディスクから読み取るデータ量を最小限に抑えるため、Keeper はログエントリをメモリにキャッシュします。 リクエストが大きい場合、ログエントリがメモリを過度に消費する可能性があるため、キャッシュするログの量には上限が設けられています。 最新ログキャッシュの上限は、次の設定で制御します。

  • latest_logs_cache_size_threshold - キャッシュに保存する最新ログの合計サイズ

デフォルト値が大きすぎる場合は、この設定を小さくすることでメモリ使用量を削減できます。

次のコミットで必要となるログエントリは、デコード済みの先読みリーダーによって提供されます。このリーダーのサイズは log_readahead_commit_window_bytes で指定します (0 を指定すると、コミット時の先読みが無効になります) 。この設定は、 非推奨の commit_logs_cache_size_threshold および commit_logs_cache_entry_count_threshold 設定を置き換えるものであり、 これらは設定の互換性のためにのみ残されています (前者は未設定の場合、引き続き log_readahead_commit_window_bytes にマッピングされます。 後者は効果がありません) 。同じ先読みメカニズムは、log_readahead_enabledtrue の場合、follower の レプリケーションのキャッチアップ読み取りにも使用されます。ピア側のチューニング パラメータについては、内部協調設定log_readahead_window_byteslog_readahead_max_peer_readerslog_readahead_eviction_timeout_mslog_readahead_pool_threadslog_readahead_serve_wait_timeout_ms、および log_readahead_chunk_size を参照してください。

Prometheus

Keeper は、Prometheus によるスクレイピング用にメトリクスデータを公開できます。

設定:

  • endpoint – Prometheus サーバーがメトリクスをスクレイピングするための HTTP エンドポイント。'/' で始まる必要があります。
  • portendpoint に使用するポート。
  • metricssystem.metrics テーブルのメトリクスを公開するかどうかを設定するフラグ。
  • eventssystem.events テーブルのメトリクスを公開するかどうかを設定するフラグ。
  • asynchronous_metricssystem.asynchronous_metrics テーブルの現在のメトリクス値を公開するかどうかを設定するフラグ。

<clickhouse>
    <listen_host>0.0.0.0</listen_host>
    <http_port>8123</http_port>
    <tcp_port>9000</tcp_port>
    <prometheus>
        <endpoint>/metrics</endpoint>
        <port>9363</port>
        <metrics>true</metrics>
        <events>true</events>
        <asynchronous_metrics>true</asynchronous_metrics>
    </prometheus>
</clickhouse>

確認してください (127.0.0.1 はご利用の ClickHouse server の IPアドレスまたはホスト名に置き換えてください) :

curl 127.0.0.1:9363/metrics

ClickHouse Cloud のPrometheus インテグレーションもご覧ください。

ClickHouse Keeper ユーザーガイド

このガイドでは、ClickHouse Keeper を設定するためのシンプルで最小限の構成と、分散処理をテストする方法の例を紹介します。この例では、Linux 上の 3 つのノードを使用します。

Keeper 設定を使用してノードを構成する

  1. 3 台のホスト (chnode1chnode2chnode3) に、3 つの ClickHouse インスタンスをインストールします。 (ClickHouse のインストール方法の詳細については、クイックスタートを参照してください。)

  2. 各ノードで、ネットワークインターフェイス経由の外部通信を許可するために、以下のエントリを追加します。

    <listen_host>0.0.0.0</listen_host>
  3. 以下のClickHouse Keeperの設定を3台すべてのサーバーに追加し、各サーバーの<server_id>設定を更新します。たとえば、chnode11chnode22となります。

    <keeper_server>
        <tcp_port>9181</tcp_port>
        <server_id>1</server_id>
        <log_storage_path>/var/lib/clickhouse/coordination/log</log_storage_path>
        <snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>
    
        <coordination_settings>
            <operation_timeout_ms>10000</operation_timeout_ms>
            <session_timeout_ms>30000</session_timeout_ms>
            <raft_logs_level>warning</raft_logs_level>
        </coordination_settings>
    
        <raft_configuration>
            <server>
                <id>1</id>
                <hostname>chnode1.domain.com</hostname>
                <port>9234</port>
            </server>
            <server>
                <id>2</id>
                <hostname>chnode2.domain.com</hostname>
                <port>9234</port>
            </server>
            <server>
                <id>3</id>
                <hostname>chnode3.domain.com</hostname>
                <port>9234</port>
            </server>
        </raft_configuration>
    </keeper_server>

    上記で使用した基本設定は以下のとおりです。

    パラメータ 説明
    tcp_port Keeper クライアントが使用するポート ZooKeeper の 2181 に相当するデフォルトの 9181
    server_id Raft 構成で使用する各 ClickHouse Keeper サーバーの識別子 1
    coordination_settings timeout などのパラメータを指定するセクション timeouts: 10000, log level: trace
    server 参加するサーバーの定義 各サーバー定義の一覧
    raft_configuration Keeper クラスター内の各サーバーに対する設定 各サーバーの server と settings
    id Keeper サービス用サーバーの数値 ID 1
    hostname Keeper クラスター内の各サーバーのホスト名、IP アドレス、または FQDN chnode1.domain.com
    port サーバー間の Keeper 接続を待ち受けるポート 9234
  4. ZooKeeper コンポーネントを有効にします。このコンポーネントでは ClickHouse Keeper エンジンを使用します:

        <zookeeper>
            <node>
                <host>chnode1.domain.com</host>
                <port>9181</port>
            </node>
            <node>
                <host>chnode2.domain.com</host>
                <port>9181</port>
            </node>
            <node>
                <host>chnode3.domain.com</host>
                <port>9181</port>
            </node>
        </zookeeper>

    上記で使用した基本設定は以下のとおりです。

    パラメータ 説明
    node ClickHouse Keeper 接続先ノードの一覧 各サーバーごとの設定エントリ
    host 各 ClickHouse Keeper ノードのホスト名、IP、または FQDN chnode1.domain.com
    port ClickHouse Keeper のクライアントポート 9181
  5. ClickHouse を再起動し、各 Keeper インスタンスが稼働していることを確認します。各サーバーで次のコマンドを実行してください。Keeper が稼働しており正常な状態であれば、ruok コマンドは imok を返します。

    # echo ruok | nc localhost 9181; echo
    imok
  6. system データベースには、ClickHouse Keeper の各インスタンスの詳細が格納された zookeeper という名前のテーブルがあります。では、このテーブルを見てみましょう。

    SELECT *
    FROM system.zookeeper
    WHERE path IN ('/', '/clickhouse')

    表は次のとおりです。

    ┌─name───────┬─value─┬─czxid─┬─mzxid─┬───────────────ctime─┬───────────────mtime─┬─version─┬─cversion─┬─aversion─┬─ephemeralOwner─┬─dataLength─┬─numChildren─┬─pzxid─┬─path────────┐
    │ clickhouse │       │   124 │   124 │ 2022-03-07 00:49:34 │ 2022-03-07 00:49:34 │       0 │        2 │        0 │              0 │          0 │           2 │  5693 │ /           │
    │ task_queue │       │   125 │   125 │ 2022-03-07 00:49:34 │ 2022-03-07 00:49:34 │       0 │        1 │        0 │              0 │          0 │           1 │   126 │ /clickhouse │
    │ tables     │       │  5693 │  5693 │ 2022-03-07 00:49:34 │ 2022-03-07 00:49:34 │       0 │        3 │        0 │              0 │          0 │           3 │  6461 │ /clickhouse │
    └────────────┴───────┴───────┴───────┴─────────────────────┴─────────────────────┴─────────┴──────────┴──────────┴────────────────┴────────────┴─────────────┴───────┴─────────────┘

ClickHouse でクラスターを構成する

  1. 2 台のノード上で、2 つの分片と各分片あたり 1 つのレプリカ בלבדのシンプルなクラスターを構成してみましょう。3 台目のノードは、ClickHouse Keeper の要件であるクォーラムを満たすために使用します。chnode1chnode2 の設定を更新します。以下のクラスターでは、各ノードに 1 つの分片を定義しているため、レプリケーションなしで合計 2 つの分片になります。この例では、データの一部は一方のノードに、残りはもう一方のノードに配置されます。

        <remote_servers>
            <cluster_2S_1R>
                <shard>
                    <replica>
                        <host>chnode1.domain.com</host>
                        <port>9000</port>
                        <user>default</user>
                        <password>ClickHouse123!</password>
                    </replica>
                </shard>
                <shard>
                    <replica>
                        <host>chnode2.domain.com</host>
                        <port>9000</port>
                        <user>default</user>
                        <password>ClickHouse123!</password>
                    </replica>
                </shard>
            </cluster_2S_1R>
        </remote_servers>
    パラメータ 説明
    shard クラスター定義内のレプリカの一覧 各分片のレプリカ一覧
    replica 各レプリカの設定一覧 各レプリカの設定エントリ
    host レプリカ分片をホストするサーバーのホスト名、IP、または FQDN chnode1.domain.com
    port native TCP プロトコルで通信するためのポート 9000
    user クラスターの各インスタンスへの認証に使用する username default
    password クラスターの各インスタンスへの接続を許可するために定義されたユーザーの password ClickHouse123!
  2. ClickHouse を再起動し、クラスターが作成されたことを確認します。

    SHOW clusters;

    クラスターが表示されるはずです。

    ┌─cluster───────┐
    │ cluster_2S_1R │
    └───────────────┘

分散テーブルの作成とテスト

  1. chnode1 上の ClickHouse client を使用して、新しいクラスターに新しいデータベースを作成します。ON CLUSTER 句により、両方のノードにデータベースが自動的に作成されます。

    CREATE DATABASE db1 ON CLUSTER 'cluster_2S_1R';
  2. db1 データベースに新しいテーブルを作成します。今回も、ON CLUSTER によって両方のノードにテーブルが作成されます。

    CREATE TABLE db1.table1 on cluster 'cluster_2S_1R'
    (
        `id` UInt64,
        `column1` String
    )
    ENGINE = MergeTree
    ORDER BY column1
  3. chnode1 ノードで、2 行のデータを追加します。

    INSERT INTO db1.table1
        (id, column1)
    VALUES
        (1, 'abc'),
        (2, 'def')
  4. chnode2 ノードでも、2 行のデータを追加します。

    INSERT INTO db1.table1
        (id, column1)
    VALUES
        (3, 'ghi'),
        (4, 'jkl')
  5. 各ノードで SELECT ステートメントを実行すると、そのノード上のデータしか表示されないことに注目してください。たとえば、chnode1 では次のようになります。

    SELECT *
    FROM db1.table1
    Query id: 7ef1edbc-df25-462b-a9d4-3fe6f9cb0b6d
    
    ┌─id─┬─column1─┐
    │  1 │ abc     │
    │  2 │ def     │
    └────┴─────────┘
    
    2 rows in set. Elapsed: 0.006 sec.

    chnode2 では次のようになります。

  6. SELECT *
    FROM db1.table1
    Query id: c43763cc-c69c-4bcc-afbe-50e764adfcbf
    
    ┌─id─┬─column1─┐
    │  3 │ ghi     │
    │  4 │ jkl     │
    └────┴─────────┘
  7. 2 つの分片上のデータを表す Distributed テーブルを作成できます。Distributed テーブルエンジンを使用するテーブル自体はデータを保持しませんが、複数のサーバーにまたがる分散クエリ処理を可能にします。read はすべての分片に対して実行され、write は分片間に分散できます。chnode1 で次のクエリを実行してください。

    CREATE TABLE db1.dist_table (
        id UInt64,
        column1 String
    )
    ENGINE = Distributed(cluster_2S_1R,db1,table1)
  8. dist_table をクエリすると、2 つの分片にある 4 行すべてのデータが返されることに注目してください。

    SELECT *
    FROM db1.dist_table
    Query id: 495bffa0-f849-4a0c-aeea-d7115a54747a
    
    ┌─id─┬─column1─┐
    │  1 │ abc     │
    │  2 │ def     │
    └────┴─────────┘
    ┌─id─┬─column1─┐
    │  3 │ ghi     │
    │  4 │ jkl     │
    └────┴─────────┘
    
    4 rows in set. Elapsed: 0.018 sec.

まとめ

このガイドでは、ClickHouse Keeper を使用してクラスターを構成する方法を説明しました。ClickHouse Keeper を使用すると、クラスターを構成し、分片をまたいでレプリケーション可能な分散テーブルを定義できます。

一意のパスでClickHouse Keeperを設定する

ClickHouse Cloud ではサポートされていません

説明

この記事では、組み込みの {uuid} マクロ設定を使って、 ClickHouse Keeper または ZooKeeper に一意のエントリを作成する方法を説明します。一意の パスは、テーブルの作成と削除を頻繁に行う場合に役立ちます。これは、 パスが作成されるたびにその パス内で新しい uuid が使用されるため、パスのエントリを削除する Keeper のガベージコレクションが完了するまで 数分待つ必要がないからです。 パスが再利用されることはありません。

環境例

3 ノードのクラスターを構成し、3 つすべてのノードで ClickHouse Keeper を、 そのうち 2 つのノードで ClickHouse を動作させます。これにより、 ClickHouse Keeper は 3 ノード (タイブレーカーノードを含む) 構成となり、 ClickHouse は 2 つのレプリカからなる単一の分片として構成されます。

node description
chnode1.marsnet.local データノード - クラスター cluster_1S_2R
chnode2.marsnet.local データノード - クラスター cluster_1S_2R
chnode3.marsnet.local ClickHouse Keeper タイブレーカーノード

クラスターの設定例:

    <remote_servers>
        <cluster_1S_2R>
            <shard>
                <replica>
                    <host>chnode1.marsnet.local</host>
                    <port>9440</port>
                    <user>default</user>
                    <password>ClickHouse123!</password>
                    <secure>1</secure>
                </replica>
                <replica>
                    <host>chnode2.marsnet.local</host>
                    <port>9440</port>
                    <user>default</user>
                    <password>ClickHouse123!</password>
                    <secure>1</secure>
                </replica>
            </shard>
        </cluster_1S_2R>
    </remote_servers>

テーブルで {uuid} を使用するための設定手順

  1. 各サーバーでマクロを設定します サーバー 1 の例:
    <macros>
        <shard>1</shard>
        <replica>replica_1</replica>
    </macros>
  1. データベースを作成する
CREATE DATABASE db_uuid
      ON CLUSTER 'cluster_1S_2R'
      ENGINE Atomic;
CREATE DATABASE db_uuid ON CLUSTER cluster_1S_2R
ENGINE = Atomic

Query id: 07fb7e65-beb4-4c30-b3ef-bd303e5c42b5

┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode2.marsnet.local │ 9440 │      0 │       │                   1 │                0 │
│ chnode1.marsnet.local │ 9440 │      0 │       │                   0 │                0 │
└───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
  1. マクロと {uuid} を使用して、クラスター上にテーブルを作成します
CREATE TABLE db_uuid.uuid_table1 ON CLUSTER 'cluster_1S_2R'
   (
     id UInt64,
     column1 String
   )
   ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/db_uuid/{uuid}', '{replica}' )
   ORDER BY (id);
CREATE TABLE db_uuid.uuid_table1 ON CLUSTER cluster_1S_2R
(
    `id` UInt64,
    `column1` String
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/db_uuid/{uuid}', '{replica}')
ORDER BY id

Query id: 8f542664-4548-4a02-bd2a-6f2c973d0dc4

┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode1.marsnet.local │ 9440 │      0 │       │                   1 │                0 │
│ chnode2.marsnet.local │ 9440 │      0 │       │                   0 │                0 │
└───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
  1. 分散テーブルを作成する
CREATE TABLE db_uuid.dist_uuid_table1 ON CLUSTER 'cluster_1S_2R'
   (
     id UInt64,
     column1 String
   )
   ENGINE = Distributed('cluster_1S_2R', 'db_uuid', 'uuid_table1' );
CREATE TABLE db_uuid.dist_uuid_table1 ON CLUSTER cluster_1S_2R
(
    `id` UInt64,
    `column1` String
)
ENGINE = Distributed('cluster_1S_2R', 'db_uuid', 'uuid_table1')

Query id: 3bc7f339-ab74-4c7d-a752-1ffe54219c0e

┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode2.marsnet.local │ 9440 │      0 │       │                   1 │                0 │
│ chnode1.marsnet.local │ 9440 │      0 │       │                   0 │                0 │
└───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘

動作確認

  1. 最初のノード (例: chnode1) にデータを挿入します
INSERT INTO db_uuid.uuid_table1
   ( id, column1)
   VALUES
   ( 1, 'abc');
INSERT INTO db_uuid.uuid_table1 (id, column1) FORMAT Values

Query id: 0f178db7-50a6-48e2-9a1b-52ed14e6e0f9

Ok.

1 row in set. Elapsed: 0.033 sec.
  1. 2つ目のノードにデータを挿入します (例: chnode2)
INSERT INTO db_uuid.uuid_table1
   ( id, column1)
   VALUES
   ( 2, 'def');
INSERT INTO db_uuid.uuid_table1 (id, column1) FORMAT Values

Query id: edc6f999-3e7d-40a0-8a29-3137e97e3607

Ok.

1 row in set. Elapsed: 0.529 sec.
  1. 分散テーブルを使ってレコードを表示する
SELECT * FROM db_uuid.dist_uuid_table1;
SELECT *
FROM db_uuid.dist_uuid_table1

Query id: 6cbab449-9e7f-40fe-b8c2-62d46ba9f5c8

┌─id─┬─column1─┐
│  1 │ abc     │
└────┴─────────┘
┌─id─┬─column1─┐
│  2 │ def     │
└────┴─────────┘

2 rows in set. Elapsed: 0.007 sec.

別の方法

デフォルトのレプリケーションパスは、マクロと {uuid} を使ってあらかじめ定義できます

  1. 各ノードでテーブルのデフォルト設定を行う
<default_replica_path>/clickhouse/tables/{shard}/db_uuid/{uuid}</default_replica_path>
<default_replica_name>{replica}</default_replica_name>
  1. パラメータを明示せずにテーブルを作成します:
CREATE TABLE db_uuid.uuid_table1 ON CLUSTER 'cluster_1S_2R'
   (
     id UInt64,
     column1 String
   )
   ENGINE = ReplicatedMergeTree
   ORDER BY (id);
CREATE TABLE db_uuid.uuid_table1 ON CLUSTER cluster_1S_2R
(
    `id` UInt64,
    `column1` String
)
ENGINE = ReplicatedMergeTree
ORDER BY id

Query id: ab68cda9-ae41-4d6d-8d3b-20d8255774ee

┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode2.marsnet.local │ 9440 │      0 │       │                   1 │                0 │
│ chnode1.marsnet.local │ 9440 │      0 │       │                   0 │                0 │
└───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘

2 rows in set. Elapsed: 1.175 sec.
  1. デフォルト設定と同じ設定が使われていることを確認します
SHOW CREATE TABLE db_uuid.uuid_table1;
SHOW CREATE TABLE db_uuid.uuid_table1

CREATE TABLE db_uuid.uuid_table1
(
    `id` UInt64,
    `column1` String
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/db_uuid/{uuid}', '{replica}')
ORDER BY id

1 row in set. Elapsed: 0.003 sec.

トラブルシューティング

テーブル情報とUUIDを取得するコマンドの例:

SELECT * FROM system.tables
WHERE database = 'db_uuid' AND name = 'uuid_table1';

上記のテーブルのUUIDを使ってZooKeeper内のテーブル情報を取得するコマンド例

SELECT * FROM system.zookeeper
WHERE path = '/clickhouse/tables/1/db_uuid/9e8a3cc2-0dec-4438-81a7-c3e63ce2a1cf/replicas';

確認するには:

たとえば、

SELECT name, engine FROM system.databases WHERE name = 'db_uuid';
SELECT
    name,
    engine
FROM system.databases
WHERE name = 'db_uuid'

Query id: b047d459-a1d2-4016-bcf9-3e97e30e49c2

┌─name────┬─engine─┐
│ db_uuid │ Atomic │
└─────────┴────────┘

1 row in set. Elapsed: 0.004 sec.

ClickHouse Keeper の動的再設定

ClickHouse Cloud ではサポートされていません

説明

keeper_server.enable_reconfiguration が有効な場合、ClickHouse Keeper はクラスターを動的に再構成するための ZooKeeper の reconfig コマンドを部分的にサポートします。

仮想ノード /keeper/config には、最後にコミットされたクラスター構成が次のフォーマットで格納されています。

server.id = server_host:server_port[;server_type][;server_priority]
server.id2 = ...
...
  • 各サーバーのエントリは改行で区切られます。
  • server_typeparticipant または learner のいずれかです (learner はリーダー選出に参加しません) 。
  • server_priority は、リーダー選出でどのノードを優先するか を示す 0 以上の整数です。 優先度が 0 の場合、そのサーバーがリーダーになることはありません。

例:

:) get /keeper/config
server.1=zoo1:9234;participant;1
server.2=zoo2:9234;participant;1
server.3=zoo3:9234;participant;1

reconfig コマンドを使用すると、新しいサーバーの追加、既存サーバーの削除、既存サーバーの 優先度の変更ができます。以下はその例です (clickhouse-keeper-client を使用) :

# 新しいサーバーを2台追加する
reconfig add "server.5=localhost:123,server.6=localhost:234;learner"
# 他の2台のサーバーを削除する
reconfig remove "3,4"
# 既存のサーバーの優先度を8に変更する
reconfig add "server.5=localhost:5123;participant;8"

kazoo の例を以下に示します。

# 2つの新しいサーバーを追加し、他の2つのサーバーを削除する
reconfig(joining="server.5=localhost:123,server.6=localhost:234;learner", leaving="3,4")

# 既存のサーバーの優先度を8に変更する
reconfig(joining="server.5=localhost:5123;participant;8", leaving=None)

joining 内のサーバーは、上記で説明したサーバー形式に従っている必要があります。サーバーエントリはカンマで区切る必要があります。 新しいサーバーを追加する際は、server_priority (デフォルト値は 1) と server_type (デフォルト値 は participant) を省略できます。

既存サーバーの優先度を変更する場合は、変更先の優先度を指定してそのサーバーを joining に追加します。 サーバーのホスト、ポート、タイプは、既存のサーバー設定と一致している必要があります。

サーバーの追加と削除は、joiningleaving に記載された順序で行われます。 joining の更新はすべて、leaving の更新より先に処理されます。

Keeper の再構成実装には、いくつかの注意点があります。

  • サポートされているのは増分再構成のみです。new_members が空でないリクエストは拒否されます。

    ClickHouse Keeper の実装では、メンバーシップを動的に変更するために NuRaft API を使用しています。NuRaft では、 1 回につき 1 台のサーバーを追加または削除できます。つまり、設定に対する各変更 (joining の各要素、leaving の各要素) は、それぞれ個別に決定される必要があります。そのため、一括での 再構成は提供されていません。エンドユーザーに誤解を与えるおそれがあるためです。

    サーバータイプ (participant/learner) の変更もできません。これは NuRaft でサポートされていないためです。また、 唯一の方法はサーバーを削除して再度追加することですが、これもやはり誤解を招くおそれがあります。

  • 返された znodestat の値は使用できません。

  • from_version フィールドは使用されません。from_version が設定されたリクエストはすべて拒否されます。 これは、/keeper/config が仮想ノードであるためです。つまり、このノードは永続ストレージには保存されず、 代わりに指定されたノード設定に基づいて、リクエストごとにその場で生成されます。 このような設計になっているのは、NuRaft がすでにこの設定を保存しているため、データの重複を避けるためです。

  • ZooKeeper とは異なり、sync コマンドを送信してクラスターの再構成が完了するまで待機する方法はありません。 新しい設定はいずれ適用されますが、適用時期は保証されません。

  • reconfig コマンドは、さまざまな理由で失敗する可能性があります。クラスターの状態を確認して、更新が 適用されたかどうかを確認できます。

単一ノードの Keeper をクラスター化する

実験的な Keeper ノードをクラスターに拡張する必要が生じる場合があります。以下は、3 ノードのクラスターに段階的に拡張する手順の概要です。

  • 重要: 新しいノードは、現在のクォーラム未満の単位で追加する必要があります。そうしないと、それらのノード間でリーダーが選出されてしまいます。この例では、1 台ずつ追加します。
  • 既存の Keeper ノードでは、keeper_server.enable_reconfiguration 設定パラメーターを有効にしておく必要があります。
  • Keeper クラスターの新しい完全な設定で 2 台目のノードを起動します。
  • 起動後、reconfig を使用してノード 1 に追加します。
  • 次に、3 台目のノードを起動し、reconfig を使用して追加します。
  • 新しい Keeper ノードを追加するように clickhouse-server の設定を更新し、変更を適用するために再起動します。
  • ノード 1 の raft 設定を更新し、必要に応じて再起動します。

この手順を確実に理解するのに役立つよう、サンドボックスリポジトリも用意されています。

サポートされていない機能

ClickHouse Keeper は ZooKeeper との完全な互換性を目指していますが、現時点では未実装の機能がいくつかあります (現在も開発は進行中です) 。

Navigation