EDB distributes ClickHouse as RPM packages for Rocky Linux 10 on x86-64. The following packages are available:
| Package | Description | Install on |
|---|---|---|
edb-clickhouse-server | ClickHouse server engine, systemd services, and default configuration files. Includes clickhouse-keeper.service, so server nodes can run Keeper alongside the server without an additional package. | Server nodes |
edb-clickhouse-client | clickhouse-client, clickhouse-local, clickhouse-benchmark, and related tools. | Server nodes, remote client hosts |
edb-clickhouse-common-static | Compiled ClickHouse binary, required by the server and client packages. | All server and client nodes |
edb-clickhouse-keeper | Standalone Keeper binary for dedicated coordination nodes. Only needed for multi-node deployments that run Keeper on separate nodes. | Dedicated Keeper nodes only |
For an explanation of node roles and deployment topologies, see Architecture.
Prerequisites
- Rocky Linux 10
sudoor root access- An EDB subscription token, available from the EDB customer portal
Deploying a single node
ClickHouse runs as a standalone instance with no cluster coordination required. Suitable for development, testing, and single-tenant analytical workloads.
Install the packages:
export EDB_SUBSCRIPTION_TOKEN=<your-token> export EDB_SUBSCRIPTION_PLAN=clickhouse curl -1sSLf "https://downloads.enterprisedb.com/$EDB_SUBSCRIPTION_TOKEN/$EDB_SUBSCRIPTION_PLAN/setup.rpm.sh" | sudo -E bash sudo dnf install -y \ edb-clickhouse-common-static \ edb-clickhouse-server \ edb-clickhouse-client
Start the server:
sudo systemctl enable clickhouse-server sudo systemctl start clickhouse-server
Verify the server is running:
sudo systemctl status clickhouse-serverConnect using the ClickHouse command-line client:
clickhouse-client
By default, the
defaultuser has no password. To set one, run the following after connecting:ALTER USER default IDENTIFIED BY 'yourpassword';
Then connect with:
clickhouse-client --passwordVerify the EDB build by checking the version string:
SELECT value FROM system.build_options WHERE name = 'VERSION_OFFICIAL';
The output includes
(EDB Build)for EDB-packaged releases.
Deploying a cluster
A cluster deployment distributes data across multiple server nodes using sharding, replication, or both. Replication requires ClickHouse Keeper running on at least three nodes. For an explanation of sharding, replication, and Keeper roles, see Architecture.
The following steps walk through a five-node deployment: four server nodes across two shards with two replicas each, with Keeper co-located on node-1 and node-2 and running as a dedicated service on node-5. Adjust the configuration for your own topology.
| Node | Role | Shard | Replica |
|---|---|---|---|
| node-1 | ClickHouse server + Keeper | 1 | 1 |
| node-2 | ClickHouse server + Keeper | 1 | 2 |
| node-3 | ClickHouse server | 2 | 1 |
| node-4 | ClickHouse server | 2 | 2 |
| node-5 | Keeper |
Installing packages
Set up the EDB repository on every node:
export EDB_SUBSCRIPTION_TOKEN=<your-token> export EDB_SUBSCRIPTION_PLAN=clickhouse curl -1sSLf "https://downloads.enterprisedb.com/$EDB_SUBSCRIPTION_TOKEN/$EDB_SUBSCRIPTION_PLAN/setup.rpm.sh" | sudo -E bash
Install the role-appropriate packages on each node.
On each server node:
sudo dnf install -y \ edb-clickhouse-common-static \ edb-clickhouse-server \ edb-clickhouse-client
For co-located deployments,
edb-clickhouse-serveralready includesclickhouse-keeper.service, so no additional package is needed.On each dedicated Keeper node:
sudo dnf install -y edb-clickhouse-keeper
Configuring Keeper
Configure all Keeper nodes before starting any service. Use a minimum of three Keeper nodes to tolerate one node failure.
The RPM installs a default
/etc/clickhouse-keeper/keeper_config.xml. Replace its contents on each Keeper node with the following, setting<server_id>to a unique integer (1,2,3) per node:<clickhouse> <listen_host>0.0.0.0</listen_host> <keeper_server> <tcp_port>9181</tcp_port> <server_id>1</server_id><!-- Set to 1, 2, or 3 depending on the node --> <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><node-1-ip></hostname><port>9234</port></server> <server><id>2</id><hostname><node-2-ip></hostname><port>9234</port></server> <server><id>3</id><hostname><node-5-ip></hostname><port>9234</port></server> </raft_configuration> </keeper_server> </clickhouse>
Configuring the servers
Each server node needs a cluster configuration that defines the remote servers, Keeper endpoints, and the node's own shard and replica identity.
Create
/etc/clickhouse-server/config.d/cluster.xmlon each server node, adjusting the<shard>and<replica>values in the<macros>section for each node:Node <shard><replica>node-1 01 01 node-2 01 02 node-3 02 01 node-4 02 02 <clickhouse> <listen_host>0.0.0.0</listen_host> <remote_servers> <my_cluster> <shard> <internal_replication>true</internal_replication> <replica><host><node-1-ip></host><port>9000</port></replica> <replica><host><node-2-ip></host><port>9000</port></replica> </shard> <shard> <internal_replication>true</internal_replication> <replica><host><node-3-ip></host><port>9000</port></replica> <replica><host><node-4-ip></host><port>9000</port></replica> </shard> </my_cluster> </remote_servers> <zookeeper> <node><host><node-1-ip></host><port>9181</port></node> <node><host><node-2-ip></host><port>9181</port></node> <node><host><node-5-ip></host><port>9181</port></node> </zookeeper> <macros> <cluster>my_cluster</cluster> <shard>01</shard><!-- Adjust per node, see table above --> <replica>01</replica><!-- Adjust per node, see table above --> </macros> <distributed_ddl> <path>/clickhouse/task_queue/ddl</path> </distributed_ddl> </clickhouse>
Starting services
Start Keeper on all Keeper nodes. On each Keeper node:
sudo systemctl enable clickhouse-keeper sudo systemctl start clickhouse-keeper
Verify each Keeper node is healthy. Run the following on each Keeper node. A healthy node responds with
imok:clickhouse-keeper-client -h 127.0.0.1 -p 9181 -q "ruok"
Outputimok
Confirm quorum is formed from any one Keeper node. A value of
2means two followers are synced to the leader, confirming all three Keeper nodes have formed a quorum:clickhouse-keeper-client -h 127.0.0.1 -p 9181 -q "mntr" | grep zk_synced_followers
Outputzk_synced_followers 2
Start the server on all server nodes:
sudo systemctl enable clickhouse-server sudo systemctl start clickhouse-server
Verify the server is running on each server node:
sudo systemctl status clickhouse-server
Connecting to the cluster
Connect to any server node from a host with
edb-clickhouse-clientinstalled:clickhouse-client -h <server-node-ip>
By default, the
defaultuser has no password. To set one, run the following after connecting:ALTER USER default IDENTIFIED BY 'yourpassword';
Then connect with:
clickhouse-client -h <server-node-ip> --password
Confirm all server nodes are registered.
system.clusterslists server nodes only, so the dedicated Keeper node-5 doesn't appear: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 │ <node-1-ip> │ │ my_cluster │ 1 │ 2 │ <node-2-ip> │ │ my_cluster │ 2 │ 1 │ <node-3-ip> │ │ my_cluster │ 2 │ 2 │ <node-4-ip> │ └────────────┴───────────┴─────────────┴─────────────┘
Testing replication and sharding
Create a local ReplicatedMergeTree table and a Distributed table on top of it. Insert some rows and query both tables to confirm that replication is working within each shard and that the distributed table aggregates data across all shards.
Create a local storage table. The
ReplicatedMergeTreeengine stores data physically on each node and replicates it within the shard: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;
Create a
Distributedtable on top ofevents. Unlike the local table, it stores no data. It routes queries toeventsacross all shards and aggregates the results: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());
Insert some rows via
events_dist. Therand()sharding key distributes each row across shards:INSERT INTO events_dist VALUES (1, 101, 'login', now()), (2, 102, 'purchase', now()), (3, 103, 'logout', now()), (4, 104, 'login', now());
Query the local table on any server node. Each node returns only the rows on its shard. The specific rows vary depending on how
rand()distributed them: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 │ └──────────┴─────────┴────────────┴────────────────────────┘
Query
events_distfrom any node to confirm all rows are returned across shards: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 │ └──────────┴─────────┴────────────┴────────────────────────┘