Эффективное резервное копирование в Amazon Web Services — рецепты

в 6:38, , рубрики: mysql, Битрикс24, Блог компании 1С-Битрикс, веб-кластер, метки: , ,

Всем привет!
Сегодня поговорим о техниках настройки резервного копирования файлов и MySQL/InnoDB/XtraDB в приложениях, развернутых в облаке, на примере Amazon Web Services.
Эффективное резервное копирование в Amazon Web Services — рецепты
В ходе разработки облачного сервиса Битрикс24 мы попробовали несколько схем резервного копирования, наткнулись на некоторые подводные камни архитектуры амазона и ограничения софта — однако все постепенно разложилось по полочкам и зажужжало :-)
Также внимательно рассмотрим вопрос инкрементального бэкапирования достаточно больших объемов данных (сотни гигабайт и больше), рейдов и конфигураций с InnoDB/XtraDB.
Но прежде всего в деталях разберемся в технологиях хранения данных, предлагаемых нам амазоном.

Где живут данные виртуальных машин

Итак, начнем с того, что нам предлагает амазон для хранения данных виртуальных машин — виртуальные блочные устройства EBS. Такой диск запросто создается и подключается к серверу в 2 клика. Максимальный размер диска — 1ТБ. По умолчанию, есть ограничение на 5000 дисков и 20ТБ, но его увеличивают по первой просьбе.
Предлагается еще технология локальных блочных устройств, данные на которых… исчезают вместе с сервером (а это запросто может произойти при аварийном завершении работы машины) — но я про нее не буду писать, т.к. мы с ней не экспериментировали.

Производительность EBS-дисков

Довольно сразу видно, что они — медленнее «железных». Насыщение устройства (%util, команда iostat) при объеме произвольного чтения в десяток-другой МБ/сек (по записи — еще меньше) — быстро приближается к 100%. Притормаживание отчетливо видно на популярных операциях типа копирования папок с диска на диск, распаковке архивов и т.д.

Рейд?

Чтобы адекватно начать работать с дисками амазона, проще всего «засунуть» их в софтварный рейд. Для баз данных мы используем рейд-10 на 8 EBS дисках как на ext4, так и xfs. Делается софтварный рейд довольно просто, работает долго и практически не ломается.
Рейд может особенно пригодиться, если EBS-диск внезапно «вылетет».
Тем не менее, для ряда задач мы не используем рейды — например для хранения бинарного лога MySQL, для бэкапов и др. А для хранения кэша nginx хорошо подошел raid0 на EBS-дисках, который устойчиво работает без сбоев примерно год.

Надежность EBS-дисков

Если честно, за полтора года работы с EBS-дисками амазона они не разу нас не подводили (никаких глупостей типа «бэдов», ошибок чтения и др.)… кроме случая, когда в Ирландский датацентр амазона ударила молния — тогда вылетело сразу по несколько дисков из рейд-10 :-)
Однако, если внимательно прочитать что пишет амазон о надежности своих дисков, то понимаешь, что и рейд нужно делать и, разумеется, регулярные бэкапы:
Amazon EBS volume data is replicated across multiple servers in an Availability Zone to prevent the loss of data from the failure of any single component. The durability of your volume depends both on the size of your volume and the percentage of the data that has changed since your last snapshot. As an example, volumes that operate with 20 GB or less of modified data since their most recent Amazon EBS snapshot can expect an annual failure rate (AFR) of between 0.1% – 0.5%, where failure refers to a complete loss of the volume. This compares with commodity hard disks that will typically fail with an AFR of around 4%, making EBS volumes 10 times more reliable than typical commodity disk drives.
С другой стороны у нас в продакшене больше сотни нагруженных EBS-дисков и за полтора года софтварные рейды не разу не выбивали диски из-за IO-ошибок. На «железных» дисках, уверен, мы бы уже сменили не одно устройство, так что делайте выводы.

Доступные технологии резервного копирования

Когда данных относительно немного и они меняются не часто, можно поиграться с tar. Но представьте себе крупный интернет-магазин, который хранит бизнес-информацию как в БД, так и в файлах на диске: новые файлы появляются ежеминутно, а общий размер контента составляет сотни гигабайт.
DRBD? Да, но не пробовали эту технологию в амазоне да и нередко слышу от коллег о ее неимоверных торможениях при возникновении ошибок.
LVM и снепшоты в режиме copy-on-write — подобие этой технологии, только с дополнительными плюшками и предлагает нам амазон. Снепшоты блочного устройства можно делать столько раз, сколько необходимо. При этом:

  1. В очередной снепшот диска EBS попадают ТОЛЬКО ИЗМЕНЕНИЯ. Причем это совершенно прозрачно и становится очевидным, когда смотришь ежемесячный счет на использование места на дисках. Даже если у тебя 100 снепшотов с диска 500ГБ, но данные менялись не часто — платишь за примерно 500-500ГБ, что конечно играет в пользу клиента.
  2. Можно и нужно удалять снепшоты — для сохранения балланса между размером окна резервирования и стоимостью хранения данных. При этом, что вызывает восторг, можно удалять ЛЮБОЙ снепшот — амазон автоматически консолидирует данные нужным образом. И совершенно не болит голова на тему — где базовый снепшот, а где инкрементальный — неважно, удаляешь лишние из любой позиции (кто работал с Acronis — оценит удобство).
  3. Снепшоты дисков сохраняются в S3. S3 — как все наверно уже знают, это хранилище объектов любого формата, реплицирующее данные минимум еще в 2 датацентра. Т.е. снепшот диска становится практически «неубиваемым» и сохранен надежнее винтчестера в запертой тумбочке под рабочим столом :-).
  4. Снепшот диска делается практически мгновенно — затем в фоне данные передаются в S3 определенное время (иногда десятки минут — если амазон загружен).

Все это означает, что мы можем делать снепшоты огромной папки часто меняющегося контента на диске хоть раз в 5 минут — они будут надежно сохраняться в S3 и если нужно откатить 1ТБ изменяемых данных на 5 минут назад — мы это с легостью делаем так:

  1. Создаем диск из сохраненного снепшота.
  2. Подключаем диск к серверу.

Разумеется, технически невозможно мгновенно перелить 1ТБ данных из S3 в SAN где живут EBS-диски, поэтому хотя блочное устройство и становится доступным операционной системе, данные на него будут заливаться в фоне определенное время — поэтому возможно скорость работы с диском поначалу будет не очень высокой. Но, тем не менее — согласитесь, как удобно можно делать инкрементальнрый бэкап большого объема данных и откатывать их на любую точку, например, на неделю назад с шагом в 5 минут? :-)
Кроме возможности создания снепшотов с EBS-дисков, можно отправлять файлы в S3 напрямую. Удобна в использовании утилита s3cmd — можно синхронизировать деревья файловой системы с облаком в обоих направлениях (передаются только изменения на базе расчета md5 на локальном диске и хранения md5 объекта внутри s3 в «ETag»). Пробовали решения на базе технологии FUSEs3fs, но заметили подтормаживания и длительные зависания с ростом LA при ее интенсивном использовании.
Эффективное резервное копирование в Amazon Web Services — рецепты

Снепшот рейда

Как я писал выше, EBS-диски показывают адекватную производительность, если их объединить в рейд0, рейд10. А как бэкапить рейд? Делать снепшот каждого диска по очереди? :-) Понимаем, что нельзя и амазон тут нам ничего не предлагает.
Добрые люди написали удобную утилиту — ec2-consistent-snapshot. Можно использовать ее, а можно в скриптах повторить ее логику.

  1. Используем файловую систему, поддерживающую «фризинг» — т.е. понимающую, что с нее сейчас делается снепшот на уровне блочного устройства и необходимо сбросить буферы, закоммитить транзакции и временно остановить изменения блоков. Такую команду (xfs_freeze) до недавнего времени понимала XFS, однако в «последних» дистрибутивах linux появилась возможность «фризить» и другие распространенные файловые системы: ext3/ext4, xfs, jfs, reiserfs.
  2. Сбрасываем изменения и кратковременно запрещаем запись в ФС: «fsfreeze -f mountpoint»
  3. Делаем снепшоты каждого диска рейда: AWS API call CreateSnapshot.
  4. Разрешаем запись в ФС: «fsfreeze -u mountpoint»

Если у вас xfs — можно использовать команду xfs_freeze.
Для подключения сохраненного рейда лучше написать скрипт, подключающий диски к машине и запускающий из них софтварный рейд. Сохраненный в снепшоты вышеуказанным способом рейд прекрасно поднимается не проигрывая журнал файловой системы — используем в разных местах в продакшене.
Итак, мы научились делать снепшот рейдов в s3 с любым объемом данных с частотой хоть раз в 5 минут и восстанавливать данные с них. Подобные вещи, уверен, многим пригодятся на различных проектах в облаке.

Снепшот машины целиком

Иногда удобнее не париться отдельно с каждым рейдом, а сделать снепшот всех дисков машины одной командой. Можно сделать снепшот в 2 режимах: с остановом машины и без останова. В последнем случае нас логично предупреждают о возможной «порче» данных на дисках/рейдах:
When taking a snapshot of a file system, we recommend unmounting it first. This ensures the file system metadata is in a consistent state, that the 'mounted indicator' is cleared, and that all applications using that file system are stopped and in a consistent state. Some file systems, such as xfs, can freeze and unfreeze activity so a snapshot can be made without unmounting.
После создания снепшота машины появляется объект AMI (Amazon Machine Image), имеющий ссылки на сохраненные снепшоты каждого своего диска. Можно одной командой запустить из этого объекта сервер со всеми дисками/рейдами — AWS API call RunInstances. Почувствовали мощь технологии? Рабочие сервера можно не только бэкапить целиком, но и поднимать из бэкапа ЦЕЛИКОМ со всеми рейдами одной командой! Данная технология сэкономила нам десятки часов системного администрирования при аварии амазона в августе прошлого года — мы подняли машины из снепшотов и развернули конфигурацию в другом датацентре.
Однако есть серьезный подводный камень — команда CreateImage совершенно непрозрачна и неясно, сколько времени она снимает снепшоты со всех дисков сервера — секунду или 10 секунд? Методом научного тыка был подобран интервал — 5 секунд, позволяющий снимать целостные образы машины с рейдами. Предупреждаю — тщательно протестируйте скрипт перед запуском в продакшн — однако перед «вкусностью» технологии создания полного бэкапа машины, согласитесь, трудно устоять :-)

Инкрементальный бэкап MySQL

Напомню нашу задачу — бэкапить проект с посещаемостью в миллионы хитов в сутки и сотнями гигабайт довольно часто меняющегося контента (самый тяжелый контент вынесен в s3 и скачивается отдельно). Повторю известные разумные подходы к бэкапу MySQL:

  1. Логический бэкап со slave. В этом случае мы не замедляем работу основного сервера, однако… рискуем забэкапить «случайно» рассинхронизированные данные (поэтому нужно следить за синхронностью, например с помощью pt-table-checksum).
  2. Бинарный снепшот с помощью LVM с боевого сервера/слейва, либо — копируем блоки на DRBD-диск на резервной машине.
  3. Инкрементальный бинарный бэкап с боевого сервера или slave с помощью xtrabackup или аналогичным платным инструментом.

Чтобы иметь возможность быстро откатить крупный интернет магазин на 5-10 минут назад в случае катастрофического удаления данных в БД (ошибочный запрос, убивающий данные в нескольких таблицах заказов — с кем еще не было? :-) ) — кажется, что подойдет только 3 вариант. Однако, как оказалось, бинарный инкрементальный бэкап при создании оказывает немалую нагрузку на и без того слабенькие EBS-диски, но и чтобы наложить инкременты на базовый бинарный бэкап при восстановлении может уйти… несколько часов!
Я не рассматривают тут сценарии восстановления из логического бэкапа с предварительным редактированием бинарного лога MySQL — это все равно быстро не сделать.
И тут нам снова помогает амазон. Делается инкрементальный бэкап MySQL так:

  1. Сбрасываем буферы MySQL/InnoDB/XtraDB на диск: «FLUSH TABLES WITH READ LOCK»
  2. Сбрасываем изменения и кратковременно запрещаем запись в ФС: «fsfreeze -f mountpoint»
  3. Делаем снепшот всех дисков машины: CreateImage. См. выше про подводные камни. Если есть опасения, делаем снепшоты каждого диска рейда с БД: AWS API call CreateSnapshot.
  4. Разрешаем запись в ФС: «fsfreeze -u mountpoint»
  5. Снимаем глобальную локировку всех таблиц во всех базах данных: «UNLOCK TABLES».

