Installing EDB Postgres AI for ClickHouse with Docker#

EDBは、Linuxパッケージと同じRPMからビルドされたコンテナイメージを公開します。イメージはRocky Linux 10minimalベースであり、x86-64で利用でき、 clickhouse-server 、clickhouse-keeper 、およびclickhouse-client が含まれています。

前提条件#

  • Docker Engine 20.10以降とCompose v2 docker compose コマンド

  • EDBサブスクリプショントークン、 EDB customer portal から入手できます。

イメージのプル#

EDBコンテナレジストリにログインし、イメージをプルします。

export EDB_SUBSCRIPTION_TOKEN=<your-token>
docker login docker.enterprisedb.com \
  --username <your-edb-email> \
  --password "$EDB_SUBSCRIPTION_TOKEN"
docker pull docker.enterprisedb.com/edb-clickhouse-server:26.3.12.3

シングルノードサーバーの実行#

開発とテストの場合、単一のClickHouse Serverノードを実行します。

  1. サーバーを起動します。

docker run -d \
  --name clickhouse-server \
  --ulimit nofile=262144:262144 \
  -p 8123:8123 \
  -p 9000:9000 \
  docker.enterprisedb.com/edb-clickhouse-server:26.3.12.3

ポート8123 は、HTTPインターフェイスを公開します。ポート9000 は、 clickhouse-client およびほとんどのドライバーが使用するネイティブTCPインターフェイスを公開します。

コンテナを再起動してもデータを持続するには、ボリュームマウントを追加します。

docker run -d \
  --name clickhouse-server \
  --ulimit nofile=262144:262144 \
  -p 8123:8123 \
  -p 9000:9000 \
  -v /local/path/clickhouse-data:/var/lib/clickhouse \
  docker.enterprisedb.com/edb-clickhouse-server:26.3.12.3
  1. デフォルトのサーバー設定をオーバーライドするには、構成ディレクトリをマウントします。

docker run -d \
  --name clickhouse-server \
  --ulimit nofile=262144:262144 \
  -p 8123:8123 \
  -p 9000:9000 \
  -v /local/path/config:/etc/clickhouse-server/config.d \
  docker.enterprisedb.com/edb-clickhouse-server:26.3.12.3

ClickHouseは、起動時にconfig.d のすべての.xml ファイルをメイン構成にマージします。

  1. ClickHouseクライアントに接続します。

docker exec -it clickhouse-server clickhouse-client
  1. EDBビルドを確認します。

SELECT value FROM system.build_options WHERE name = VERSION_OFFICIAL;

出力には、EDBパッケージリリースの(EDB Build) が含まれます。

マルチノードクラスターの実行#

Docker Composeを使用して、マルチノードクラスターを展開します。 EDB提供のサーバーイメージには clickhouse-server とclickhouse-keeper の両方が含まれているため、クラスター内のすべてのノードは単一のイメージから実行されます。

次の例では、3つの専用キーパーノード合計7つのコンテナを使用した2シャード、2レプリカクラスターをセットアップします。シャーディング、レプリケーション、およびKeeperロールの説明については、 ClickHouse architecture を参照してください。

構成ファイルの作成#

次のディレクトリ構造を作成します。

cluster/
├── docker-compose.yml
├── keeper-01/
│   └── keeper_config.xml
├── keeper-02/
│   └── keeper_config.xml
├── keeper-03/
│   └── keeper_config.xml
├── server-01/
│   ├── config.xml
│   └── users.xml
├── server-02/
│   ├── config.xml
│   └── users.xml
├── server-03/
│   ├── config.xml
│   └── users.xml
└── server-04/
    ├── config.xml
    └── users.xml

各ディレクトリに、そのノードロールの構成ファイルを設定します。

キーパーノード

3つのKeeperノードは、Raftクォーラムを形成します。それぞれに一意のserver_id があります。各キーパーディレクトリにkeeper_config.xml を作成し、 server_id を1 、2 、および3 にそれぞれ設定します。

keeper_config.xml

<clickhouse replace="true">
    <logger>
        <level>information</level>
        <console>1</console>
    </logger>
    <listen_host>0.0.0.0</listen_host>
    <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>information</raft_logs_level>
        </coordination_settings>
        <raft_configuration>
            <server>
                <id>1</id>
                <hostname>keeper-01</hostname>
                <port>9234</port>
            </server>
            <server>
                <id>2</id>
                <hostname>keeper-02</hostname>
                <port>9234</port>
            </server>
            <server>
                <id>3</id>
                <hostname>keeper-03</hostname>
                <port>9234</port>
            </server>
        </raft_configuration>
    </keeper_server>
</clickhouse>

サーバーノード

各サーバーノードには、クラスタートポロジ、Keeperエンドポイント、およびシャード/レプリカマクロが必要です。各サーバーディレクトリにconfig.xml を作成します。ノード間で異なる値は、<macros> セクションの<shard> および<replica> エントリのみです。

Node

<shard>

<replica>

server-01

01

01

server-02

02

01

server-03

01

02

server-04

02

02

config.xml

<clickhouse replace="true">
    <logger>
        <level>information</level>
        <console>1</console>
    </logger>
    <display_name>cluster node 01</display_name>
    <listen_host>0.0.0.0</listen_host>
    <http_port>8123</http_port>
    <tcp_port>9000</tcp_port>
    <distributed_ddl>
        <path>/clickhouse/task_queue/ddl</path>
    </distributed_ddl>
    <remote_servers>
        <my_cluster>
            <shard>
                <internal_replication>true</internal_replication>
                <replica>
                    <host>server-01</host>
                    <port>9000</port>
                </replica>
                <replica>
                    <host>server-03</host>
                    <port>9000</port>
                </replica>
            </shard>
            <shard>
                <internal_replication>true</internal_replication>
                <replica>
                    <host>server-02</host>
                    <port>9000</port>
                </replica>
                <replica>
                    <host>server-04</host>
                    <port>9000</port>
                </replica>
            </shard>
        </my_cluster>
    </remote_servers>
    <zookeeper>
        <node>
            <host>keeper-01</host>
            <port>9181</port>
        </node>
        <node>
            <host>keeper-02</host>
            <port>9181</port>
        </node>
        <node>
            <host>keeper-03</host>
            <port>9181</port>
        </node>
    </zookeeper>
    <macros>
        <shard>01</shard>
        <replica>01</replica>
    </macros>
</clickhouse>

ユーザー設定

4つのサーバーノードはすべて同じusers.xml を使用します。これを各サーバーディレクトリにコピーし、クラスター起動後にパスワードを設定します。

users.xml

<clickhouse replace="true">
    <profiles>
        <default>
            <max_memory_usage>10000000000</max_memory_usage>
            <load_balancing>in_order</load_balancing>
            <log_queries>1</log_queries>
        </default>
    </profiles>
    <users>
        <default>
            <profile>default</profile>
            <networks>
                <ip>::/0</ip>
            </networks>
            <quota>default</quota>
            <access_management>1</access_management>
        </default>
    </users>
    <quotas>
        <default>
            <interval>
                <duration>3600</duration>
                <queries>0</queries>
                <errors>0</errors>
                <result_rows>0</result_rows>
                <read_rows>0</read_rows>
                <execution_time>0</execution_time>
            </interval>
        </default>
    </quotas>
</clickhouse>

Composeファイルの作成#

cluster/ ディレクトリにdocker-compose.yml を作成します。

