Passer au contenu principal
Le moteur est basé sur le moteur Atomic. Il prend en charge la réplication des métadonnées via un journal DDL écrit dans ZooKeeper et exécuté sur toutes les répliques d’une base de données donnée. Un serveur ClickHouse peut exécuter plusieurs bases de données répliquées et les mettre à jour simultanément. En revanche, il ne peut pas y avoir plusieurs répliques d’une même base de données répliquée.

Créer une base de données

CREATE DATABASE testdb [UUID '...'] ENGINE = Replicated('zoo_path', 'shard_name', 'replica_name') [SETTINGS ...]
Paramètres du moteur
  • zoo_path — chemin ZooKeeper. Un même chemin ZooKeeper correspond à une même base de données.
  • shard_name — nom du shard. Les répliques de la base de données sont regroupées en shards selon shard_name.
  • replica_name — nom de la réplique. Les noms de réplique doivent être différents pour toutes les répliques d’un même shard.
Les paramètres peuvent être omis ; dans ce cas, les paramètres manquants sont remplacés par les valeurs par défaut. Si zoo_path contient la macro {uuid}, il est nécessaire de spécifier un UUID explicite ou d’ajouter ON CLUSTER à l’instruction CREATE afin de garantir que toutes les répliques utilisent le même UUID pour cette base de données. Pour les tables ReplicatedMergeTree, si aucun argument n’est fourni, les arguments par défaut suivants sont utilisés : /clickhouse/tables/{uuid}/{shard} et {replica}. Ils peuvent être modifiés dans les paramètres du serveur default_replica_path et default_replica_name. La macro {uuid} est remplacée par l’uuid de la table, tandis que {shard} et {replica} sont remplacés par les valeurs issues de la configuration du serveur, et non des arguments du moteur de base de données. Mais à l’avenir, il sera possible d’utiliser shard_name et replica_name de la base de données Replicated. Un cluster ZooKeeper auxiliaire est également pris en charge pour stocker les métadonnées d’une base de données répliquée au lieu d’utiliser le cluster ZooKeeper par défaut. Vous pouvez utiliser SQL pour créer la base de données répliquée avec un cluster ZooKeeper auxiliaire, comme suit :
CREATE DATABASE database_name ENGINE = Replicated('zookeeper_name_configured_in_auxiliary_zookeepers:path', 'shard_name', 'replica_name')

Spécificités et recommandations

Les requêtes DDL avec une base de données Replicated fonctionnent de manière similaire aux requêtes ON CLUSTER, avec toutefois quelques différences mineures. Tout d’abord, la requête DDL tente de s’exécuter sur l’initiateur (l’hôte qui a initialement reçu la requête de l’utilisateur). Si la requête échoue, l’utilisateur reçoit immédiatement une erreur et les autres hôtes ne tentent pas de l’exécuter. Si la requête a été exécutée avec succès sur l’initiateur, tous les autres hôtes la retenteront automatiquement jusqu’à ce qu’elle aboutisse. L’initiateur essaiera d’attendre que la requête soit terminée sur les autres hôtes (pas plus longtemps que distributed_ddl_task_timeout) et renverra une table contenant les statuts d’exécution de la requête sur chaque hôte. Le comportement en cas d’erreur est régi par le paramètre distributed_ddl_output_mode ; pour une base de données Replicated, il est préférable de le définir sur null_status_on_timeout — c.-à-d. que si certains hôtes n’ont pas eu le temps d’exécuter la requête dans le délai de distributed_ddl_task_timeout, il ne faut pas lever d’exception, mais afficher le statut NULL pour ces hôtes dans la table. La table système system.clusters contient un cluster portant le même nom que la base de données répliquée, qui se compose de toutes les répliques de la base de données. Ce cluster est mis à jour automatiquement lors de la création ou de la suppression de répliques, et il peut être utilisé pour les tables Distributed. Lors de la création d’une nouvelle réplique de la base de données, cette réplique crée elle-même les tables. Si la réplique a été indisponible pendant longtemps et a pris du retard sur le journal de réplication, elle compare ses métadonnées locales aux métadonnées actuelles dans ZooKeeper, déplace les tables supplémentaires avec leurs données vers une base de données séparée non répliquée (afin de ne pas supprimer accidentellement des éléments superflus), crée les tables manquantes et met à jour les noms des tables si elles ont été renommées. Les données sont répliquées au niveau de ReplicatedMergeTree, c.-à-d. que si la table n’est pas répliquée, les données ne le seront pas non plus (la base de données n’est responsable que des métadonnées). Les requêtes ALTER TABLE FREEZE|ATTACH|FETCH|DROP|DROP DETACHED|DETACH PARTITION|PART sont autorisées, mais ne sont pas répliquées. Le moteur de base de données ajoutera/récupérera/supprimera uniquement la partition/la partie sur la réplique actuelle. Cependant, si la table elle-même utilise un moteur de table Replicated, les données seront répliquées après l’utilisation de ATTACH. Si vous avez seulement besoin de configurer un cluster sans maintenir la réplication des tables, reportez-vous à la fonctionnalité Cluster Discovery.