Теперь у нас появился объект AMI с горячим бэкапом MySQL и мы сделали максимум возможного, чтобы он запустился из бэкапа как можно быстрее.
Таким образом, оказалось довольного просто делать инкрементальный бэкап сервера MySQL в S3 с частотой хоть раз в 5 минут и возможностью его быстрого ввода в продакшн. Если сервер используется в репликации, то он восстановит ее как правило без особых проблем, если вы не забыли в настройках задать консервативные настройки репликации (ну или ее можно довольно быстро вернуть в работу вручную):
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
sync_master_info = 1
sync_relay_log = 1
sync_relay_log_info = 1

Как заскриптовать действия с амазоном?

Для системного администратора имеются удобные утилиты, дергающие REST-методы АПИ амазона. Скачивается несколько утилит, для каждого используемого веб-сервиса, и вызовы к утилитам скриптуются в bash. Вот пример скрипта, меняющего у сервера «железо»:

#!/bin/bash

#Change cluster node hw type

#Which node to change hardware?
NODE_INSTANCE_ID=$1

#To which hw-type to change?
#Some 64-bit hw types: t1.micro (1 core, 613M), m1.large (2 cores, 7.5G), m1.xlarge (4 cores, 15G),
#m2.xlarge (2 cores, 17G), c1.xlarge (8 cores, 7G)
NODE_TARGET_TYPE='c1.xlarge'

#To which reserved elastic ip to bind node?
NODE_ELASTIC_IP=$2

ec2-stop-instances $NODE_INSTANCE_ID

while ec2-describe-instances $NODE_INSTANCE_ID | grep -q stopping
do
    sleep 5
    echo 'Waiting'
done

ec2-modify-instance-attribute --instance-type $NODE_TARGET_TYPE $NODE_INSTANCE_ID

ec2-start-instances $NODE_INSTANCE_ID

ec2-associate-address $NODE_ELASTIC_IP -i $NODE_INSTANCE_ID

Для разработчиков имеются библиотеки на разных языках для работы с API амазона. Вот библиотечка для работы из PHP — AWS SDK for PHP.
Как видим, заскриптовать работу с объектами амазона — просто.
Эффективное резервное копирование в Amazon Web Services — рецепты

Итоги

На конкретных примерах, разбавленных теоретической базой популярных практик и подсоленных эффективными инструментами API амазона мы научились:

  • инкрементально бэкапить и восстанавливать большие объемы данных с EBS-дисков и рейдов амазона в S3 и обратно
  • бэкапить и восстанавливать машины амазона целиком
  • инкрементально бэкапить и быстро вводить в строй сервера MySQL с данными, хранящимися на рейдах EBS-дисков
  • обсудили несколько подводных камней
  • посмотрели как просто заскриптовать основные действия

В одной из следующих статей расскажу как эффективно управлять трафиком и балансировать нагрузку между кластерами и датацентрами амазона.
На практике мы активно используем перечисленные в статье технологии, эксперементируем, открыты и готовы делиться опытом и искать простые и эффективные решения возникающих задач, используя инструменты мира open source.
Приглашаю всех зарегистрироваться на нашем облачном сервисе «Битрикс24» и посмотреть что у нас получилось. Также приглашаю желающих на БЕСПЛАТНЫЙ семинар, посвященный веб-кластерам и высоким нагрузкам, который пройдет в конференц-зале компании «1С» 22 мая.
Всем удачи в построении масштабируемых и отказоустойчивых систем!

Автор: AlexSerbul


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js