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

# Масштабирование

> Страница с описанием примера архитектуры, разработанной для обеспечения масштабируемости

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>;
};

> В этом примере вы узнаете, как настроить простой кластер ClickHouse с возможностью
> масштабирования. В конфигурации используются пять серверов. Два из них используются для сегментирования данных.
> Остальные три сервера используются для координации.

Архитектура кластера, который вы будете настраивать, показана ниже:

<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="Схема архитектуры для 2 сегментов и 1 реплики" width="1200" height="800" data-path="images/deployment-guides/replication-sharding-examples/sharding.webp" />

<Note>
  Хотя ClickHouse Server и ClickHouse Keeper можно запускать вместе на одном сервере,
  мы настоятельно рекомендуем использовать *выделенные* хосты для ClickHouse Keeper в производственных средах —
  именно этот подход мы и продемонстрируем в данном примере.

  Серверы Keeper могут быть менее мощными, и 4 ГБ оперативной памяти обычно достаточно для каждого сервера Keeper
  до тех пор, пока ваши серверы ClickHouse не станут достаточно крупными.
</Note>

<div id="pre-requisites">
  ## Предварительные требования
</div>

* Вы уже настраивали [локальный сервер ClickHouse](/docs/ru/get-started/setup/install)
* Вы знакомы с базовыми принципами настройки ClickHouse, такими как [файлы конфигурации](/docs/ru/concepts/features/configuration/server-config/configuration-files)
* На вашем компьютере установлен Docker