Exemple d’utilisation

Création d’un cluster de trois hôtes :
node1 :) CREATE DATABASE r ENGINE=Replicated('some/path/r','shard1','replica1');
node2 :) CREATE DATABASE r ENGINE=Replicated('some/path/r','shard1','other_replica');
node3 :) CREATE DATABASE r ENGINE=Replicated('some/path/r','other_shard','{replica}');
Création d’une base de données sur un cluster avec des paramètres implicites :
CREATE DATABASE r ON CLUSTER default ENGINE=Replicated;
Exécution de la requête DDL :
CREATE TABLE r.rmt (n UInt64) ENGINE=ReplicatedMergeTree ORDER BY n;
┌─────hosts────────────┬──status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ shard1|replica1      │    0    │       │          2          │        0         │
│ shard1|other_replica │    0    │       │          1          │        0         │
│ other_shard|r1       │    0    │       │          0          │        0         │
└──────────────────────┴─────────┴───────┴─────────────────────┴──────────────────┘
Affichage de la table système :
SELECT cluster, shard_num, replica_num, host_name, host_address, port, is_local
FROM system.clusters WHERE cluster='r';
┌─cluster─┬─shard_num─┬─replica_num─┬─host_name─┬─host_address─┬─port─┬─is_local─┐
│ r       │     1     │      1      │   node3   │  127.0.0.1   │ 9002 │     0    │
│ r       │     2     │      1      │   node2   │  127.0.0.1   │ 9001 │     0    │
│ r       │     2     │      2      │   node1   │  127.0.0.1   │ 9000 │     1    │
└─────────┴───────────┴─────────────┴───────────┴──────────────┴──────┴──────────┘
Créer une table distribuée et insérer les données :
node2 :) CREATE TABLE r.d (n UInt64) ENGINE=Distributed('r','r','rmt', n % 2);
node3 :) INSERT INTO r.d SELECT * FROM numbers(10);
node1 :) SELECT materialize(hostName()) AS host, groupArray(n) FROM r.d GROUP BY host;
┌─hosts─┬─groupArray(n)─┐
│ node3 │  [1,3,5,7,9]  │
│ node2 │  [0,2,4,6,8]  │
└───────┴───────────────┘
Ajout d’une réplique sur un hôte supplémentaire :
node4 :) CREATE DATABASE r ENGINE=Replicated('some/path/r','other_shard','r2');
Ajout d’une réplique sur un hôte supplémentaire si la macro {uuid} est utilisée dans zoo_path :
node1 :) SELECT uuid FROM system.databases WHERE database='r';
node4 :) CREATE DATABASE r UUID '<uuid from previous query>' ENGINE=Replicated('some/path/{uuid}','other_shard','r2');
La configuration du cluster ressemblera à ceci :
┌─cluster─┬─shard_num─┬─replica_num─┬─host_name─┬─host_address─┬─port─┬─is_local─┐
│ r       │     1     │      1      │   node3   │  127.0.0.1   │ 9002 │     0    │
│ r       │     1     │      2      │   node4   │  127.0.0.1   │ 9003 │     0    │
│ r       │     2     │      1      │   node2   │  127.0.0.1   │ 9001 │     0    │
│ r       │     2     │      2      │   node1   │  127.0.0.1   │ 9000 │     1    │
└─────────┴───────────┴─────────────┴───────────┴──────────────┴──────┴──────────┘
La table distribuée récupérera également les données du nouvel hôte :
node2 :) SELECT materialize(hostName()) AS host, groupArray(n) FROM r.d GROUP BY host;
┌─hosts─┬─groupArray(n)─┐
│ node2 │  [1,3,5,7,9]  │
│ node4 │  [0,2,4,6,8]  │
└───────┴───────────────┘

