Dans cet exemple, vous allez apprendre à mettre en place un cluster ClickHouse simple avec réplication des données. Cinq serveurs sont configurés. Deux servent à héberger des copies des données. Les trois autres servent à coordonner la réplication des données.
L’architecture du cluster que vous allez mettre en place est présentée ci-dessous :

Prérequis
- Vous avez déjà configuré un serveur ClickHouse local
- Vous êtes familiarisé avec les concepts de base de la configuration de ClickHouse, comme les fichiers de configuration
- Docker est installé sur votre machine
Configurer la structure de répertoires et l’environnement de test
Dans ce tutoriel, vous utiliserez Docker compose pour configurer le cluster ClickHouse. Cette configuration peut également être adaptée pour fonctionner sur des machines locales distinctes, des machines virtuelles ou des instances Cloud.
Exécutez les commandes suivantes pour configurer l'arborescence de répertoires de cet exemple :
mkdir cluster_1S_2R
cd cluster_1S_2R
# Create clickhouse-keeper directories
for i in {01..03}; do
mkdir -p fs/volumes/clickhouse-keeper-${i}/etc/clickhouse-keeper
done
# Create clickhouse-server directories
for i in {01..02}; do
mkdir -p fs/volumes/clickhouse-${i}/etc/clickhouse-server
doneAjoutez le fichier docker-compose.yml suivant dans le répertoire cluster_1S_2R :
version: '3.8'
services:
clickhouse-01:
image: "clickhouse/clickhouse-server:latest"
user: "101:101"
container_name: clickhouse-01
hostname: clickhouse-01
volumes:
- ${PWD}/fs/volumes/clickhouse-01/etc/clickhouse-server/config.d/config.xml:/etc/clickhouse-server/config.d/config.xml
- ${PWD}/fs/volumes/clickhouse-01/etc/clickhouse-server/users.d/users.xml:/etc/clickhouse-server/users.d/users.xml
ports:
- "127.0.0.1:8123:8123"
- "127.0.0.1:9000:9000"
depends_on:
- clickhouse-keeper-01
- clickhouse-keeper-02
- clickhouse-keeper-03
clickhouse-02:
image: "clickhouse/clickhouse-server:latest"
user: "101:101"
container_name: clickhouse-02
hostname: clickhouse-02
volumes:
- ${PWD}/fs/volumes/clickhouse-02/etc/clickhouse-server/config.d/config.xml:/etc/clickhouse-server/config.d/config.xml
- ${PWD}/fs/volumes/clickhouse-02/etc/clickhouse-server/users.d/users.xml:/etc/clickhouse-server/users.d/users.xml
ports:
- "127.0.0.1:8124:8123"
- "127.0.0.1:9001:9000"
depends_on:
- clickhouse-keeper-01
- clickhouse-keeper-02
- clickhouse-keeper-03
clickhouse-keeper-01:
image: "clickhouse/clickhouse-keeper:latest-alpine"
user: "101:101"
container_name: clickhouse-keeper-01
hostname: clickhouse-keeper-01
volumes:
- ${PWD}/fs/volumes/clickhouse-keeper-01/etc/clickhouse-keeper/keeper_config.xml:/etc/clickhouse-keeper/keeper_config.xml
ports:
- "127.0.0.1:9181:9181"
clickhouse-keeper-02:
image: "clickhouse/clickhouse-keeper:latest-alpine"
user: "101:101"
container_name: clickhouse-keeper-02
hostname: clickhouse-keeper-02
volumes:
- ${PWD}/fs/volumes/clickhouse-keeper-02/etc/clickhouse-keeper/keeper_config.xml:/etc/clickhouse-keeper/keeper_config.xml
ports:
- "127.0.0.1:9182:9181"
clickhouse-keeper-03:
image: "clickhouse/clickhouse-keeper:latest-alpine"
user: "101:101"
container_name: clickhouse-keeper-03
hostname: clickhouse-keeper-03
volumes:
- ${PWD}/fs/volumes/clickhouse-keeper-03/etc/clickhouse-keeper/keeper_config.xml:/etc/clickhouse-keeper/keeper_config.xml
ports:
- "127.0.0.1:9183:9181"Créez les sous-répertoires et fichiers suivants :
for i in {01..02}; do
mkdir -p fs/volumes/clickhouse-${i}/etc/clickhouse-server/config.d
mkdir -p fs/volumes/clickhouse-${i}/etc/clickhouse-server/users.d
touch fs/volumes/clickhouse-${i}/etc/clickhouse-server/config.d/config.xml
touch fs/volumes/clickhouse-${i}/etc/clickhouse-server/users.d/users.xml
done- Le répertoire
config.dcontient le fichier de configuration du serveur ClickHouseconfig.xml, dans lequel est définie la configuration personnalisée de chaque nœud ClickHouse. Cette configuration est fusionnée avec le fichier de configuration ClickHouseconfig.xmlpar défaut fourni avec chaque installation de ClickHouse. - Le répertoire
users.dcontient le fichier de configuration utilisateurusers.xml, dans lequel est définie la configuration personnalisée des utilisateurs. Cette configuration est fusionnée avec le fichier de configuration ClickHouseusers.xmlpar défaut fourni avec chaque installation de ClickHouse.
Configurer les nœuds ClickHouse
Configuration du serveur
Modifiez maintenant chaque fichier de configuration vide config.xml situé dans
fs/volumes/clickhouse-{}/etc/clickhouse-server/config.d. Les lignes surlignées
ci-dessous doivent être adaptées à chaque nœud :
<clickhouse replace="true">
<logger>
<level>debug</level>
<log>/var/log/clickhouse-server/clickhouse-server.log</log>
<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
<size>1000M</size>
<count>3</count>
</logger>
<display_name>cluster_1S_2R node 1</display_name>
<listen_host>0.0.0.0</listen_host>
<http_port>8123</http_port>
<tcp_port>9000</tcp_port>
<user_directories>
<users_xml>
<path>users.xml</path>
</users_xml>
<local_directory>
<path>/var/lib/clickhouse/access/</path>
</local_directory>
</user_directories>
<distributed_ddl>
<path>/clickhouse/task_queue/ddl</path>
</distributed_ddl>
<remote_servers>
<cluster_1S_2R>
<shard>
<internal_replication>true</internal_replication>
<replica>
<host>clickhouse-01</host>
<port>9000</port>
</replica>
<replica>
<host>clickhouse-02</host>
<port>9000</port>
</replica>
</shard>
</cluster_1S_2R>
</remote_servers>
<zookeeper>
<node>
<host>clickhouse-keeper-01</host>
<port>9181</port>
</node>
<node>
<host>clickhouse-keeper-02</host>
<port>9181</port>
</node>
<node>
<host>clickhouse-keeper-03</host>
<port>9181</port>
</node>
</zookeeper>
<macros>
<shard>01</shard>
<replica>01</replica>
<cluster>cluster_1S_2R</cluster>
</macros>
</clickhouse>| Répertoire | File |
|---|---|
fs/volumes/clickhouse-01/etc/clickhouse-server/config.d |
config.xml |
fs/volumes/clickhouse-02/etc/clickhouse-server/config.d |
config.xml |
Chaque section du fichier de configuration ci-dessus est expliquée plus en détail ci-dessous.
Réseau et journalisation
La communication externe via l’interface réseau est activée en configurant le paramètre listen host. Cela garantit que l’hôte du serveur ClickHouse est accessible depuis d’autres hôtes :
<listen_host>0.0.0.0</listen_host>Le port de l’API HTTP est configuré sur 8123 :
<http_port>8123</http_port>Le port TCP utilisé pour la communication via le protocole natif de ClickHouse entre clickhouse-client
et d'autres outils natifs de ClickHouse, ainsi qu'entre clickhouse-server et d'autres clickhouse-servers,
est défini sur 9000:
<tcp_port>9000</tcp_port>La journalisation est définie dans le bloc <logger>. Cet exemple de configuration
génère un journal de débogage qui effectuera une rotation à 1 000 Mo, trois fois :
<logger>
<level>debug</level>
<log>/var/log/clickhouse-server/clickhouse-server.log</log>
<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
<size>1000M</size>
<count>3</count>
</logger>Pour plus d'informations sur la configuration de la journalisation, consultez les commentaires inclus dans le fichier de configuration ClickHouse par défaut.
Configuration du cluster
La configuration du cluster est définie dans le bloc <remote_servers>.
Le nom du cluster cluster_1S_2R y est défini.
Le bloc <cluster_1S_2R></cluster_1S_2R> définit la disposition du cluster,
à l'aide des paramètres <shard></shard> et <replica></replica>, et sert de
template pour les requêtes DDL distribuées, c'est-à-dire les requêtes qui s'exécutent sur l'ensemble du
cluster via la clause ON CLUSTER. Par défaut, les requêtes DDL distribuées
sont autorisées, mais peuvent également être désactivées avec le paramètre allow_distributed_ddl_queries.
internal_replication est défini sur true afin que les données ne soient écrites que sur l'une des répliques.
<remote_servers>
<!-- cluster name (should not contain dots) -->
<cluster_1S_2R>
<!-- <allow_distributed_ddl_queries>false</allow_distributed_ddl_queries> -->
<shard>
<!-- Optional. Whether to write data to just one of the replicas. Default: false (write data to all replicas). -->
<internal_replication>true</internal_replication>
<replica>
<host>clickhouse-01</host>
<port>9000</port>
</replica>
<replica>
<host>clickhouse-02</host>
<port>9000</port>
</replica>
</shard>
</cluster_1S_2R>
</remote_servers>Pour chaque serveur, les paramètres suivants sont définis :
| Paramètre | Description | Valeur par défaut |
|---|---|---|
host |
L’adresse du serveur distant. Vous pouvez utiliser soit le nom de domaine, soit l’adresse IPv4 ou IPv6. Si vous spécifiez le nom de domaine, le serveur effectue une requête DNS au démarrage, et le résultat de la résolution est conservé tant que le serveur est en cours d’exécution. Si la requête DNS échoue, le serveur ne démarre pas. Si vous modifiez l’enregistrement DNS, vous devez redémarrer le serveur. | - |
port |
Le port TCP utilisé pour l’activité de messagerie (tcp_port dans la config, généralement défini sur 9000). À ne pas confondre avec http_port. |
- |
Configuration de Keeper
La section <ZooKeeper> indique à ClickHouse où ClickHouse Keeper (ou ZooKeeper) s'exécute.
Comme nous utilisons un cluster ClickHouse Keeper, chaque <node> du cluster doit être spécifié,
avec son hostname et son numéro de port via les tags <host> et <port> respectivement.
La configuration de ClickHouse Keeper est décrite à l'étape suivante du tutoriel.
<zookeeper>
<node>
<host>clickhouse-keeper-01</host>
<port>9181</port>
</node>
<node>
<host>clickhouse-keeper-02</host>
<port>9181</port>
</node>
<node>
<host>clickhouse-keeper-03</host>
<port>9181</port>
</node>
</zookeeper>Configuration des macros
Par ailleurs, la section <macros> permet de définir des substitutions de paramètres pour
les tables répliquées. Celles-ci sont répertoriées dans system.macros et permettent d'utiliser des substitutions
telles que {shard} et {replica} dans les requêtes.
<macros>
<shard>01</shard>
<replica>01</replica>
<cluster>cluster_1S_2R</cluster>
</macros>Configuration utilisateur
Modifiez maintenant chaque fichier de configuration vide users.xml situé dans
fs/volumes/clickhouse-{}/etc/clickhouse-server/users.d en y ajoutant le contenu suivant :
<?xml version="1.0"?>
<clickhouse replace="true">
<profiles>
<default>
<max_memory_usage>10000000000</max_memory_usage>
<use_uncompressed_cache>0</use_uncompressed_cache>
<load_balancing>in_order</load_balancing>
<log_queries>1</log_queries>
</default>
</profiles>
<users>
<default>
<access_management>1</access_management>
<profile>default</profile>
<networks>
<ip>::/0</ip>
</networks>
<quota>default</quota>
<access_management>1</access_management>
<named_collection_control>1</named_collection_control>
<show_named_collections>1</show_named_collections>
<show_named_collections_secrets>1</show_named_collections_secrets>
</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>| Répertoire | File |
|---|---|
fs/volumes/clickhouse-01/etc/clickhouse-server/users.d |
users.xml |
fs/volumes/clickhouse-02/etc/clickhouse-server/users.d |
users.xml |
Dans cet exemple, l'utilisateur par défaut est configuré sans mot de passe par souci de simplicité. En pratique, cette pratique est déconseillée.
Configurer ClickHouse Keeper
Configuration de ClickHouse Keeper
Pour que la réplication fonctionne, un cluster ClickHouse Keeper doit être mis en place et configuré. ClickHouse Keeper fournit le système de coordination pour la réplication des données, et remplace ZooKeeper, qui peut également être utilisé. ClickHouse Keeper est toutefois recommandé, car il offre de meilleures garanties, une meilleure fiabilité et utilise moins de ressources que ZooKeeper. Pour assurer une haute disponibilité et maintenir le quorum, il est recommandé d’exécuter au moins trois nœuds ClickHouse Keeper.
Créez les fichiers keeper_config.xml pour chaque nœud ClickHouse Keeper
à l’aide de la commande suivante depuis la racine du dossier d’exemple :
for i in {01..03}; do
touch fs/volumes/clickhouse-keeper-${i}/etc/clickhouse-keeper/keeper_config.xml
doneModifiez les fichiers de configuration vides créés dans chaque
répertoire de nœud fs/volumes/clickhouse-keeper-{}/etc/clickhouse-keeper. Les
lignes mises en évidence ci-dessous doivent être adaptées à chaque nœud :
<clickhouse replace="true">
<logger>
<level>information</level>
<log>/var/log/clickhouse-keeper/clickhouse-keeper.log</log>
<errorlog>/var/log/clickhouse-keeper/clickhouse-keeper.err.log</errorlog>
<size>1000M</size>
<count>3</count>
</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>clickhouse-keeper-01</hostname>
<port>9234</port>
</server>
<server>
<id>2</id>
<hostname>clickhouse-keeper-02</hostname>
<port>9234</port>
</server>
<server>
<id>3</id>
<hostname>clickhouse-keeper-03</hostname>
<port>9234</port>
</server>
</raft_configuration>
</keeper_server>
</clickhouse>| Répertoire | Fichier |
|---|---|
fs/volumes/clickhouse-keeper-01/etc/clickhouse-keeper |
keeper_config.xml |
fs/volumes/clickhouse-keeper-02/etc/clickhouse-keeper |
keeper_config.xml |
fs/volumes/clickhouse-keeper-03/etc/clickhouse-keeper |
keeper_config.xml |
Chaque fichier de configuration contient la configuration unique suivante (illustrée ci-dessous).
Le server_id utilisé doit être unique pour ce nœud ClickHouse Keeper
dans le cluster et correspondre à l’<id> du serveur défini dans la section <raft_configuration>.
tcp_port est le port utilisé par les clients de ClickHouse Keeper.
<tcp_port>9181</tcp_port>
<server_id>{id}</server_id>La section suivante permet de configurer les serveurs qui participent au quorum de l’algorithme de consensus Raft :
<raft_configuration>
<server>
<id>1</id>
<hostname>clickhouse-keeper-01</hostname>
<!-- TCP port used for communication between ClickHouse Keeper nodes -->
<port>9234</port>
</server>
<server>
<id>2</id>
<hostname>clickhouse-keeper-02</hostname>
<port>9234</port>
</server>
<server>
<id>3</id>
<hostname>clickhouse-keeper-03</hostname>
<port>9234</port>
</server>
</raft_configuration>Tester la configuration
Assurez-vous que Docker est en cours d’exécution sur votre machine.
Démarrez le cluster à l’aide de la commande docker-compose up depuis la racine du répertoire cluster_1S_2R :
docker-compose up -dVous devriez voir Docker commencer à télécharger les images ClickHouse et Keeper, puis démarrer les conteneurs :
[+] Running 6/6
✔ Network cluster_1s_2r_default Created
✔ Container clickhouse-keeper-03 Started
✔ Container clickhouse-keeper-02 Started
✔ Container clickhouse-keeper-01 Started
✔ Container clickhouse-01 Started
✔ Container clickhouse-02 StartedPour vérifier que le cluster fonctionne, connectez-vous à clickhouse-01 ou à clickhouse-02 et exécutez la
requête suivante. La commande pour se connecter au premier nœud est indiquée :
# Connect to any node
docker exec -it clickhouse-01 clickhouse-clientSi tout se passe bien, vous verrez l’invite de commande du client ClickHouse :
cluster_1S_2R node 1 :)Exécutez la requête suivante pour vérifier quelles topologies de cluster sont définies pour quels hôtes :
SELECT
cluster,
shard_num,
replica_num,
host_name,
port
FROM system.clusters; ┌─cluster───────┬─shard_num─┬─replica_num─┬─host_name─────┬─port─┐
1. │ cluster_1S_2R │ 1 │ 1 │ clickhouse-01 │ 9000 │
2. │ cluster_1S_2R │ 1 │ 2 │ clickhouse-02 │ 9000 │
3. │ default │ 1 │ 1 │ localhost │ 9000 │
└───────────────┴───────────┴─────────────┴───────────────┴──────┘Exécutez la requête suivante pour vérifier l’état du cluster ClickHouse Keeper :
SELECT *
FROM system.zookeeper
WHERE path IN ('/', '/clickhouse') ┌─name───────┬─value─┬─path────────┐
1. │ sessions │ │ /clickhouse │
2. │ task_queue │ │ /clickhouse │
3. │ keeper │ │ / │
4. │ clickhouse │ │ / │
└────────────┴───────┴─────────────┘La commande mntr est également couramment utilisée pour vérifier que ClickHouse Keeper
est en cours d’exécution et pour obtenir des informations sur l’état des relations entre les trois nœuds Keeper.
Dans la configuration utilisée dans cet exemple, trois nœuds fonctionnent ensemble.
Les nœuds éliront un leader, et les nœuds restants seront des followers.
La commande mntr fournit des informations relatives aux performances et indique si un nœud donné
est un follower ou un leader.
Exécutez la commande ci-dessous depuis un shell sur clickhouse-keeper-01, clickhouse-keeper-02 et
clickhouse-keeper-03 pour vérifier l’état de chaque nœud Keeper. La commande
pour clickhouse-keeper-01 est indiquée ci-dessous :
docker exec -it clickhouse-keeper-01 /bin/sh -c 'echo mntr | nc 127.0.0.1 9181'La réponse ci-dessous présente un exemple de réponse d’un nœud follower :
zk_version v23.3.1.2823-testing-46e85357ce2da2a99f56ee83a079e892d7ec3726
zk_avg_latency 0
zk_max_latency 0
zk_min_latency 0
zk_packets_received 0
zk_packets_sent 0
zk_num_alive_connections 0
zk_outstanding_requests 0
zk_server_state follower
zk_znode_count 6
zk_watch_count 0
zk_ephemerals_count 0
zk_approximate_data_size 1271
zk_key_arena_size 4096
zk_latest_snapshot_size 0
zk_open_file_descriptor_count 46
zk_max_file_descriptor_count 18446744073709551615La réponse ci-dessous montre un exemple de réponse renvoyée par un nœud leader :
zk_version v23.3.1.2823-testing-46e85357ce2da2a99f56ee83a079e892d7ec3726
zk_avg_latency 0
zk_max_latency 0
zk_min_latency 0
zk_packets_received 0
zk_packets_sent 0
zk_num_alive_connections 0
zk_outstanding_requests 0
zk_server_state leader
zk_znode_count 6
zk_watch_count 0
zk_ephemerals_count 0
zk_approximate_data_size 1271
zk_key_arena_size 4096
zk_latest_snapshot_size 0
zk_open_file_descriptor_count 48
zk_max_file_descriptor_count 18446744073709551615
zk_followers 2
zk_synced_followers 2Vous avez ainsi configuré avec succès un cluster ClickHouse avec un seul segment et deux répliques. À l’étape suivante, vous créerez une table dans le cluster.
Créer une base de données
Maintenant que vous avez vérifié que le cluster est correctement configuré et fonctionne, vous allez recréer la même table que celle utilisée dans le tutoriel du jeu de données d’exemple sur les prix de l’immobilier au Royaume-Uni. Il contient environ 30 millions de lignes correspondant aux prix payés pour des biens immobiliers en Angleterre et au pays de Galles depuis 1995.
Connectez-vous au client de chaque hôte en exécutant chacune des commandes suivantes dans des onglets ou fenêtres de terminal distincts :
docker exec -it clickhouse-01 clickhouse-client
docker exec -it clickhouse-02 clickhouse-clientVous pouvez exécuter la requête ci-dessous depuis clickhouse-client sur chaque hôte afin de vérifier
qu'aucune base de données n'a encore été créée, en dehors de celles par défaut :
SHOW DATABASES; ┌─name───────────────┐
1. │ INFORMATION_SCHEMA │
2. │ default │
3. │ information_schema │
4. │ system │
└────────────────────┘Depuis le client clickhouse-01, exécutez la requête DDL distribuée suivante à l’aide de la
clause ON CLUSTER pour créer une nouvelle base de données nommée uk :
CREATE DATABASE IF NOT EXISTS uk
ON CLUSTER cluster_1S_2R;Vous pouvez à nouveau exécuter la même requête qu’auparavant depuis le client de chaque hôte
pour confirmer que la base de données a bien été créée sur l’ensemble du cluster, bien que la requête
n’ait été exécutée que sur clickhouse-01 :
SHOW DATABASES; ┌─name───────────────┐
1. │ INFORMATION_SCHEMA │
2. │ default │
3. │ information_schema │
4. │ system │
5. │ uk │
└────────────────────┘Créer une table sur le cluster
Maintenant que la base de données a été créée, créez une table sur le cluster. Exécutez la requête suivante depuis n’importe quel client hôte :
CREATE TABLE IF NOT EXISTS uk.uk_price_paid_local
ON CLUSTER cluster_1S_2R
(
price UInt32,
date Date,
postcode1 LowCardinality(String),
postcode2 LowCardinality(String),
type Enum8('terraced' = 1, 'semi-detached' = 2, 'detached' = 3, 'flat' = 4, 'other' = 0),
is_new UInt8,
duration Enum8('freehold' = 1, 'leasehold' = 2, 'unknown' = 0),
addr1 String,
addr2 String,
street LowCardinality(String),
locality LowCardinality(String),
town LowCardinality(String),
district LowCardinality(String),
county LowCardinality(String)
)
ENGINE = ReplicatedMergeTree
ORDER BY (postcode1, postcode2, addr1, addr2);Notez qu'elle est identique à la requête utilisée dans l'instruction CREATE d'origine du
tutoriel du jeu de données d'exemple
prix de l'immobilier au Royaume-Uni,
à l'exception de la clause ON CLUSTER et de l'utilisation du moteur ReplicatedMergeTree.
La clause ON CLUSTER est conçue pour l'exécution distribuée des requêtes DDL (langage de définition de données)
telles que CREATE, DROP, ALTER et RENAME, afin de garantir que ces
modifications de schéma sont appliquées à tous les nœuds du cluster.
Le moteur ReplicatedMergeTree
fonctionne comme le moteur de table MergeTree classique, mais il réplique également les données.
Vous pouvez exécuter la requête ci-dessous depuis le client clickhouse-01 ou clickhouse-02
pour vérifier que la table a bien été créée sur l'ensemble du cluster :
SHOW TABLES IN uk; ┌─name────────────────┐
1. │ uk_price_paid. │
└─────────────────────┘Insérer des données
Le jeu de données étant volumineux et son ingestion complète prenant quelques minutes, nous n'insérerons dans un premier temps qu'un petit sous-ensemble.
Insérez un sous-ensemble réduit des données à l'aide de la requête ci-dessous depuis clickhouse-01 :
INSERT INTO uk.uk_price_paid_local
SELECT
toUInt32(price_string) AS price,
parseDateTimeBestEffortUS(time) AS date,
splitByChar(' ', postcode)[1] AS postcode1,
splitByChar(' ', postcode)[2] AS postcode2,
transform(a, ['T', 'S', 'D', 'F', 'O'], ['terraced', 'semi-detached', 'detached', 'flat', 'other']) AS type,
b = 'Y' AS is_new,
transform(c, ['F', 'L', 'U'], ['freehold', 'leasehold', 'unknown']) AS duration,
addr1,
addr2,
street,
locality,
town,
district,
county
FROM url(
'http://prod1.publicdata.landregistry.gov.uk.s3-website-eu-west-1.amazonaws.com/pp-complete.csv',
'CSV',
'uuid_string String,
price_string String,
time String,
postcode String,
a String,
b String,
c String,
addr1 String,
addr2 String,
street String,
locality String,
town String,
district String,
county String,
d String,
e String'
) LIMIT 10000
SETTINGS max_http_get_redirects=10;Notez que les données sont entièrement répliquées sur chaque hôte :
-- clickhouse-01
SELECT count(*)
FROM uk.uk_price_paid_local
-- ┌─count()─┐
-- 1.│ 10000 │
-- └─────────┘
-- clickhouse-02
SELECT count(*)
FROM uk.uk_price_paid_local
-- ┌─count()─┐
-- 1.│ 10000 │
-- └─────────┘Pour illustrer ce qui se passe lorsque l'un des hôtes tombe en panne, créez une base de données de test simple et une table de test depuis l'un ou l'autre des hôtes :
CREATE DATABASE IF NOT EXISTS test ON CLUSTER cluster_1S_2R;
CREATE TABLE test.test_table ON CLUSTER cluster_1S_2R
(
`id` UInt64,
`name` String
)
ENGINE = ReplicatedMergeTree
ORDER BY id;Comme pour la table uk_price_paid, nous pouvons insérer des données depuis l'un ou l'autre hôte :
INSERT INTO test.test_table (id, name) VALUES (1, 'Clicky McClickface');Mais que se passe-t-il si l'un des hôtes est indisponible ? Pour simuler ce scénario, arrêtez
clickhouse-01 en exécutant :
docker stop clickhouse-01Vérifiez que l'hôte est hors ligne en exécutant :
docker-compose psNAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
clickhouse-02 clickhouse/clickhouse-server:latest "/entrypoint.sh" clickhouse-02 X minutes ago Up X minutes 127.0.0.1:8124->8123/tcp, 127.0.0.1:9001->9000/tcp
clickhouse-keeper-01 clickhouse/clickhouse-keeper:latest-alpine "/entrypoint.sh" clickhouse-keeper-01 X minutes ago Up X minutes 127.0.0.1:9181->9181/tcp
clickhouse-keeper-02 clickhouse/clickhouse-keeper:latest-alpine "/entrypoint.sh" clickhouse-keeper-02 X minutes ago Up X minutes 127.0.0.1:9182->9181/tcp
clickhouse-keeper-03 clickhouse/clickhouse-keeper:latest-alpine "/entrypoint.sh" clickhouse-keeper-03 X minutes ago Up X minutes 127.0.0.1:9183->9181/tcpclickhouse-01 étant maintenant hors ligne, insérez une nouvelle ligne de données dans la table de test
et interrogez la table :
INSERT INTO test.test_table (id, name) VALUES (2, 'Alexey Milovidov');
SELECT * FROM test.test_table; ┌─id─┬─name───────────────┐
1. │ 1 │ Clicky McClickface │
2. │ 2 │ Alexey Milovidov │
└────┴────────────────────┘Redémarrez maintenant clickhouse-01 avec la commande suivante (vous pouvez exécuter à nouveau docker-compose ps ensuite pour confirmer) :
docker start clickhouse-01Interrogez à nouveau la table de test depuis clickhouse-01 après avoir exécuté docker exec -it clickhouse-01 clickhouse-client :
SELECT * FROM test.test_table ┌─id─┬─name───────────────┐
1. │ 1 │ Clicky McClickface │
2. │ 2 │ Alexey Milovidov │
└────┴────────────────────┘Si vous souhaitez à ce stade ingérer l'intégralité du jeu de données des prix immobiliers au Royaume-Uni pour l'explorer, vous pouvez exécuter les requêtes suivantes :
TRUNCATE TABLE uk.uk_price_paid_local ON CLUSTER cluster_1S_2R;
INSERT INTO uk.uk_price_paid_local
SELECT
toUInt32(price_string) AS price,
parseDateTimeBestEffortUS(time) AS date,
splitByChar(' ', postcode)[1] AS postcode1,
splitByChar(' ', postcode)[2] AS postcode2,
transform(a, ['T', 'S', 'D', 'F', 'O'], ['terraced', 'semi-detached', 'detached', 'flat', 'other']) AS type,
b = 'Y' AS is_new,
transform(c, ['F', 'L', 'U'], ['freehold', 'leasehold', 'unknown']) AS duration,
addr1,
addr2,
street,
locality,
town,
district,
county
FROM url(
'http://prod1.publicdata.landregistry.gov.uk.s3-website-eu-west-1.amazonaws.com/pp-complete.csv',
'CSV',
'uuid_string String,
price_string String,
time String,
postcode String,
a String,
b String,
c String,
addr1 String,
addr2 String,
street String,
locality String,
town String,
district String,
county String,
d String,
e String'
) SETTINGS max_http_get_redirects=10;Interrogez la table depuis clickhouse-02 ou clickhouse-01 :
SELECT count(*) FROM uk.uk_price_paid_local; ┌──count()─┐
1. │ 30212555 │ -- 30.21 million
└──────────┘Conclusion
L’avantage de cette topologie de cluster est qu’avec deux répliques, vos données sont présentes sur deux hôtes distincts. Si l’un des hôtes tombe en panne, l’autre réplique continue de servir les données sans aucune perte. Cela élimine les points de défaillance uniques au niveau du stockage.
Lorsqu’un hôte tombe en panne, la réplique restante est toujours en mesure de :
- Traiter les requêtes en lecture sans interruption
- Accepter de nouvelles écritures (selon vos paramètres de cohérence)
- Maintenir la disponibilité du service pour les applications
Lorsque l’hôte défaillant revient en ligne, il est en mesure de :
- Synchroniser automatiquement les données manquantes à partir de la réplique saine
- Reprendre un fonctionnement normal sans intervention manuelle
- Rétablir rapidement une redondance complète
Dans l’exemple suivant, nous verrons comment configurer un cluster avec deux shards mais une seule réplique.