Как бэкапить данные и MySQL в Amazon Web Services

    Всем привет!
    Хочу поделиться опытом организации резервного копирования файлов и MySQL/XtraDB в Amazon Web Services. Надеюсь, информация пригодится, особенно если вас «принудили» развернуть проекты в облаке, а время — ограничено :-)
    Но прежде всего кратко пробежим технологии хранения данных, предлагаемые нам амазоном.


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


    Итак, начнем с того, что нам предлагает амазон для хранения данных виртуальных машин — виртуальные блочные устройства 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ГБ, но данные менялись не часто — платишь за примерно 600-800ГБ, что конечно играет в пользу клиента.
    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 при ее интенсивном использовании.

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


    Как я писал выше, 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.
    Как видим, заскриптовать работу с объектами амазона — просто.

    P.S.


    Архитектура нашего проекта обзорно представлена тут. Кроме бэкапов, думаю, стоит написать про несложную технику автомасштабирования кластера и переключение трафика между датацентрами. 22 мая проводим БЕСПЛАТНЫЙ семинар, посвященный веб-кластерам и высоким нагрузкам, который пройдет в конференц-зале компании «1С».
    Надеюсь, будет интересно, приходите :-)
    • +24
    • 3,8k
    • 7
    Поделиться публикацией

    Комментарии 7

      +1
      Есть к вам пара вопросов.

      Во-первых, не пугает ли вас, что делая снапшоты каждого диска в raid10, вы получаете 8 дисков, забитых мусором и бесполезных поодиночке? Понимаете ли вы, что при потере пары снапшотов из одной зеркальной пары восстановить массив не удастся, и придется откатываться к более ранним копиям?

      Во-вторых, если вы используете нативный механизм снапшотов в ec2, это означает, что вы не сможете получить к снапшотам доступ в случае падения всего региона, пусть даже они и бакапятся внутри самого амазона в один или несколько регионов. Кроме того, будет довольно проблематично использовать полученные снапшоты где-то еще кроме амазона.

      Рассматривали ли вы вариант с LVM поверх raid, самостоятельными снапшотами и бакапами прямо на S3, откуда их можно слить без особых проблем?
        +2
        1) А что делать, если на рейде бизнес-данные, их много, и нужно обеспечить их инкрементальное копирование с возможностью отката назад на короткое время. ФС фризится и в результате многочисленных тестов ФС с рейдом поднималась без проигрывания журнала.

        2) На регион амазона SLA — 99,95%, однако даже 4 часового простоя региона за последние 2 года (и насколько знаю и больше) у них не было. ДЦ — лежали сутками, было, а вот регион максимум разок тупил полчаса. У них вся архитектура спланирована вокруг того, что регион «неубиваем». Ну мы планируем снепшоты их использовать для восстановления машин в другом ДЦ этого же региона.

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

        3) Нет, LVM не рассматривали пока. Удобно, что это встроено в их API.

        Спасибо за коммент.
        0
        Мы эксперементировали с instance-store («технология локальных блочных устройств»). Поскольку у него есть «фишка» умирать вместе с остановкой машины, то в случае падения (или отключения ssh), машина выходит из-под контроля (это не решается даже через сапорт амазона). Он полезен, когда надо открыть несколько клонов одного сервера (из одной AMI), на которых не хранится нчего, кроме кеша (ресурсы хранятся на s3/cloudfront, БД и почта на отдельных серверах).
          0
          Я слышал, что у коллег, держащих данные на instance-store при известной аварии EBS-контроллера амазона в штатах все продолжало крутиться :-)

          В связи с неоднократно замеченными фактами внезапной перезагрузки машин амазона (раз и ребут, без сообщения о kernel-panic) — мы стараемся все данные хранить в EBS. В вирджинии не ребутятся и надежно работают машины типа c1.xlarge, другие, более слабые и равные по мощности типы периодически внезапно ребутились.
            0
            У нас случай внезапного выхода сервера из строя был только один раз (не связано с молнией). Обычно, в преддверии хардварных проблем, Амазон присылает письмо, мол «так и так, скоро ваша инстанция сдохнет, чтобы она переоткрылась на другом железе сделайте рестарт или разверните новую AMI». Конечно, хранить на instance-store нодах нельзя ничего, кроме кешей, временных файлов и локальных логов. Это должны быть чистые application-сервера, которые можно без последствий создавать, когда требуются мощности и убивать когда уже не требуются.
          +1
          Прекрасная статья, с удовольствием не раз ещё перечитаю. Большое спасибо автору!
          Столько полезного материала, собранного в одном месте, не встречал и на английском.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое