In this example, you’ll learn how to set up a simple ClickHouse cluster which replicates the data. There are five servers configured. Two are used to host copies of the data. The other three servers are used to coordinate the replication of data.The architecture of the cluster you will be setting up is shown below:
Although it is possible to run ClickHouse Server and ClickHouse Keeper combined on the same server,
we strongly recommend using dedicated hosts for ClickHouse keeper in production environments,
which is the approach we will demonstrate in this example.Keeper servers can be smaller, and 4GB RAM is generally enough for each Keeper server
until your ClickHouse Servers grow large.
Prerequisites
- You’ve set up a local ClickHouse server before
- You’re familiar with basic configuration concepts of ClickHouse such as configuration files
- You have docker installed on your machine
1
Set up directory structure and test environment
In this tutorial, you will use Docker compose to set up the ClickHouse cluster. This setup could be modified to work for separate local machines, virtual machines or cloud instances as well.Run the following commands to set up the directory structure for this example:docker-compose.yml file to the cluster_1S_2R directory:docker-compose.yml
- The
config.ddirectory contains ClickHouse server configuration fileconfig.xml, in which custom configuration for each ClickHouse node is defined. This configuration gets combined with the defaultconfig.xmlClickHouse configuration file that comes with every ClickHouse installation. - The
users.ddirectory contains user configuration fileusers.xml, in which custom configuration for users is defined. This configuration gets combined with the default ClickHouseusers.xmlconfiguration file that comes with every ClickHouse installation.
2
Configure ClickHouse nodes
Server setup
Now modify each empty configuration fileconfig.xml located at
fs/volumes/clickhouse-{}/etc/clickhouse-server/config.d. The lines which are
highlighted below need to be changed to be specific to each node:Each section of the above configuration file is explained in more detail below.
Networking and logging
External communication to the network interface is enabled by activating the listen host setting. This ensures that the ClickHouse server host is reachable by other hosts:8123:9000:<logger> block. This example configuration gives
you a debug log that will roll over at 1000M three times:Cluster configuration
Configuration for the cluster is set up in the<remote_servers> block.
Here the cluster name cluster_1S_2R is defined.The <cluster_1S_2R></cluster_1S_2R> block defines the layout of the cluster,
using the <shard></shard> and <replica></replica> settings, and acts as a
template for distributed DDL queries, which are queries that execute across the
cluster using the ON CLUSTER clause. By default, distributed DDL queries
are allowed, but can also be turned off with setting allow_distributed_ddl_queries.internal_replication is set to true so that data is written to just one of the replicas.Keeper configuration
The<ZooKeeper> section tells ClickHouse where ClickHouse Keeper (or ZooKeeper) is running.
As we’re using a ClickHouse Keeper cluster, each <node> of the cluster needs to be specified,
along with its hostname and port number using the <host> and <port> tags respectively.Set up of ClickHouse Keeper is explained in the next step of the tutorial.Although it is possible to run ClickHouse Keeper on the same server as ClickHouse Server,
in production environments we strongly recommend that ClickHouse Keeper runs on dedicated hosts.
Macros configuration
Additionally, the<macros> section is used to define parameter substitutions for
replicated tables. These are listed in system.macros and allow using substitutions
like {shard} and {replica} in queries.These will be defined uniquely depending on the layout of the cluster.
User configuration
Now modify each empty configuration fileusers.xml located at
fs/volumes/clickhouse-{}/etc/clickhouse-server/users.d with the following:/users.d/users.xml
In this example, the default user is configured without a password for simplicity.
In practice, this is discouraged.
In this example, each
users.xml file is identical for all nodes in the cluster.3
Configure ClickHouse Keeper
Keeper setup
In order for replication to work, a ClickHouse keeper cluster needs to be set up and configured. ClickHouse Keeper provides the coordination system for data replication, acting as a stand in replacement for Zookeeper, which could also be used. ClickHouse Keeper is, however, recommended, as it provides better guarantees and reliability and uses fewer resources than ZooKeeper. For high availability and to keep quorum, it is recommended to run at least three ClickHouse Keeper nodes.ClickHouse Keeper can run on any node of the cluster alongside ClickHouse, although
it is recommended to have it run on a dedicated node which allows scaling and
managing the ClickHouse Keeper cluster independently of the database cluster.
keeper_config.xml files for each ClickHouse Keeper node
using the following command from the root of the example folder:fs/volumes/clickhouse-keeper-{}/etc/clickhouse-keeper. The
highlighted lines below need to be changed to be specific to each node:/clickhouse-keeper/keeper_config.xml
Each configuration file will contain the following unique configuration (shown below).
The
server_id used should be unique for that particular ClickHouse Keeper node
in the cluster and match the server <id> defined in the <raft_configuration> section.
tcp_port is the port used by clients of ClickHouse Keeper.4
Test the setup
Make sure that docker is running on your machine. Start the cluster using thedocker-compose up command from the root of the cluster_1S_2R directory:clickhouse-01 or clickhouse-02 and run the
following query. The command to connect to the first node is shown:Query
Response
Query
Response
mntr command is also commonly used to verify that ClickHouse Keeper is
running and to get state information about the relationship of the three Keeper nodes.
In the configuration used in this example, there are three nodes working together.
The nodes will elect a leader, and the remaining nodes will be followers.The mntr command gives information related to performance, and whether a particular
node is a follower or a leader.Run the command below from a shell on clickhouse-keeper-01, clickhouse-keeper-02, and
clickhouse-keeper-03 to check the status of each Keeper node. The command
for clickhouse-keeper-01 is shown below:Response
Response
5
Create a database
Now that you have verified the cluster is correctly setup and is running, you will be recreating the same table as the one used in the UK property prices example dataset tutorial. It consists of around 30 million rows of prices paid for real-estate property in England and Wales since 1995.Connect to the client of each host by running each of the following commands from separate terminal tabs or windows:Query
Response
clickhouse-01 client run the following distributed DDL query using the
ON CLUSTER clause to create a new database called uk:clickhouse-01:6
Create a table on the cluster
Now that the database has been created, create a table on the cluster. Run the following query from any of the host clients:CREATE statement of the
UK property prices example dataset tutorial,
except for the ON CLUSTER clause and use of the ReplicatedMergeTree engine.The ON CLUSTER clause is designed for distributed execution of DDL (Data Definition Language)
queries such as CREATE, DROP, ALTER, and RENAME, ensuring that these
schema changes are applied across all nodes in a cluster.The ReplicatedMergeTree
engine works just as the ordinary MergeTree table engine, but it will also replicate the data.You can run the query below from either clickhouse-01 or clickhouse-02 client
to confirm that the table has been created across the cluster:Query
Response
7
Insert data
As the data set is large and takes a few minutes to completely ingest, we will insert only a small subset to begin with.Insert a smaller subset of the data using the query below fromclickhouse-01:uk_price_paid table, we can insert data from either host:clickhouse-01 by running:Response
clickhouse-01 now down, insert another row of data into the test table
and query the table:Response
clickhouse-01 with the following command (you can run docker-compose ps again after to confirm):clickhouse-01 after running docker exec -it clickhouse-01 clickhouse-client:Query
Response
clickhouse-02 or clickhouse-01:Query
Response
Conclusion
The advantage of this cluster topology is that with two replicas, your data exists on two separate hosts. If one host fails, the other replica continues serving data without any loss. This eliminates single points of failure at the storage level. When one host goes down, the remaining replica is still able to:- Handle read queries without interruption
- Accept new writes (depending on your consistency settings)
- Maintain service availability for applications
- Automatically sync missing data from the healthy replica
- Resume normal operations without manual intervention
- Restore full redundancy quickly