services:
  keeper-01:
    image: docker.enterprisedb.com/edb-clickhouse-server:26.3.12.3
    container_name: keeper-01
    hostname: keeper-01
    entrypoint: ["/usr/bin/clickhouse-keeper", "--config-file=/etc/clickhouse-keeper/keeper_config.xml"]
    volumes:
      - ./keeper-01/keeper_config.xml:/etc/clickhouse-keeper/keeper_config.xml

  keeper-02:
    image: docker.enterprisedb.com/edb-clickhouse-server:26.3.12.3
    container_name: keeper-02
    hostname: keeper-02
    entrypoint: ["/usr/bin/clickhouse-keeper", "--config-file=/etc/clickhouse-keeper/keeper_config.xml"]
    volumes:
      - ./keeper-02/keeper_config.xml:/etc/clickhouse-keeper/keeper_config.xml

  keeper-03:
    image: docker.enterprisedb.com/edb-clickhouse-server:26.3.12.3
    container_name: keeper-03
    hostname: keeper-03
    entrypoint: ["/usr/bin/clickhouse-keeper", "--config-file=/etc/clickhouse-keeper/keeper_config.xml"]
    volumes:
      - ./keeper-03/keeper_config.xml:/etc/clickhouse-keeper/keeper_config.xml

  server-01:
    image: docker.enterprisedb.com/edb-clickhouse-server:26.3.12.3
    container_name: server-01
    hostname: server-01
    ulimits:
      nofile: { soft: 262144, hard: 262144 }
    ports:
      - "127.0.0.1:18123:8123"
      - "127.0.0.1:19000:9000"
    volumes:
      - ./server-01/config.xml:/etc/clickhouse-server/config.d/config.xml
      - ./server-01/users.xml:/etc/clickhouse-server/users.d/users.xml
    depends_on: [keeper-01, keeper-02, keeper-03]

  server-02:
    image: docker.enterprisedb.com/edb-clickhouse-server:26.3.12.3
    container_name: server-02
    hostname: server-02
    ulimits:
      nofile: { soft: 262144, hard: 262144 }
    ports:
      - "127.0.0.1:18124:8123"
      - "127.0.0.1:19001:9000"
    volumes:
      - ./server-02/config.xml:/etc/clickhouse-server/config.d/config.xml
      - ./server-02/users.xml:/etc/clickhouse-server/users.d/users.xml
    depends_on: [keeper-01, keeper-02, keeper-03]

  server-03:
    image: docker.enterprisedb.com/edb-clickhouse-server:26.3.12.3
    container_name: server-03
    hostname: server-03
    ulimits:
      nofile: { soft: 262144, hard: 262144 }
    ports:
      - "127.0.0.1:18125:8123"
      - "127.0.0.1:19002:9000"
    volumes:
      - ./server-03/config.xml:/etc/clickhouse-server/config.d/config.xml
      - ./server-03/users.xml:/etc/clickhouse-server/users.d/users.xml
    depends_on: [keeper-01, keeper-02, keeper-03]

  server-04:
    image: docker.enterprisedb.com/edb-clickhouse-server:26.3.12.3
    container_name: server-04
    hostname: server-04
    ulimits:
      nofile: { soft: 262144, hard: 262144 }
    ports:
      - "127.0.0.1:18126:8123"
      - "127.0.0.1:19003:9000"
    volumes:
      - ./server-04/config.xml:/etc/clickhouse-server/config.d/config.xml
      - ./server-04/users.xml:/etc/clickhouse-server/users.d/users.xml
    depends_on: [keeper-01, keeper-02, keeper-03]

クラスターの起動と検証#

  1. cluster/ ディレクトリから、すべてのコンテナを起動します。

docker compose up -d
  1. server-01 に接続します。

docker exec -it server-01 clickhouse-client
  1. すべてのサーバーノードが登録されていることを確認します。 system.clusters はサーバーノードのみをリストするため、専用のKeeperコンテナは表示されません。

SELECT cluster, shard_num, replica_num, host_name
FROM system.clusters
WHERE cluster = my_cluster;
__OUTPUT__
┌─cluster────┬─shard_num─┬─replica_num─┬─host_name─┐
│ my_cluster │         1 │           1 │ server-01 │
│ my_cluster │         1 │           2 │ server-03 │
│ my_cluster │         2 │           1 │ server-02 │
│ my_cluster │         2 │           2 │ server-04 │
└────────────┴───────────┴─────────────┴───────────┘
  1. すべてのノードにわたってKeeperの接続を確認します。クエリーはclusterAllReplicas を使用してすべてのサーバーノードに対して実行され、それぞれが認識するルートzノードを結果ます。行を返すすべてのノードは、すべてのサーバーがKeeperに到達できることを確認します。

SELECT hostName(), name, path
FROM clusterAllReplicas(my_cluster, system.zookeeper)
WHERE path = /;
__OUTPUT__
┌─hostName()─┬─name───────┬─path─┐
│ server-01  │ keeper     │ /    │
│ server-01  │ clickhouse │ /    │
│ server-02  │ keeper     │ /    │
│ server-02  │ clickhouse │ /    │
│ server-03  │ keeper     │ /    │
│ server-03  │ clickhouse │ /    │
│ server-04  │ keeper     │ /    │
│ server-04  │ clickhouse │ /    │
└────────────┴────────────┴──────┘

レプリケーションとシャーディングのテスト#

ローカルのReplicatedMergeTree テーブルとその上にDistributed テーブルを作成します。いくつかの行を挿入し、両方のテーブルを照会して、各シャード内でレプリケーションが機能していること、および分散テーブルがすべてのシャードのデータを集計することを確認します。

  1. ローカルストレージテーブルを作成します。 ReplicatedMergeTree エンジンは、各ノードにデータを物理的に保存し、シャード内でレプリケートします。

CREATE TABLE events ON CLUSTER my_cluster (
    event_id   UInt32,
    user_id    UInt32,
    event_type String,
    created_at DateTime
) ENGINE = ReplicatedMergeTree(/clickhouse/tables/{shard}/events, {replica})
ORDER BY event_id;
  1. events の上にDistributed テーブルを作成します。ローカルテーブルとは異なり、データは保存されません。クエリーをすべてのシャードにわたってevents にルーティングし、結果を集計します。

CREATE TABLE events_dist ON CLUSTER my_cluster (
    event_id   UInt32,
    user_id    UInt32,
    event_type String,
    created_at DateTime
) ENGINE = Distributed(my_cluster, default, events, rand());
  1. events_dist を介していくつかの行を挿入します。 rand() シャーディングキーは、各行をシャード全体に分散します。

INSERT INTO events_dist VALUES
    (1, 101, login,    now()),
    (2, 102, purchase, now()),
    (3, 103, logout,   now()),
    (4, 104, login,    now());
  1. 任意のサーバーノードのローカルテーブルを照会します。各ノードは、そのシャードの行のみを結果ます。特定の行は、rand() がそれらを分散した方法によって異なります。

SELECT * FROM events;
__OUTPUT__
┌─event_id─┬─user_id─┬─event_type─┬─────────────created_at─┐
│        2 │     102 │ purchase   │ 2026-06-10 14:48:15    │
│        3 │     103 │ logout     │ 2026-06-10 14:48:15    │
└──────────┴─────────┴────────────┴────────────────────────┘
  1. 任意のノードからevents_dist を照会して、すべての行がシャードにわたって返されることを確認します。

SELECT * FROM events_dist ORDER BY event_id;
__OUTPUT__
┌─event_id─┬─user_id─┬─event_type─┬─────────────created_at─┐
│        1 │     101 │ login      │ 2026-06-10 14:48:15    │
│        2 │     102 │ purchase   │ 2026-06-10 14:48:15    │
│        3 │     103 │ logout     │ 2026-06-10 14:48:15    │
│        4 │     104 │ login      │ 2026-06-10 14:48:15    │
└──────────┴─────────┴────────────┴────────────────────────┘