Перейти к основному содержимому
Перейти к основному содержимому

Репликация данных

примечание

В ClickHouse Cloud репликация управляется для вас. Пожалуйста, создавайте свои таблицы, не добавляя аргументы. Например, в приведенном ниже тексте вы замените:

на:

Репликация поддерживается только для таблиц семейства MergeTree:

  • ReplicatedMergeTree
  • ReplicatedSummingMergeTree
  • ReplicatedReplacingMergeTree
  • ReplicatedAggregatingMergeTree
  • ReplicatedCollapsingMergeTree
  • ReplicatedVersionedCollapsingMergeTree
  • ReplicatedGraphiteMergeTree

Репликация осуществляется на уровне отдельной таблицы, а не всего сервера. Сервер может одновременно хранить как реплицируемые, так и нереплицируемые таблицы.

Репликация не зависит от шардирования. Каждый шард имеет свою независимую репликацию.

Сжатые данные для INSERT и ALTER запросов реплицируются (для получения дополнительной информации см. документацию по ALTER).

Запросы CREATE, DROP, ATTACH, DETACH и RENAME выполняются на одном сервере и не реплицируются:

  • Запрос CREATE TABLE создает новую реплицируемую таблицу на сервере, где выполняется запрос. Если эта таблица уже существует на других серверах, добавляется новая реплика.
  • Запрос DROP TABLE удаляет реплику, расположенную на сервере, где выполняется запрос.
  • Запрос RENAME переименовывает таблицу на одной из реплик. Другими словами, реплицируемые таблицы могут иметь разные имена на разных репликах.

ClickHouse использует ClickHouse Keeper для хранения метаинформации о репликах. Возможна также работа с ZooKeeper версии 3.4.5 или новее, но рекомендуется использовать ClickHouse Keeper.

Для использования репликации установите параметры в разделе конфигурации сервера zookeeper.

примечание

Не пренебрегайте настройками безопасности. ClickHouse поддерживает схему безопасности digest ACL подсистемы безопасности ZooKeeper.

Пример настройки адресов кластера ClickHouse Keeper:

ClickHouse также поддерживает хранение метаинформации о репликах в вспомогательном кластере ZooKeeper. Для этого укажите имя кластера ZooKeeper и путь в качестве аргументов движка. Другими словами, он поддерживает хранение метаданных различных таблиц в различных кластерах ZooKeeper.

Пример настройки адресов вспомогательного кластера ZooKeeper:

Чтобы хранить метаданные таблицы во вспомогательном кластере ZooKeeper, а не в кластере ZooKeeper по умолчанию, мы можем использовать SQL для создания таблицы с движком ReplicatedMergeTree следующим образом:

Вы можете указать любой существующий кластер ZooKeeper, и система будет использовать каталог на нем для своих собственных данных (каталог указывается при создании реплицируемой таблицы).

Если ZooKeeper не задан в конфигурационном файле, вы не сможете создать реплицируемые таблицы, и все существующие реплицируемые таблицы будут доступны только для чтения.

ZooKeeper не используется в запросах SELECT, поскольку репликация не влияет на производительность SELECT, и запросы выполняются так же быстро, как и для нереплицируемых таблиц. При запросе распределенных реплицируемых таблиц поведение ClickHouse контролируется настройками max_replica_delay_for_distributed_queries и fallback_to_stale_replicas_for_distributed_queries.

Для каждого INSERT запроса примерно десять записей добавляется в ZooKeeper через несколько транзакций. (Чтобы быть более точным, это касается каждого вставленного блока данных; запрос INSERT содержит один блок или один блок на max_insert_block_size = 1048576 строк.) Это приводит к немного более длительным задержкам для INSERT по сравнению с нереплицируемыми таблицами. Но если следовать рекомендациям по вставке данных пакетами не более одного INSERT в секунду, это не создает никаких проблем. Весь кластер ClickHouse, используемый для координации одного кластера ZooKeeper, имеет в общей сложности несколько сотен INSERTs в секунду. Пропускная способность на вставку данных (количество строк в секунду) такая же высокая, как и для нереплицируемых данных.

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