<Steps>
  <Step title="Настройка структуры каталогов и тестовой среды" id="set-up">
    <Tip>
      **Файлы с примерами**

      Следующие шаги помогут вам с нуля настроить кластер. Если вы хотите
      пропустить их и сразу перейти к запуску
      кластера, файлы с примерами можно взять из
      репозитория examples [каталог «docker-compose-recipes»](https://github.com/ClickHouse/examples/tree/main/docker-compose-recipes/recipes).
    </Tip>

    В этом руководстве вы будете использовать [Docker compose](https://docs.docker.com/compose/) для
    настройки кластера ClickHouse. Данную конфигурацию можно адаптировать для работы
    на отдельных локальных машинах, виртуальных машинах или облачных инстансах.

    Выполните следующие команды для создания структуры каталогов для данного примера:

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

    Добавьте следующий файл `docker-compose.yml` в каталог `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
    ```

    Создайте следующие подкаталоги и файлы:

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

    * Каталог `config.d` содержит файл конфигурации сервера ClickHouse `config.xml`,
      в котором задаётся пользовательская конфигурация для каждого узла ClickHouse. Эта
      конфигурация объединяется с файлом конфигурации ClickHouse `config.xml` по умолчанию,
      который входит в состав каждой установки ClickHouse.
    * Каталог `users.d` содержит файл пользовательской конфигурации `users.xml`, в котором
      задаётся пользовательская конфигурация для пользователей. Эта конфигурация объединяется с
      файлом конфигурации ClickHouse `users.xml` по умолчанию, который входит в состав каждой
      установки ClickHouse.

    <Tip>
      **Пользовательские каталоги конфигурации**

      Рекомендуется использовать каталоги `config.d` и `users.d` при
      создании собственной конфигурации, а не изменять напрямую конфигурацию по умолчанию
      в `/etc/clickhouse-server/config.xml` и `etc/clickhouse-server/users.xml`.

      Строка

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

      обеспечивает, что разделы конфигурации, определённые в каталогах `config.d` и `users.d`,
      переопределяют разделы конфигурации по умолчанию, заданные в стандартных файлах
      `config.xml` и `users.xml`.
    </Tip>
  </Step>

  <Step title="Настройка узлов ClickHouse" id="configure-clickhouse-servers">
    ### Настройка сервера

    Теперь измените каждый пустой файл конфигурации `config.xml`, расположенный по пути
    `fs/volumes/clickhouse-{}/etc/clickhouse-server/config.d`. Выделенные ниже строки
    необходимо изменить, чтобы они были специфичны для каждого узла:

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

    | Каталог                                                   | 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) |

    Каждый раздел приведённого выше конфигурационного файла подробно описан ниже.

    #### Сеть и логирование

    Возможность внешних подключений через сетевой интерфейс включается при активации настройки listen
    host. Это гарантирует, что хост сервера ClickHouse доступен с других
    хостов:

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

    Порт HTTP API установлен на `8123`:

    ```xml theme={null}
    <http_port>8123</http_port>
    ```

    TCP-порт для взаимодействия по собственному протоколу ClickHouse между clickhouse-client
    и другими инструментами ClickHouse, а также между clickhouse-server и другими clickhouse-servers,
    установлен в `9000`:

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

    Логирование настраивается в блоке `<logger>`. Приведённая ниже конфигурация
    задаёт отладочный лог с ротацией по достижении 1000 МБ, не более трёх файлов:

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

    Дополнительную информацию о конфигурации логирования см. в комментариях в стандартном [файле конфигурации](https://github.com/ClickHouse/ClickHouse/blob/master/programs/server/config.xml) ClickHouse.

    #### Конфигурация кластера

    Конфигурация кластера задаётся в блоке `<remote_servers>`.
    Здесь определяется имя кластера `cluster_2S_1R`.

    Блок `<cluster_2S_1R></cluster_2S_1R>` определяет структуру кластера
    с помощью настроек `<shard></shard>` и `<replica></replica>` и служит
    шаблоном для распределённых DDL-запросов — то есть запросов, выполняемых по всему
    кластеру с использованием предложения `ON CLUSTER`. По умолчанию распределённые DDL-запросы
    разрешены, однако их можно отключить с помощью настройки `allow_distributed_ddl_queries`.

    `internal_replication` по умолчанию имеет значение false, так как на каждый сегмент приходится только одна реплика.

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

    Для каждого сервера указываются следующие параметры:

    | Параметр | Описание                                                                                                                                                                                                                                                                                                                         | Значение по умолчанию |
    | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
    | `host`   | Адрес удалённого сервера. Можно использовать либо доменное имя, либо IPv4- или IPv6-адрес. Если указать доменное имя, при запуске сервер выполняет DNS-запрос, и результат сохраняется на всё время его работы. Если DNS-запрос завершается ошибкой, сервер не запустится. Если изменить DNS-запись, сервер нужно перезапустить. | -                     |
    | `port`   | TCP-порт для обмена сообщениями (`tcp_port` в конфигурации, обычно 9000). Не путать с `http_port`.                                                                                                                                                                                                                               | -                     |

    #### Конфигурация Keeper

    Раздел `<ZooKeeper>` указывает ClickHouse, где запущен ClickHouse Keeper (или ZooKeeper).
    Поскольку мы используем кластер Keeper, необходимо указать каждый `<node>` кластера
    вместе с его hostname и номером порта с помощью тегов `<host>` и `<port>` соответственно.

    Настройка ClickHouse Keeper рассматривается на следующем шаге руководства.

    ```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>
      Хотя ClickHouse Keeper можно запускать на том же сервере, что и ClickHouse Server,
      в продакшн-средах мы настоятельно рекомендуем запускать ClickHouse Keeper на выделенных хостах.
    </Note>

    #### Конфигурация макросов

    Кроме того, раздел `<macros>` используется для определения подстановок параметров для
    реплицированных таблиц. Они перечислены в `system.macros` и позволяют использовать подстановки
    вида `{shard}` и `{replica}` в запросах.

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

    <Note>
      Они будут определяться по-разному в зависимости от структуры кластера.
    </Note>

    ### Конфигурация пользователя

    Теперь внесите следующие изменения в каждый пустой конфигурационный файл `users.xml`, расположенный по пути
    `fs/volumes/clickhouse-{}/etc/clickhouse-server/users.d`:

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

    | Каталог                                                  | 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) |

    В данном примере default user настроен без пароля для удобства.
    На практике такой подход не рекомендуется.

    <Note>
      В этом примере файл `users.xml` одинаков на всех узлах кластера.
    </Note>
  </Step>

  <Step title="Настройка ClickHouse Keeper" id="configure-clickhouse-keeper-nodes">
    ### Настройка Keeper

    Чтобы репликация работала, необходимо развернуть и
    настроить кластер ClickHouse Keeper. ClickHouse Keeper обеспечивает систему координации для репликации данных,
    выступая в качестве замены ZooKeeper, который также можно использовать.
    Однако рекомендуется использовать ClickHouse Keeper, так как он обеспечивает более строгие гарантии и
    надежность, а также потребляет меньше ресурсов, чем ZooKeeper. Для Высокой доступности и
    сохранения кворума рекомендуется запускать как минимум три узла ClickHouse Keeper.

    <Note>
      ClickHouse Keeper может работать на любом узле кластера вместе с ClickHouse, однако
      рекомендуется запускать его на выделенном узле, что позволяет масштабировать
      кластер ClickHouse Keeper и управлять им независимо от кластера базы данных.
    </Note>

    Создайте файлы `keeper_config.xml` для каждого узла ClickHouse Keeper,
    выполнив следующую команду из корневой папки примера:

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

    Измените пустые файлы конфигурации, созданные в каждом
    каталоге узла `fs/volumes/clickhouse-keeper-{}/etc/clickhouse-keeper`. Выделенные
    ниже строки нужно изменить для каждого узла:

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

    | Каталог                                                 | Файл                                                                                                                                                                                         |
    | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `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) |

    Каждый файл конфигурации должен содержать следующую уникальную конфигурацию (показана ниже).
    Используемый `server_id` должен быть уникальным для соответствующего узла ClickHouse Keeper
    в кластере и совпадать с `<id>` сервера, заданным в разделе `<raft_configuration>`.
    `tcp_port` — порт, используемый *клиентами* ClickHouse Keeper.

    ```xml theme={null}
    <tcp_port>9181</tcp_port>
    <server_id>{id}</server_id>
    ```

    Следующий раздел используется для настройки серверов, которые участвуют в
    кворуме [алгоритма консенсуса 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-порт для связи между узлами ClickHouse Keeper -->
            <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 упрощает администрирование**

      [ClickHouse Cloud](/docs/ru/products/cloud/getting-started/intro)
      снимает операционную нагрузку, связанную с управлением сегментами и репликами. Платформа
      автоматически обеспечивает высокую доступность, репликацию и масштабирование.
      Вычислительные ресурсы и хранилище разделены и масштабируются по мере необходимости без ручной
      настройки и постоянного обслуживания.

      [Подробнее](/docs/ru/products/cloud/features/autoscaling/overview)
    </Tip>
  </Step>

  <Step title="Проверьте настройку" id="test-the-setup">
    Убедитесь, что на вашем компьютере запущен Docker.
    Запустите кластер командой `docker-compose up` из корневого каталога `cluster_2S_1R`:

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

    Вы должны увидеть, как docker начинает скачивать образы ClickHouse и Keeper,
    а затем запускает контейнеры:

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

    Чтобы убедиться, что кластер работает, подключитесь к `clickhouse-01` или `clickhouse-02` и выполните
    следующий запрос. Ниже показана команда для подключения к первому узлу:

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

    Если всё прошло успешно, вы увидите приглашение клиента ClickHouse:

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

    Выполните следующий запрос, чтобы проверить, какие топологии кластера определены для каких
    хостов:

    ```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 │
       └───────────────┴───────────┴─────────────┴───────────────┴──────┘
    ```

    Выполните следующий запрос, чтобы проверить состояние кластера 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     │       │ /           │
       └────────────┴───────┴─────────────┘
    ```

    Команда `mntr` также часто используется, чтобы убедиться, что ClickHouse Keeper
    запущен, и получить информацию о состоянии и ролях трёх узлов Keeper.
    В конфигурации, используемой в этом примере, вместе работают три узла.
    Они выберут leader, а остальные узлы будут followers.

    Команда `mntr` предоставляет информацию о производительности, а также о том,
    является ли конкретный узел follower или leader.

    <Tip>
      Возможно, вам потребуется установить `netcat`, чтобы отправить команду `mntr` в Keeper.
      Информацию о загрузке см. на странице [nmap.org](https://nmap.org/ncat/).
    </Tip>

    Выполните приведённую ниже команду в оболочке на `clickhouse-keeper-01`, `clickhouse-keeper-02` и
    `clickhouse-keeper-03`, чтобы проверить состояние каждого узла Keeper. Команда
    для `clickhouse-keeper-01` показана ниже:

    ```bash theme={null}
    docker exec -it clickhouse-keeper-01  /bin/sh -c 'echo mntr | nc 127.0.0.1 9181'
    ```

    Ниже приведён пример ответа от узла-реплики:

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

    Ниже приведён пример ответа от узла-лидера:

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

    На этом этапе вы успешно настроили кластер ClickHouse с двумя сегментами, в каждом из которых по одной реплике.
    На следующем шаге вы создадите таблицу в кластере.
  </Step>

  <Step title="Создайте базу данных" id="creating-a-database">
    Теперь, когда вы убедились, что кластер правильно настроен и работает, вы
    воссоздадите ту же таблицу, которая используется в руководстве по работе с [UK property prices](/docs/ru/get-started/sample-datasets/uk-price-paid)
    — демонстрационным набором данных. Она содержит около 30 миллионов строк с ценами сделок
    с недвижимостью в Англии и Уэльсе с 1995 года.

    Подключитесь к клиенту каждого хоста, выполнив каждую из следующих команд в отдельных вкладках
    или окнах терминала:

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

    Вы можете выполнить приведённый ниже запрос в clickhouse-client на каждом хосте, чтобы убедиться, что
    пока не создано никаких баз данных, кроме стандартных:

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

    ```response title="Response" theme={null}
       ┌─name───────────────┐
    1. │ INFORMATION_SCHEMA │
    2. │ default            │
    3. │ information_schema │
    4. │ system             │
       └────────────────────┘
    ```

    На клиенте `clickhouse-01` выполните следующий **распределённый** DDL-запрос, используя
    предложение `ON CLUSTER`, чтобы создать новую базу данных `uk`:

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

    Вы можете снова выполнить тот же запрос, что и раньше, из клиента на каждом хосте,
    чтобы убедиться, что база данных создана во всём кластере, хотя запрос был выполнен
    только на `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="Создайте таблицу в кластере" id="creating-a-table">
    Теперь, когда база данных создана, создайте таблицу.
    Выполните следующий запрос с любого из хост-клиентов:

    ```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);
    ```

    Обратите внимание, что он идентичен запросу, использованному в исходном операторе `CREATE` в руководстве по демонстрационному набору данных
    [UK property prices](/docs/ru/get-started/sample-datasets/uk-price-paid), за исключением предложения `ON CLUSTER`.

    Предложение `ON CLUSTER` предназначено для распределённого выполнения DDL-запросов (Data Definition Language),
    таких как `CREATE`, `DROP`, `ALTER` и `RENAME`, и гарантирует, что эти
    изменения схемы будут применены на всех узлах кластера.

    Вы можете выполнить приведённый ниже запрос из клиента на каждом хосте, чтобы убедиться, что таблица была создана во всём кластере:

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

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

    Прежде чем выполнять вставку данных UK price paid, давайте проведем небольшой эксперимент и посмотрим,
    что произойдет, если вставить данные в обычную таблицу с любого из хостов.

    Создайте тестовую базу данных и таблицу, выполнив следующий запрос с любого из хостов:

    ```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;
    ```

    Теперь на `clickhouse-01` выполните следующий запрос `INSERT`:

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

    Переключитесь на `clickhouse-02` и выполните следующий запрос `INSERT`:

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

    Теперь на `clickhouse-01` или `clickhouse-02` выполните следующий запрос:

    ```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   │
    --   └────┴────────────────────┘
    ```

    Вы заметите, что, в отличие от таблицы `ReplicatedMergeTree`, возвращается только строка, вставленная в таблицу на
    этом конкретном хосте, а не обе строки.

    Чтобы читать данные из двух сегментов, нам нужен интерфейс, способный обрабатывать запросы
    ко всем сегментам, объединяя данные из обоих сегментов, когда мы выполняем SELECT-запросы
    к этой таблице, или выполняя вставку данных в оба сегмента, когда мы выполняем запросы INSERT.

    В ClickHouse такой интерфейс называется **distributed таблица** и создаётся с помощью
    движка таблицы [`Distributed`](/docs/ru/reference/engines/table-engines/special/distributed). Давайте посмотрим, как это работает.
  </Step>

  <Step title="Создание distributed таблицы" id="create-distributed-table">
    Создайте distributed таблицу, выполнив следующий запрос:

    ```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())
    ```

    В этом примере в качестве ключа сегментирования выбрана функция `rand()`, поэтому
    вставка случайным образом распределяется по сегментам.

    Теперь выполните запрос к distributed таблице с любого из хостов, и вы получите
    обе строки, вставленные на двух хостах, в отличие от предыдущего примера:

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

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

    Давайте сделаем то же самое для наших данных о ценах на недвижимость в Великобритании. С любого из клиентских хостов
    выполните следующий запрос, чтобы создать distributed таблицу, используя существующую таблицу,
    которую мы ранее создали с помощью `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="Вставка данных в distributed таблицу" id="inserting-data-into-distributed-table">
    Теперь подключитесь к любому из хостов и вставьте данные:

    ```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;
    ```

    После вставки данных можно проверить количество строк с помощью распределённой
    таблицы:

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

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

    Если вы выполните следующий запрос на любом из хостов, то увидите, что данные более или менее равномерно распределены по сегментам (имейте в виду, что выбор сегмента для вставки определялся с помощью `rand()`, поэтому результаты могут отличаться):

    ```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
    --    └──────────┘
    ```

    Что произойдёт, если один из хостов выйдет из строя? Смоделируем это, остановив
    `clickhouse-01`:

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

    Убедитесь, что хост недоступен, выполнив команду:

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

    Теперь с `clickhouse-02` выполните тот же запрос SELECT, что и раньше, к распределённой
    таблице:

    ```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)
    ```

    К сожалению, наш кластер не является отказоустойчивым. Если один из хостов выходит из строя, кластер считается неработоспособным и запрос завершается с ошибкой — в отличие от реплицированной таблицы из [предыдущего примера](/docs/ru/guides/oss/deployment-and-scaling/examples/1-shard-2-replicas), в которую мы могли вставлять данные даже при отказе одного из хостов.
  </Step>
</Steps>

<div id="conclusion">
  ## Заключение
</div>

Преимущество этой топологии кластера в том, что данные распределяются по
отдельным хостам и требуют вдвое меньше дискового пространства на каждом узле. Что еще важнее,
запросы обрабатываются на обоих сегментах, что эффективнее с точки зрения
использования памяти и снижает I/O на каждом хосте.

Основной недостаток этой топологии кластера, разумеется, в том, что потеря одного из
хостов лишает нас возможности выполнять запросы.

В [следующем примере](/docs/ru/guides/oss/deployment-and-scaling/examples/2-shards-2-replicas) мы рассмотрим, как
настроить кластер с двумя сегментами и двумя репликами, обеспечивающий как масштабируемость, так и
отказоустойчивость.
