> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Mise à l'échelle

> Page décrivant un exemple d’architecture conçu pour assurer l’évolutivité

export const Image = ({img, alt, size = "lg"}) => {
  const normalizedSize = ["sm", "md", "lg"].includes(size) ? size : "lg";
  return <div className={`ch-image-${normalizedSize}`}>
      <Frame>
        <img src={img} alt={alt} />
      </Frame>
    </div>;
};

> Dans cet exemple, vous allez apprendre à mettre en place un cluster ClickHouse simple et
> évolutif. Cinq serveurs sont configurés. Deux servent à sharder les données.
> Les trois autres sont utilisés pour la coordination.

L’architecture du cluster que vous allez mettre en place est illustrée ci-dessous :

<Image img="https://mintcdn.com/private-7c7dfe99/NvnCM4vX9aZ07JxK/images/deployment-guides/replication-sharding-examples/sharding.webp?fit=max&auto=format&n=NvnCM4vX9aZ07JxK&q=85&s=bb9b9d42024b0aed234f3cc36f854628" size="md" alt="Schéma d’architecture pour 2 shards et 1 réplique" width="1200" height="800" data-path="images/deployment-guides/replication-sharding-examples/sharding.webp" />

<Note>
  Bien qu'il soit possible d'exécuter ClickHouse Server et ClickHouse Keeper sur le même serveur,
  nous recommandons vivement d'utiliser des hôtes *dédiés* pour ClickHouse Keeper dans les environnements de production.
  C'est l'approche que nous allons illustrer dans cet exemple.

  Les serveurs Keeper peuvent être plus modestes, et 4 Go de RAM suffisent généralement pour chaque serveur Keeper
  jusqu'à ce que vos serveurs ClickHouse prennent de l'ampleur.
</Note>

<div id="pre-requisites">
  ## Prérequis
</div>

* Vous avez déjà installé un [serveur ClickHouse local](/docs/fr/get-started/setup/install)
* Vous maîtrisez les concepts de base de la configuration de ClickHouse, comme les [fichiers de configuration](/docs/fr/concepts/features/configuration/server-config/configuration-files)
* Docker est installé sur votre machine

<Steps>
  <Step title="Configurer la structure de répertoires et l'environnement de test" id="set-up">
    <Tip>
      **Fichiers d'exemple**

      Les étapes suivantes vous guideront dans la configuration du cluster à partir de
      zéro. Si vous préférez ignorer ces étapes et passer directement à l'exécution du
      cluster, vous pouvez récupérer les fichiers
      d'exemple dans le dépôt examples, dans le ['répertoire docker-compose-recipes'](https://github.com/ClickHouse/examples/tree/main/docker-compose-recipes/recipes).
    </Tip>

    Dans ce tutoriel, vous utiliserez [Docker compose](https://docs.docker.com/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 :

    ```bash theme={null}
    mkdir cluster_2S_1R
    cd cluster_2S_1R

    # 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
    done
    ```

    Ajoutez le fichier `docker-compose.yml` suivant dans le répertoire `cluster_2S_1R` :

    ```yaml title="docker-compose.yml" theme={null}
    version: '3.8'
    services:
      clickhouse-01:
        image: "clickhouse/clickhouse-server:latest"
        user: "101:101"
        container_name: clickhouse-01
        hostname: clickhouse-01
        networks:
          cluster_2S_1R:
            ipv4_address: 192.168.7.1
        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
        networks:
          cluster_2S_1R:
            ipv4_address: 192.168.7.2
        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
        networks:
          cluster_2S_1R:
            ipv4_address: 192.168.7.5
        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
        networks:
          cluster_2S_1R:
            ipv4_address: 192.168.7.6
        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
        networks:
          cluster_2S_1R:
            ipv4_address: 192.168.7.7
        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"
    networks:
      cluster_2S_1R:
        driver: bridge
        ipam:
          config:
            - subnet: 192.168.7.0/24
              gateway: 192.168.7.254
    ```

    Créez les sous-répertoires et fichiers suivants :

    ```bash theme={null}
    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.d` contient le fichier de configuration du serveur ClickHouse `config.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 ClickHouse `config.xml`
      par défaut fourni avec chaque installation de ClickHouse.
    * Le répertoire `users.d` contient le fichier de configuration utilisateur `users.xml`, dans lequel
      est définie la configuration personnalisée des utilisateurs. Cette configuration est fusionnée avec
      le fichier de configuration ClickHouse `users.xml` par défaut fourni avec chaque
      installation de ClickHouse.

    <Tip>
      **Répertoires de configuration personnalisés**

      Il est recommandé d'utiliser les répertoires `config.d` et `users.d` lors de la
      rédaction de votre propre configuration, plutôt que de modifier directement la configuration par défaut
      dans `/etc/clickhouse-server/config.xml` et `etc/clickhouse-server/users.xml`.

      La ligne

      ```xml theme={null}
      <clickhouse replace="true">
      ```

      garantit que les sections de configuration définies dans les répertoires `config.d` et `users.d`
      remplacent les sections de configuration par défaut définies dans les fichiers
      `config.xml` et `users.xml`.
    </Tip>
  </Step>

  <Step title="Configurer les nœuds ClickHouse" id="configure-clickhouse-servers">
    ### 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 :

    ```xml highlight={9,54-57} theme={null}
    <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_2S_1R 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_2S_1R>
                <shard>
                    <replica>
                        <host>clickhouse-01</host>
                        <port>9000</port>
                    </replica>
                </shard>
                <shard>
                    <replica>
                        <host>clickhouse-02</host>
                        <port>9000</port>
                    </replica>
                </shard>
            </cluster_2S_1R>
        </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>
        </macros>
    </clickhouse>
    ```

    | Répertoire                                                | File                                                                                                                                                                             |
    | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `fs/volumes/clickhouse-01/etc/clickhouse-server/config.d` | [`config.xml`](https://github.com/ClickHouse/examples/blob/main/docker-compose-recipes/recipes/cluster_2S_1R/fs/volumes/clickhouse-01/etc/clickhouse-server/config.d/config.xml) |
    | `fs/volumes/clickhouse-02/etc/clickhouse-server/config.d` | [`config.xml`](https://github.com/ClickHouse/examples/blob/main/docker-compose-recipes/recipes/cluster_2S_1R/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 :

    ```xml theme={null}
    <listen_host>0.0.0.0</listen_host>
    ```

    Le port de l’API HTTP est configuré sur `8123` :

    ```xml theme={null}
    <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`:

    ```xml theme={null}
    <tcp_port>9000</tcp_port>
    ```

    La journalisation est définie dans le bloc `<logger>`. Cet exemple de configuration
    vous fournit un journal de débogage qui effectuera une rotation à 1000 Mo, trois fois :

    ```xml theme={null}
    <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](https://github.com/ClickHouse/ClickHouse/blob/master/programs/server/config.xml) ClickHouse par défaut.

    #### Configuration du cluster

    La configuration du cluster est définie dans le bloc `<remote_servers>`.
    Le nom du cluster `cluster_2S_1R` y est déclaré.

    Le bloc `<cluster_2S_1R></cluster_2S_1R>` définit la disposition du cluster,
    à l'aide des paramètres `<shard></shard>` et `<replica></replica>`, et sert de
    modèle 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 laissé à false par défaut, car il n'y a qu'un seul réplica par segment.

    ```xml theme={null}
    <remote_servers>
        <cluster_2S_1R>
            <shard>
                <replica>
                    <host>clickhouse-01</host>
                    <port>9000</port>
                </replica>
            </shard>
            <shard>
                <replica>
                    <host>clickhouse-02</host>
                    <port>9000</port>
                </replica>
            </shard>
        </cluster_2S_1R>
    </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) est en cours d'exécution.
    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 présentée à l'étape suivante du tutoriel.

    ```xml theme={null}
    <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>
    ```

    <Note>
      Bien qu’il soit possible d’exécuter ClickHouse Keeper sur le même serveur que ClickHouse Server,
      dans les environnements de production, nous recommandons vivement d’exécuter ClickHouse Keeper sur des hôtes dédiés.
    </Note>

    #### 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.

    ```xml theme={null}
    <macros>
        <shard>01</shard>
        <replica>01</replica>
    </macros>
    ```

    <Note>
      Ils seront définis en fonction de la topologie du cluster.
    </Note>

    ### 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 title="/users.d/users.xml" theme={null}
    <?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`](https://github.com/ClickHouse/examples/blob/main/docker-compose-recipes/recipes/cluster_2S_1R/fs/volumes/clickhouse-01/etc/clickhouse-server/users.d/users.xml) |
    | `fs/volumes/clickhouse-02/etc/clickhouse-server/users.d` | [`users.xml`](https://github.com/ClickHouse/examples/blob/main/docker-compose-recipes/recipes/cluster_2S_1R/fs/volumes/clickhouse-02/etc/clickhouse-server/users.d/users.xml) |

    Dans cet exemple, le default user est configuré sans password par souci de simplicité.
    En pratique, cette pratique est déconseillée.

    <Note>
      Dans cet exemple, le fichier `users.xml` est identique sur tous les nœuds du cluster.
    </Note>
  </Step>

  <Step title="Configurer ClickHouse Keeper" id="configure-clickhouse-keeper-nodes">
    ### 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.

    <Note>
      ClickHouse Keeper peut s’exécuter sur n’importe quel nœud du cluster aux côtés de ClickHouse, mais il
      est recommandé de l’exécuter sur un nœud dédié, ce qui permet de faire évoluer et de
      gérer le cluster ClickHouse Keeper indépendamment du cluster de base de données.
    </Note>

    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 :

    ```bash theme={null}
    for i in {01..03}; do
      touch fs/volumes/clickhouse-keeper-${i}/etc/clickhouse-keeper/keeper_config.xml
    done
    ```

    Modifiez 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 :

    ```xml title="/clickhouse-keeper/keeper_config.xml" highlight={12} theme={null}
    <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`](https://github.com/ClickHouse/examples/blob/main/docker-compose-recipes/recipes/cluster_2S_1R/fs/volumes/clickhouse-keeper-01/etc/clickhouse-keeper/keeper_config.xml) |
    | `fs/volumes/clickhouse-keeper-02/etc/clickhouse-keeper` | [`keeper_config.xml`](https://github.com/ClickHouse/examples/blob/main/docker-compose-recipes/recipes/cluster_2S_1R/fs/volumes/clickhouse-keeper-02/etc/clickhouse-keeper/keeper_config.xml) |
    | `fs/volumes/clickhouse-keeper-03/etc/clickhouse-keeper` | [`keeper_config.xml`](https://github.com/ClickHouse/examples/blob/main/docker-compose-recipes/recipes/cluster_2S_1R/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.

    ```xml theme={null}
    <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](https://en.wikipedia.org/wiki/Raft_\(algorithm\)) :

    ```xml highlight={6} theme={null}
    <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>
    ```

    <Tip>
      **ClickHouse Cloud simplifie la gestion**

      [ClickHouse Cloud](/docs/fr/products/cloud/getting-started/intro)
      allège la charge opérationnelle liée à la gestion des shards et des réplicas. La
      plateforme gère automatiquement la haute disponibilité, la réplication et les ajustements de capacité.
      La puissance de calcul et le stockage sont dissociés et s’adaptent à la demande sans nécessiter de
      configuration manuelle ni de maintenance continue.

      [En savoir plus](/docs/fr/products/cloud/features/autoscaling/overview)
    </Tip>
  </Step>

  <Step title="Tester la configuration" id="test-the-setup">
    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_2S_1R` :

    ```bash theme={null}
    docker-compose up -d
    ```

    Vous devriez voir Docker commencer à télécharger les images ClickHouse et Keeper,
    puis démarrer les conteneurs :

    ```bash theme={null}
    [+] Running 6/6
     ✔ Network cluster_2s_1r_default   Created
     ✔ Container clickhouse-keeper-03  Started
     ✔ Container clickhouse-keeper-02  Started
     ✔ Container clickhouse-keeper-01  Started
     ✔ Container clickhouse-01         Started
     ✔ Container clickhouse-02         Started
    ```

    Pour vérifier que le cluster fonctionne, connectez-vous à `clickhouse-01` ou à `clickhouse-02`, puis exécutez la
    requête suivante. La commande pour se connecter au premier nœud est indiquée ci-dessous :

    ```bash theme={null}
    # Connect to any node
    docker exec -it clickhouse-01 clickhouse-client
    ```

    Si l’opération réussit, vous verrez l’invite du client ClickHouse :

    ```response theme={null}
    cluster_2S_1R node 1 :)
    ```

    Exécutez la requête suivante pour vérifier quelles topologies de cluster sont définies sur quels
    hôtes :

    ```sql title="Query" theme={null}
    SELECT 
        cluster,
        shard_num,
        replica_num,
        host_name,
        port
    FROM system.clusters;
    ```

    ```response title="Response" theme={null}
       ┌─cluster───────┬─shard_num─┬─replica_num─┬─host_name─────┬─port─┐
    1. │ cluster_2S_1R │         1 │           1 │ clickhouse-01 │ 9000 │
    2. │ cluster_2S_1R │         2 │           1 │ clickhouse-02 │ 9000 │
    3. │ default       │         1 │           1 │ localhost     │ 9000 │
       └───────────────┴───────────┴─────────────┴───────────────┴──────┘
    ```

    Exécutez la requête suivante pour vérifier l’état du cluster ClickHouse Keeper :

    ```sql title="Query" theme={null}
    SELECT *
    FROM system.zookeeper
    WHERE path IN ('/', '/clickhouse')
    ```

    ```response title="Response" theme={null}
       ┌─name───────┬─value─┬─path────────┐
    1. │ task_queue │       │ /clickhouse │
    2. │ sessions   │       │ /clickhouse │
    3. │ clickhouse │       │ /           │
    4. │ keeper     │       │ /           │
       └────────────┴───────┴─────────────┘
    ```

    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.

    <Tip>
      Il peut être nécessaire d’installer `netcat` afin d’envoyer la commande `mntr` à Keeper.
      Veuillez consulter la page [nmap.org](https://nmap.org/ncat/) pour les informations de téléchargement.
    </Tip>

    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 :

    ```bash theme={null}
    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 :

    ```response title="Response" highlight={9} theme={null}
    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    18446744073709551615
    ```

    La réponse ci-dessous montre un exemple de réponse renvoyée par un nœud leader :

    ```response title="Response" highlight={9,18-19} theme={null}
    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     2
    ```

    Vous avez ainsi configuré avec succès un cluster ClickHouse avec deux shards et une réplique par shard.
    À l’étape suivante, vous créerez une table dans le cluster.
  </Step>

  <Step title="Créer une base de données" id="creating-a-database">
    Maintenant que vous avez vérifié que le cluster est correctement configuré et en cours d’exécution, 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](/docs/fr/get-started/sample-datasets/uk-price-paid).
    Il contient environ 30 millions de lignes correspondant aux prix d’achat
    de biens immobiliers en Angleterre et au Pays de Galles depuis 1995.

    Connectez-vous au client de chacun des hôtes en exécutant chacune des commandes suivantes dans des
    onglets ou fenêtres de terminal distincts :

    ```bash theme={null}
    docker exec -it clickhouse-01 clickhouse-client
    docker exec -it clickhouse-02 clickhouse-client
    ```

    Vous pouvez exécuter la requête ci-dessous depuis le clickhouse-client de chaque hôte pour vérifier
    qu’aucune base de données n’a encore été créée, à l’exception de celles par défaut :

    ```sql title="Query" theme={null}
    SHOW DATABASES;
    ```

    ```response title="Response" theme={null}
       ┌─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 en utilisant la
    clause `ON CLUSTER` afin de créer une nouvelle base de données nommée `uk` :

    ```sql highlight={2} theme={null}
    CREATE DATABASE IF NOT EXISTS uk 
    ON CLUSTER cluster_2S_1R;
    ```

    Vous pouvez de nouveau exécuter la même requête qu’auparavant depuis le client de chaque hôte
    afin de vérifier que la base de données a bien été créée sur l’ensemble du cluster, même si
    la requête n’a été exécutée que sur `clickhouse-01` :

    ```sql theme={null}
    SHOW DATABASES;
    ```

    ```response highlight={6} theme={null}
       ┌─name───────────────┐
    1. │ INFORMATION_SCHEMA │
    2. │ default            │
    3. │ information_schema │
    4. │ system             │
    5. │ uk                 │
       └────────────────────┘
    ```
  </Step>

  <Step title="Créer une table sur le cluster" id="creating-a-table">
    Maintenant que la base de données a été créée, vous allez créer une table.
    Exécutez la requête suivante depuis n’importe quel client hôte :

    ```sql highlight={2} theme={null}
    CREATE TABLE IF NOT EXISTS uk.uk_price_paid_local
    ON CLUSTER cluster_2S_1R
    (
        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 = MergeTree
    ORDER BY (postcode1, postcode2, addr1, addr2);
    ```

    Notez qu’elle est identique à la requête utilisée dans l’instruction `CREATE` initiale du
    tutoriel sur le [jeu de données d’exemple des prix de l’immobilier au Royaume-Uni](/docs/fr/get-started/sample-datasets/uk-price-paid),
    à l’exception de la clause `ON CLUSTER`.

    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 sur l’ensemble des nœuds d’un cluster.

    Vous pouvez exécuter la requête ci-dessous à partir du client de chaque hôte afin de vérifier que la table a bien été créée sur l’ensemble du cluster :

    ```sql title="Query" theme={null}
    SHOW TABLES IN uk;
    ```

    ```response title="Response" theme={null}
       ┌─name────────────────┐
    1. │ uk_price_paid_local │
       └─────────────────────┘
    ```

    Avant d’insérer les données « UK Price Paid », faisons une petite expérience pour voir
    ce qui se passe lorsque nous insérons des données dans une table ordinaire depuis l’un ou l’autre hôte.

    Créez une base de données et une table de test à l’aide de la requête suivante depuis l’un ou l’autre hôte :

    ```sql theme={null}
    CREATE DATABASE IF NOT EXISTS test ON CLUSTER cluster_2S_1R;
    CREATE TABLE test.test_table ON CLUSTER cluster_2S_1R
    (
        `id` UInt64,
        `name` String
    )
    ENGINE = MergeTree()
    ORDER BY id;
    ```

    Maintenant, depuis `clickhouse-01`, exécutez la requête `INSERT` suivante :

    ```sql theme={null}
    INSERT INTO test.test_table (id, name) VALUES (1, 'Clicky McClickface');
    ```

    Passez sur `clickhouse-02` et exécutez la requête `INSERT` suivante :

    ```sql title="Query" theme={null}
    INSERT INTO test.test_table (id, name) VALUES (1, 'Alexey Milovidov');
    ```

    À présent, depuis `clickhouse-01` ou `clickhouse-02`, exécutez la requête suivante :

    ```sql theme={null}
    -- from clickhouse-01
    SELECT * FROM test.test_table;
    --   ┌─id─┬─name───────────────┐
    -- 1.│  1 │ Clicky McClickface │
    --   └────┴────────────────────┘

    --from clickhouse-02
    SELECT * FROM test.test_table;
    --   ┌─id─┬─name───────────────┐
    -- 1.│  1 │ Alexey Milovidov   │
    --   └────┴────────────────────┘
    ```

    Vous remarquerez que, contrairement à une table `ReplicatedMergeTree`, seule la ligne insérée dans la table sur cet
    hôte précis est renvoyée, et non les deux lignes.

    Pour lire les données sur les deux shards, nous avons besoin d’une interface capable de traiter des requêtes
    sur l’ensemble des shards, en combinant les données des deux shards lorsque nous exécutons des requêtes SELECT
    sur celle-ci ou en insérant des données dans les deux shards lorsque nous exécutons des requêtes INSERT.

    Dans ClickHouse, cette interface est appelée une **table distribuée**, que nous créons à l’aide du
    moteur de table [`Distributed`](/docs/fr/reference/engines/table-engines/special/distributed). Voyons comment cela fonctionne.
  </Step>

  <Step title="Créer une table distribuée" id="create-distributed-table">
    Créez une table distribuée à l’aide de la requête suivante :

    ```sql theme={null}
    CREATE TABLE test.test_table_dist ON CLUSTER cluster_2S_1R AS test.test_table
    ENGINE = Distributed('cluster_2S_1R', 'test', 'test_table', rand())
    ```

    Dans cet exemple, la fonction `rand()` est choisie comme clé de sharding afin que
    les insertions soient réparties aléatoirement entre les shards.

    Interrogez maintenant la table distribuée depuis l’un ou l’autre hôte, et vous obtiendrez
    les deux lignes qui ont été insérées sur les deux hôtes, contrairement à l’exemple précédent :

    ```sql theme={null}
    SELECT * FROM test.test_table_dist;
    ```

    ```response theme={null}
       ┌─id─┬─name───────────────┐
    1. │  1 │ Alexey Milovidov   │
    2. │  1 │ Clicky McClickface │
       └────┴────────────────────┘
    ```

    Faisons de même pour nos données sur les prix de l’immobilier au Royaume-Uni. Depuis n’importe quel client hôte,
    exécutez la query suivante pour créer une table distribuée à l’aide de la table existante
    que nous avons créée précédemment avec `ON CLUSTER` :

    ```sql theme={null}
    CREATE TABLE IF NOT EXISTS uk.uk_price_paid_distributed
    ON CLUSTER cluster_2S_1R
    ENGINE = Distributed('cluster_2S_1R', 'uk', 'uk_price_paid_local', rand());
    ```
  </Step>

  <Step title="Insérer des données dans une table distribuée" id="inserting-data-into-distributed-table">
    Connectez-vous maintenant à l'un des hôtes et insérez les données :

    ```sql theme={null}
    INSERT INTO uk.uk_price_paid_distributed
    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;
    ```

    Une fois les données insérées, vous pouvez vérifier le nombre de lignes à l'aide de la table
    distribuée :

    ```sql title="Query" theme={null}
    SELECT count(*)
    FROM uk.uk_price_paid_distributed
    ```

    ```response title="Response" theme={null}
       ┌──count()─┐
    1. │ 30212555 │ -- 30.21 million
       └──────────┘
    ```

    Si vous exécutez la requête suivante sur l'un ou l'autre des hôtes, vous constaterez que les données ont été
    réparties de manière plus ou moins équitable entre les shards (notez que le choix du
    shard cible a été déterminé par `rand()`, les résultats peuvent donc varier) :

    ```sql theme={null}
    -- from clickhouse-01
    SELECT count(*)
    FROM uk.uk_price_paid_local
    --    ┌──count()─┐
    -- 1. │ 15107353 │ -- 15.11 million
    --    └──────────┘

    --from clickhouse-02
    SELECT count(*)
    FROM uk.uk_price_paid_local
    --    ┌──count()─┐
    -- 1. │ 15105202 │ -- 15.11 million
    --    └──────────┘
    ```

    Que se passe-t-il si l'un des hôtes tombe en panne ? Simulons cela en arrêtant
    `clickhouse-01` :

    ```bash theme={null}
    docker stop clickhouse-01
    ```

    Vérifiez que l’hôte est hors ligne en exécutant :

    ```bash theme={null}
    docker-compose ps
    ```

    ```response title="Response" theme={null}
    NAME                   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/tcp
    ```

    Depuis `clickhouse-02`, exécutez maintenant la même requête select que précédemment sur la table distribuée :

    ```sql theme={null}
    SELECT count(*)
    FROM uk.uk_price_paid_distributed
    ```

    ```response title="Response" highlight={6} theme={null}
    Received exception from server (version 25.5.2):
    Code: 279. DB::Exception: Received from localhost:9000. DB::Exception: All connection tries failed. Log:

    Code: 32. DB::Exception: Attempt to read after eof. (ATTEMPT_TO_READ_AFTER_EOF) (version 25.5.2.47 (official build))
    Code: 209. DB::NetException: Timeout: connect timed out: 192.168.7.1:9000 (clickhouse-01:9000, 192.168.7.1, local address: 192.168.7.2:37484, connection timeout 1000 ms). (SOCKET_TIMEOUT) (version 25.5.2.47 (official build))
    Code: 198. DB::NetException: Not found address of host: clickhouse-01: (clickhouse-01:9000, 192.168.7.1, local address: 192.168.7.2:37484). (DNS_ERROR) (version 25.5.2.47 (official build))

    : While executing Remote. (ALL_CONNECTION_TRIES_FAILED)
    ```

    Malheureusement, notre cluster n'est pas tolérant aux pannes. Si l'un des hôtes tombe en panne, le
    cluster est considéré comme défaillant et la requête échoue — contrairement à la table répliquée
    que nous avons vue dans l'[exemple précédent](/docs/fr/guides/oss/deployment-and-scaling/examples/1-shard-2-replicas), pour laquelle
    nous pouvions insérer des données même lorsque l'un des hôtes était défaillant.
  </Step>
</Steps>

<div id="conclusion">
  ## Conclusion
</div>

L’avantage de cette topologie de cluster est que les données sont réparties sur
des hôtes distincts et n’utilisent que la moitié du stockage par nœud. Plus important encore, les requêtes
sont traitées sur les deux shards, ce qui optimise l’utilisation de la mémoire
et réduit les E/S par hôte.

Le principal inconvénient de cette topologie de cluster est, bien sûr, que la perte de l’un des
hôtes nous empêche d’exécuter des requêtes.

Dans l’[exemple suivant](/docs/fr/guides/oss/deployment-and-scaling/examples/2-shards-2-replicas), nous verrons comment
configurer un cluster avec deux shards et deux répliques, offrant à la fois évolutivité et
tolérance aux pannes.