Репликация асинхронная и многомастеровая. Запросы INSERT (а также ALTER) могут быть отправлены на любой доступный сервер. Данные вставляются на сервере, где выполняется запрос, а затем копируются на другие серверы. Поскольку это асинхронно, недавно вставленные данные появляются на других репликах с некоторой задержкой. Если часть реплик недоступна, данные записываются, когда они становятся доступными. Если реплика доступна, задержка составляет время, необходимое для передачи блока сжатых данных по сети. Количество потоков, выполняющих фоновые задачи для реплицируемых таблиц, можно установить с помощью настройки background_schedule_pool_size.

Движок ReplicatedMergeTree использует отдельный пул потоков для реплицированных выборок. Размер пула ограничен настройкой background_fetches_pool_size, которую можно настроить с перезагрузкой сервера.

По умолчанию запрос INSERT ожидает подтверждения записи данных только от одной реплики. Если данные успешно записаны только на одну реплику и сервер с этой репликой перестает существовать, сохраненные данные будут утеряны. Чтобы включить получение подтверждений записи данных от нескольких реплик, используйте опцию insert_quorum.

Каждый блок данных записывается атомарно. Запрос INSERT делится на блоки размером до max_insert_block_size = 1048576 строк. Другими словами, если запрос INSERT содержит менее 1048576 строк, он выполняется атомарно.

Блоки данных дедуплицируются. При нескольких записях одного и того же блока данных (блоки данных одинакового размера, содержащие одни и те же строки в одном и том же порядке) блок записывается только один раз. Причина этого заключается в возможных сетевых сбоях, когда клиентское приложение не знает, были ли данные записаны в базу данных, поэтому запрос INSERT может просто быть повторен. Не имеет значения, на какие реплики были отправлены INSERTs с одинаковыми данными. INSERTs идемпотентны. Параметры дедупликации контролируются настройками сервера merge_tree.

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

Вы можете иметь любое количество реплик одних и тех же данных. Исходя из нашего опыта, относительно надежным и удобным решением могла бы быть двойная репликация в производственной среде, при этом каждый сервер использует RAID-5 или RAID-6 (и RAID-10 в некоторых случаях).

Система контролирует синхронность данных на репликах и может восстанавливаться после сбоя. Переключение на резервный сервер происходит автоматически (для небольших различий в данных) или полуработоспособно (когда данные слишком различаются, что может указывать на ошибку конфигурации).

Создание реплицируемых таблиц

примечание

В ClickHouse Cloud репликация управляется для вас. Пожалуйста, создавайте свои таблицы, не добавляя аргументы. Например, в приведенном ниже тексте вы замените:

на:

Префикс Replicated добавляется к имени движка таблицы. Например: ReplicatedMergeTree.

подсказка

Добавление Replicated является необязательным в ClickHouse Cloud, так как все таблицы реплицируемы.

Параметры Replicated*MergeTree

zoo_path

zoo_path — Путь к таблице в ClickHouse Keeper.

replica_name

replica_name — Имя реплики в ClickHouse Keeper.

other_parameters

other_parameters — Параметры двигателя, который используется для создания реплицированной версии, например, версия в ReplacingMergeTree.

Пример:

Пример в устаревшем синтаксисе

Как показывает пример, эти параметры могут содержать подстановки в фигурных скобках. Подставляемые значения берутся из раздела macros конфигурационного файла.

Пример:

Путь к таблице в ClickHouse Keeper должен быть уникальным для каждой реплицируемой таблицы. Таблицы на разных шардах должны иметь разные пути. В этом случае путь состоит из следующих частей:

/clickhouse/tables/ — это общий префикс. Мы рекомендуем использовать именно этот.

{shard} будет развернут в идентификатор шарда.

table_name — это имя узла для таблицы в ClickHouse Keeper. Хорошей идеей будет сделать его таким же, как имя таблицы. Оно определено явно, потому что в отличие от имени таблицы, оно не меняется после выполнения запроса RENAME. ПОДСКАЗКА: вы также можете добавить имя базы данных перед table_name. Например, db_name.table_name.

Две встроенные подстановки {database} и {table} могут быть использованы, они развернутся в имя таблицы и имя базы данных соответственно (если только эти макросы не определены в разделе macros). Таким образом, путь zookeeper может быть указан как '/clickhouse/tables/{shard}/{database}/{table}'. Будьте осторожны с переименованием таблиц при использовании этих встроенных подстановок. Путь в ClickHouse Keeper не может быть изменен, и при переименовании таблицы макросы развернутся в другой путь, таблица будет ссылаться на путь, который не существует в ClickHouse Keeper, и перейдет в режим только для чтения.

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

Вы можете явно определить параметры, а не использовать подстановки. Это может быть удобно для тестирования и настройки небольших кластеров. Однако в этом случае вы не сможете использовать распределенные DDL запросы (ON CLUSTER).

При работе с большими кластерами мы рекомендуем использовать подстановки, так как они уменьшают вероятность ошибок.

Вы можете указать значения по умолчанию для параметров Replicated движка таблицы в файле конфигурации сервера. Например:

В этом случае вы можете опустить аргументы при создании таблиц:

Это эквивалентно:

Запустите запрос CREATE TABLE на каждой реплике. Этот запрос создает новую реплицируемую таблицу или добавляет новую реплику к существующей.

Если вы добавите новую реплику после того, как в таблице уже есть некоторые данные на других репликах, данные будут скопированы с других реплик на новую после выполнения запроса. Другими словами, новая реплика синхронизируется с другими.

Чтобы удалить реплику, выполните DROP TABLE. Однако будет удалена только одна реплика — та, которая находится на сервере, где вы выполняете запрос.

Восстановление после сбоев

Если ClickHouse Keeper недоступен при запуске сервера, реплицируемые таблицы переходят в режим только для чтения. Система периодически пытается подключиться к ClickHouse Keeper.

Если ClickHouse Keeper недоступен во время INSERT, или возникает ошибка при взаимодействии с ClickHouse Keeper, выбрасывается исключение.

После подключения к ClickHouse Keeper система проверяет, соответствует ли набор данных в локальной файловой системе ожидаемому набору данных (ClickHouse Keeper хранит эту информацию). Если есть небольшие несоответствия, система разрешает их, синхронизируя данные с репликами.

Если система обнаруживает поврежденные части данных (с неправильным размером файлов) или нераспознанные части (части, записанные в файловую систему, но не зафиксированные в ClickHouse Keeper), она перемещает их в подкаталог detached (они не удаляются). Все отсутствующие части копируются с реплик.

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

Когда сервер запускается (или устанавливает новое соединение с ClickHouse Keeper), он только проверяет количество и размеры всех файлов. Если размеры файлов совпадают, но байты были изменены где-то посередине, это не обнаруживается немедленно, а только при попытке прочитать данные для запроса SELECT. Запрос выбрасывает исключение о несовпадающей контрольной сумме или размере сжатого блока. В этом случае части данных добавляются в очередь проверки и при необходимости копируются с реплик.

Если локальный набор данных слишком сильно отличается от ожидаемого, срабатывает защитный механизм. Сервер записывает это в журнал и отказывается запускаться. Причина этого заключается в том, что этот случай может указывать на ошибку конфигурации, например, если реплика на шарде была случайно настроена как реплика на другом шарде. Однако пороги для этого механизма установлены довольно низко, и эта ситуация может возникнуть во время нормального восстановления после сбоя. В этом случае данные восстанавливаются полуработоспособно - путем «нажатия кнопки».

Чтобы начать восстановление, создайте узел /path_to_table/replica_name/flags/force_restore_data в ClickHouse Keeper с любым содержимым или выполните команду для восстановления всех реплицируемых таблиц:

Затем перезапустите сервер. При запуске сервер удаляет эти флаги и начинает восстановление.

Восстановление после полной утраты данных