Paramètres

Les paramètres suivants sont pris en charge :
ParamètrePar défautDescription
max_broken_tables_ratio1Ne récupère pas automatiquement la réplique si la proportion de tables obsolètes par rapport au nombre total de tables est supérieure
max_replication_lag_to_enqueue50La réplique lèvera une exception lors d’une tentative d’exécution d’une requête si son retard de réplication est supérieur
wait_entry_commited_timeout_sec3600Les répliques tenteront d’annuler la requête si le délai d’expiration est dépassé, mais que l’hôte initiateur ne l’a pas encore exécutée
collection_nameNom d’une collection définie dans la configuration du serveur, où toutes les informations d’authentification du cluster sont définies
check_consistencytrueVérifie la cohérence entre les métadonnées locales et celles de Keeper, et récupère la réplique en cas d’incohérence
max_retries_before_automatic_recovery10Nombre maximal de tentatives d’exécution d’une entrée de la file d’attente avant de marquer la réplique comme perdue et de la récupérer depuis un instantané (0 signifie infini)
allow_skipping_old_temporary_tables_ddls_of_refreshable_materialized_viewsfalseSi activé, lors du traitement des DDL dans les bases de données Replicated, ignore si possible la création et l’échange des DDL des tables temporaires des vues matérialisées actualisables
logs_to_keep1000Nombre de journaux conservés par défaut dans ZooKeeper pour une base de données Replicated.
default_replica_path/clickhouse/databases/{uuid}Chemin vers la base de données dans ZooKeeper. Utilisé lors de la création de la base de données si les arguments sont omis.
default_replica_shard_name{shard}Nom du shard de la réplique dans la base de données. Utilisé lors de la création de la base de données si les arguments sont omis.
default_replica_name{replica}Nom de la réplique dans la base de données. Utilisé lors de la création de la base de données si les arguments sont omis.
internal_replicationfalseIndique si une table Distributed créée avec le cluster de cette base de données Replicated enverra les données à l’une des répliques (la réplication interne signifie que les répliques du cluster effectuent elles-mêmes la réplication) ou à toutes les répliques (sans réplication interne, la table Distributed enverra les données insérées à toutes les répliques)
Les valeurs par défaut peuvent être remplacées dans le fichier de configuration
<clickhouse>
    <database_replicated>
        <max_broken_tables_ratio>0.75</max_broken_tables_ratio>
        <max_replication_lag_to_enqueue>100</max_replication_lag_to_enqueue>
        <wait_entry_commited_timeout_sec>1800</wait_entry_commited_timeout_sec>
        <collection_name>postgres1</collection_name>
        <check_consistency>false</check_consistency>
        <max_retries_before_automatic_recovery>5</max_retries_before_automatic_recovery>
        <default_replica_path>/clickhouse/databases/{uuid}</default_replica_path>
        <default_replica_shard_name>{shard}</default_replica_shard_name>
        <default_replica_name>{replica}</default_replica_name>
        <internal_replication>false</internal_replication>
    </database_replicated>
</clickhouse>
Dernière modification le 25 juin 2026