Репликация данных
В 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 репликация обрабатывается автоматически.
Создавайте таблицы, используя MergeTree
, без аргументов репликации. Система внутренне заменяет MergeTree
на SharedMergeTree
для репликации и распределения данных.
Избегайте использования ReplicatedMergeTree
или указания параметров репликации, поскольку управление репликацией осуществляется платформой.
Параметры Replicated*MergeTree
Параметр | Описание |
---|---|
zoo_path | Путь к таблице в ClickHouse Keeper. |
replica_name | Имя реплики в ClickHouse Keeper. |
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 с любым содержимым, или выполните команду для восстановления всех реплицированных таблиц:
Затем перезапустите сервер. При запуске сервер удаляет эти флаги и начинает восстановление.
Восстановление после полной потери данных
Если все данные и метаданные исчезли с одного из серверов, выполните следующие шаги для восстановления:
- Установите ClickHouse на сервере. Правильно определите заменители в конфигурационном файле, содержащем идентификатор шара и реплики, если вы их используете.
- Если у вас были непреплицированные таблицы, которые необходимо вручную дублировать на серверах, скопируйте их данные с реплики (в каталоге
/var/lib/clickhouse/data/db_name/table_name/
). - Скопируйте определения таблиц, находящиеся в
/var/lib/clickhouse/metadata/
, с реплики. Если идентификатор шара или реплики явно указан в определениях таблицы, исправьте его так, чтобы он соответствовал этой реплике. (В качестве альтернативы, запустите сервер и выполните все запросыATTACH TABLE
, которые должны были быть в .sql файлах в/var/lib/clickhouse/metadata/
.) - Чтобы начать восстановление, создайте узел 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 были потеряны или повреждены, вы можете сохранить данные, переместив их в непреплицированную таблицу, как описано выше.
Смотрите также