Если все данные и метаданные исчезли с одного из серверов, выполните следующие шаги для восстановления:

  1. Установите ClickHouse на сервер. Правильно определите подстановки в файле конфигурации, который содержит идентификатор шарда и реплик, если вы их используете.
  2. Если у вас были нереплицируемые таблицы, которые необходимо вручную продублировать на серверах, скопируйте их данные с реплики (в каталоге /var/lib/clickhouse/data/db_name/table_name/).
  3. Скопируйте определения таблиц, расположенные в /var/lib/clickhouse/metadata/, с реплики. Если идентификатор шарда или реплики явно указан в определениях таблиц, исправьте его, чтобы он соответствовал этой реплике. (В качестве альтернативы, запустите сервер и выполните все запросы ATTACH TABLE, которые должны были находиться в .sql файлах в /var/lib/clickhouse/metadata/.)
  4. Чтобы начать восстановление, создайте узел ClickHouse Keeper /path_to_table/replica_name/flags/force_restore_data с любым содержимым или выполните команду для восстановления всех реплицируемых таблиц: sudo -u clickhouse touch /var/lib/clickhouse/flags/force_restore_data

Затем запустите сервер (перезагрузите, если он уже работает). Данные будут загружены с реплик.

Альтернативный вариант восстановления - удалить информацию о потерянной реплике из ClickHouse Keeper (/path_to_table/replica_name), а затем создать реплику снова, как описано в "Создание реплицируемых таблиц".

Нет ограничений на пропускную способность сети во время восстановления. Имейте это в виду, если вы восстанавливаете множество реплик одновременно.

Конвертация из MergeTree в ReplicatedMergeTree

Мы используем термин MergeTree, чтобы обозначить все движки таблиц в семействе MergeTree, так же как и для ReplicatedMergeTree.

Если у вас была таблица MergeTree, которая была вручную реплицирована, вы можете конвертировать ее в реплицированную таблицу. Вам может понадобиться это сделать, если у вас уже собрана большая часть данных в таблице MergeTree, и теперь вы хотите включить репликацию.

Запрос ATTACH TABLE ... AS REPLICATED позволяет прикрепить отсоединенную таблицу MergeTree как ReplicatedMergeTree.

Таблица MergeTree может быть автоматически конвертирована при перезагрузке сервера, если установлен флаг convert_to_replicated в каталоге данных таблицы (/store/xxx/xxxyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy/ для атомарной базы данных). Создайте пустой файл convert_to_replicated, и таблица будет загружена как реплицированная на следующей перезагрузке сервера.

Этот запрос можно использовать для получения пути данных таблицы. Если у таблицы много путей данных, вам нужно использовать первый из них.

Обратите внимание, что таблица ReplicatedMergeTree будет создана со значениями параметров default_replica_path и default_replica_name. Чтобы создать конвертированную таблицу на других репликах, вам нужно будет явно указать ее путь в первом аргументе движка ReplicatedMergeTree. Следующий запрос можно использовать для получения ее пути.

Существует также ручной способ сделать это.

Если данные различаются на различных репликах, сначала синхронизируйте их или удалите эти данные на всех репликах, кроме одной.

Переименуйте существующую таблицу MergeTree, затем создайте таблицу ReplicatedMergeTree с прежним именем. Переместите данные из старой таблицы в подкаталог detached внутри каталога с новыми данными таблицы (/var/lib/clickhouse/data/db_name/table_name/). Затем выполните ALTER TABLE ATTACH PARTITION на одной из реплик, чтобы добавить эти части данных в рабочий набор.

Конвертация из ReplicatedMergeTree в MergeTree

Используйте запрос ATTACH TABLE ... AS NOT REPLICATED для прикрепления отсоединенной таблицы ReplicatedMergeTree как MergeTree на одном сервере.

Другой способ сделать это включает перезагрузку сервера. Создайте таблицу MergeTree с другим именем. Переместите все данные из каталога с таблицей ReplicatedMergeTree в каталог данных новой таблицы. Затем удалите таблицу ReplicatedMergeTree и перезагрузите сервер.

Если вы хотите избавиться от таблицы ReplicatedMergeTree, не запускаючи сервер:

  • Удалите соответствующий .sql файл в каталоге метаданных (/var/lib/clickhouse/metadata/).
  • Удалите соответствующий путь в ClickHouse Keeper (/path_to_table/replica_name).

После этого вы можете запустить сервер, создать таблицу MergeTree, переместить данные в ее каталог, а затем перезагрузить сервер.

Восстановление при потере или повреждении метаданных в кластере ClickHouse Keeper

Если данные в ClickHouse Keeper были потеряны или повреждены, вы можете спасти данные, переместив их в нереплицируемую таблицу, как описано выше.

Смотрите также