Движки таблиц Replicated*
В 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 для координации, в сумме выполняет несколько сотен INSERT в секунду. Пропускная способность по вставке данных (количество строк в секунду) столь же высока, как и для нереплицируемых данных.
Для очень больших кластеров вы можете использовать разные кластеры ZooKeeper для разных шардов. Однако, исходя из нашего опыта, в этом не было необходимости даже для промышленных кластеров примерно из 300 серверов.
Репликация асинхронная и многомастерная (multi-master). Запросы INSERT (а также ALTER) могут быть отправлены на любой доступный сервер. Данные вставляются на тот сервер, на котором выполняется запрос, а затем копируются на остальные серверы. Поскольку это асинхронно, недавно вставленные данные появляются на других репликах с некоторой задержкой. Если часть реплик недоступна, данные будут записаны, когда они станут доступны. Если реплика доступна, задержка равна времени, необходимому для передачи блока сжатых данных по сети. Количество потоков, выполняющих фоновые задачи для реплицируемых таблиц, можно задать настройкой background_schedule_pool_size.
Движок ReplicatedMergeTree использует отдельный пул потоков для реплицируемых выборок данных (fetch). Размер пула ограничивается настройкой background_fetches_pool_size, которую можно изменить с перезапуском сервера.
По умолчанию запрос INSERT ждёт подтверждения записи данных только от одной реплики. Если данные были успешно записаны только на одну реплику и сервер с этой репликой перестаёт существовать, сохранённые данные будут потеряны. Чтобы получать подтверждение записи данных от нескольких реплик, используйте опцию insert_quorum.
Каждый блок данных записывается атомарно. Запрос INSERT разбивается на блоки до max_insert_block_size = 1048576 строк. Другими словами, если запрос INSERT содержит меньше 1048576 строк, он выполняется атомарно.
Блоки данных дедуплицируются. При многократной записи одного и того же блока данных (блоков одинакового размера, содержащих одинаковые строки в одном и том же порядке) блок записывается только один раз. Причина в том, что при сетевых сбоях клиентское приложение может не знать, были ли данные записаны в БД, поэтому запрос INSERT можно просто повторить. Не имеет значения, на какие реплики отправлялись INSERT с идентичными данными. Запросы INSERT являются идемпотентными. Параметры дедупликации управляются серверными настройками merge_tree.
Во время репликации по сети передаются только исходные данные для вставки. Дальнейшая обработка данных (слияние) координируется и выполняется на всех репликах одинаковым образом. Это минимизирует использование сети, что означает, что репликация хорошо работает, когда реплики расположены в разных дата-центрах. (Обратите внимание, что дублирование данных в разных дата-центрах является основной целью репликации.)
Вы можете иметь любое количество реплик одних и тех же данных. По нашему опыту, относительно надёжным и удобным решением в продакшене может быть двойная репликация, при этом каждый сервер использует RAID-5 или RAID-6 (а в некоторых случаях RAID-10).
Система отслеживает синхронность данных на репликах и способна восстанавливаться после сбоя. Переключение осуществляется автоматически (при небольших расхождениях в данных) или полуавтоматически (когда данные отличаются слишком сильно, что может указывать на ошибку конфигурации).
Создание реплицируемых таблиц
В ClickHouse Cloud репликация выполняется автоматически.
Создавайте таблицы с использованием MergeTree без аргументов репликации. Система автоматически преобразует MergeTree в SharedMergeTree для репликации и распределения данных.
Не используйте ReplicatedMergeTree и не задавайте параметры репликации, так как репликацией управляет платформа.
Параметры Replicated*MergeTree
| Parameter | Description |
|---|---|
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). Таким образом, путь в ClickHouse Keeper можно указать как '/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/ для базы данных Atomic).
Создайте пустой файл 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 были утеряны или повреждены, их можно сохранить, переместив в нереплицируемую таблицу, как описано выше.
См. также