Делаем резервное копирование кластера ClickHouse: простая инструкция

—

от автора

Меня зовут Леонид Блынский и я администратор баз данных в Лиге Цифровой Экономики. В этой небольшой статье расскажу, как я делаю резервное копирование кластера ClickHouse размером 20 ТБ.

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

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

Для стенда разработки мы сделали возможность создания локальных бэкапов. В файле настроек /etc/clickhouse-server/config.d/backup_disk.xml

потребовалось прописать разрешенный путь для бэкапа:

<clickhouse> <storage_configuration>     <disks>         <backups>             <type>local</type>                 <path>/var/lib/clickhouse/backups</path>         </backups>     </disks> </storage_configuration> <backups>         <allowed_disk>backups</allowed_disk>     <allowed_path>/var/lib/clickhouse/backups/</allowed_path> </backups> </clickhouse>

Разработчики и аналитики теперь могли сохранить данные перед какими-либо необратимыми действиями:

backup table main.dim_account TO Disk('backups', ' main.dim_account.zip')

Ключевое слово Disk следует писать с большой буквы:)

Или так, для бэкапа всей БД:

backup database main TO Disk('backups', ' main_dev.zip')

Мы проверили — восстановиться просто, все работает отлично:

restore table main.dim_account AS main.dim_account FROM Disk('backups', ' main.dim_account.zip')

Далее мы настроили хранилище S3 для хранения бэкапа нашей БД. Команда для запуска стала выглядеть так:

backup table main.dim_account to S3('http://10.10.10.10:9000/clickhouse/ main.dim_account.zip','bkp_user','bkp_pwd');

Далее мы попробовали вручную забэкапить все таблицы базы. Все шло хорошо, пока не пришла очередь самой большой таблицы размером около 3 ТБ. В какой-то момент стала выпадать ошибка:

<Fatal> BaseDaemon: Received signal Segmentation fault (11)
<Fatal> BaseDaemon: Address: 0x7f0ba8a00960 Access: write. Address not mapped to object.
<Fatal> BaseDaemon: Stack trace: 0x7f7ab25479e6 ………………….

Ошибка возникала случайным образом: таблица то бэкапилась, то нет. Поиск на форумах ни к чему не привел. 

Так как с другими таблицами проблем не возникало, мы сделали вывод, что проблема именно в размере, потому и надо что-то придумать, чтобы уменьшить размер резервной копии в одной команде.

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

В нашем кластере 6 узлов и несколько конфигураций баз данных: база allrp (имеет реплики на всех шести узлах), main (3 шарда, и каждый шард имеет две реплики). 

Для бэкапа allrp достаточно снять копию только с одного узла. Для резервного копирования main требуется снять копию c трех узлов. То есть надо зайти на все хосты, где располагаются шарды, сгенерировать  и выполнить команды бэкапа.

Немного вспомнив язык SQL, мы явили на свет скрипт генерации команд бэкапа по партициям:

select distinct 'backup table ' || database || '.' || table || '  partition ''' || partition || ''' to S3(''http://10.10.10.10:9000/clickhouse/' || formatDateTime(now(),   '%d-%m-%Y')|| '/main.' || table || '.' || partition || '-shard-' || q2.shard || '.zip'',''bkp_user'',''bkp_pwd'');' as backup_command FROM   system.parts,   (   select          toString(shard_num) as shard   from          system.clusters   where          host_address = '127.0.0.1'          and cluster = 'main') q2 where active   and database = 'main'   and table in ('fct_bigtable') group by   database,   table,   partition,s   q2.shard

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

Так как остальные таблицы не вызывали проблем, то их бэкапим уже целиком:

select * from   (   select          distinct 'backup table ' || database || '.' || table || '  to S3(''http://10.10.10.10:9000/clickhouse/' || formatDateTime(now(),          '%d-%m-%Y')|| '/main.' || table || '-shard-' || q2.shard || '.zip'',''bkp_user'',''bkp_pwd'');'   from          system.parts,          (          select                toString(shard_num) as shard          from                system.clusters          where                host_address = '127.0.0.1'                and cluster = 'main') q2   where          active          and database = 'main'          and table not like 'fct_bigtable%' ) q1

Данные SQL надо выполнить на каждом узле с уникальными шардами (в нашем примере на трех) и на этих же узлах запустить сгенерированные команды. Для сохранения результата запроса в файл можно последней строчкой дописать:

INTO OUTFILE '/var/lib/clickhouse/backups/backup.sql' FORMAT TabSeparatedRaw; 

Для бэкапа базы allrp генерируем команды, которые надо запустить на любом узле:

select   distinct 'backup table ' || database || '.' || table || '  to S3(''http://10.10.10.10:9000/clickhouse/' || formatDateTime(now(),   '%d-%m-%Y')|| '/allrp.' || table || '.zip'',''bkp_user'',''bkp_pwd'');' from   system.parts where   active   and database = 'allrp'; 

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

select * from system.backups_distributed

После того как нам удалось в ручном режиме проводить полноценный бэкап базы данных, начался этап автоматизации. Мы привлекли разработчика Python — он за пару дней реализовал задачи в Airflow, которые генерируют команды бэкапа, запускают их, отслеживают выполнение и в случае аварии отдельных команд ставят их в очередь снова. То есть бэкап стало возможным пускать по расписание или «по нажатию кнопки» в Airflow.

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

Как результат — вполне стабильный инструмент с интерфейсом, визуализацией работы и мониторингом, который можно полностью контролировать.

Ранее мы рассказывали, как работать со словарями данных и оптимизировать запросы и распределенными таблицами в ClickHouse. Возможно, это тоже будет полезно.


ссылка на оригинал статьи https://habr.com/ru/articles/810445/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *