...

четверг, 14 ноября 2013 г.

О бэкапах в облаке: используем Rackspace CloudFiles



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

Задача: есть у нас сервер в Rackspace, на полном фарше. На сервере неонка крутится база на MS SQL Web Edition. И вот внезапно ребятки спохватились — а куда еженощный бэкап девать? А то превышать он стал все разумные пределы, а пользы от его хранения на диске того же инстанса — чуть.


Как та мудрая сова из анекдота, я им предложил настроить средства облака из консольки. И был жестоко истыкан горячими острыми предметами — оказывается, сервер там не просто стар, а очень стар, висит он там на древнючем каком-то плане, у которого и нет ничего доступного, одни Cloud Files. И поменять — это надо идти к большому боссу уважаемой конторы, которая 200 лет на рынке. А большой босс им зарплату платит не за то чтобы они к нему за такими вещами ходили.


Я страшно удивился и спросил — а что, это так сложно — на коленке скрипт изваять? И запускать его аккурат после того как БД отбэкапится?


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


Мало ли, вдруг кому-то еще будет полезно, поэтому про эти скрипты подробнее расскажу.


Подготовка





Изучение мануала нам подсказывает, что для работы с облаком достаточно установить Curl. Однако мы им не поверим и поставим весь MSYS, который идет в комплекте с MinGW.


И заполним файлик про логин:



<?xml version="1.0" encoding="UTF-8"?>
<credentials xmlns="http://docs.rackspacecloud.com/auth/api/v1.1" username="LOGIN" key="RS API KEY"/>


Этот файлик мы будем скармливать рэкспейсу, чтобы получить токен. Без такого токена мы дальше не продвинемся.


Также, для остроты ощущений, писать мы будем досовские бат-файлы, чтобы враг не догадался. На самом деле, изобретать что-то более сложное просто нет смысла, они все в 5 строк получаются. Структура каждого из них вот такая



@echo off
setlocal
set PATH="%PATH%;C:\MinGW\msys\1.0\bin
...
endlocal




поэтому приведу ее один раз.

Login






Токен, который действует аж 24 часа, мы получим вот так:

curl -k -X POST -d @mylogin.xml -H "Content-Type: application/xml" -H "Accept: application/xml" https://auth.api.rackspacecloud.com/v1.1/auth > auth-token.xml
cat auth-token.xml | sed -e 's/.*token id=.//' | sed -e 's/..expires=.*//g' > token


Суровое смешение стилей — но зато у нас есть первый скрипт, он же login.bat. И — токен как результат его работы. Токен мы в дальнейшем можем использовать вот так



set /p TOKEN=<token


Создаем контейнер для бэкапов






Теперь нам надо определиться — куда мы будем складывать бэкапы и как именно. Схемы могут быть разные и и достаточно вычурные, но мы возьмем простейший случай. Представим на минутку что у нас есть обычный дифференциальный бэкап, и все что нам надо — это его раз в сутки заливать в определенное место.

set /p TOKEN=<token
curl -k -X PUT -H "X-Auth-Token: %TOKEN%" https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_d3125ab9-8601-45ba-a432-edf3728673bb/Backup




И мы определили это место, контейнер называется Backup. Свои именования — по вкусу.

Заливаем — первая попытка





А теперь попробуем залить туда что-нибудь:



set /p TOKEN=<token
curl -# -k -X PUT -T %1 -H "Content-Type: application/octet-stream" -H "X-Auth-Token: %TOKEN%" https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_d3125ab9-8601-45ba-a432-edf3728673bb/Backup/%1




А что там лежит?






Отвлечемся на минутку, а как мы увидим — что там вообще есть?

set /p TOKEN=<token
curl -# -k -H "X-Auth-Token: %TOKEN%" https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_d3125ab9-8601-45ba-a432-edf3728673bb/Backup/%1


После запуска, мы увидим список того что есть в контейнере, например вот так



4.0.327-RC1.rar
5.0.709-RELENG-spfix.rar
5.5.907-spfix.rar
foo.bak




Что успели залить на прошлом шаге, то и лежит, логично.

Скачаем обратно






Это в общем-то очевидно — просто урл с токеном.

set /p TOKEN=<token
curl -# -o %1 -k -H "X-Auth-Token: %TOKEN%" https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_d3125ab9-8601-45ba-a432-edf3728673bb/Backup/%1




Передаем параметром имя файла — работает!..

А теперь — горбатый!






Если бы дело было только в этом, я бы пост не писал.

Внедряем это в продакшен, то есть копируем скрипт на сервер, и… ба-бам! превышен размер пост-запроса. Логично — мы же для тестов заливали файлы небольшие, а дамп БД превышает 50 гигабайт.


Заливка больших файлов — попытка номер два






Значит ли это, что целиком дамп БД мы залить не можем?

И да и нет.


Одним запросом залить мы его не можем, это факт. Но получить на сервере один файл в 50+ гигабайт — можем. Заливать можно по частям, а затем эти части объединить в один файл.


Для этого, я приведу весь фрагмент, а затем разберем его подробнее.


Скрытый текст


set /p TOKEN=<token

split -d --bytes=500m %1 %1.parts.

ls %1.parts.* | awk 'BEGIN{x=0; print "@echo off"; }{ ++x; print "echo Uploading part " x "...\ncurl -# -k -X PUT -T " $1 " -H \"Content-Type: application/octet-stream\" -H \"X-Auth-Token: TOKEN\" https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_d3125ab9-8601-45ba-a432-edf3728673bb/Backup/FNN/" x " --data-binary \'" x "\'" }' | sed -e s/FNN/%1/g | sed -e s/TOKEN/%TOKEN%/g > _1.bat
echo curl -# -k -X PUT -H "X-Auth-Token: TOKEN" -H "X-Object-Manifest: Backup/%1/" https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_d3125ab9-8601-45ba-a432-edf3728673bb/Backup/%1 --data-binary '' | sed -e s/TOKEN/%TOKEN%/g >> _1.bat
call _1.bat
echo Clearing...
rm -f _1.bat %1.parts.*





Итак, сначала нам надо порезать большой файл на кусочки:



split -d --bytes=500m %1 %1.parts.


После чего мы займемся кодоложеством в тяжелой форме, а именно — построим из нашего скрипта второй скрипт, который и сделает всю работу.



ls %1.parts.* | awk 'BEGIN{x=0; print "@echo off"; }{ ++x; print "echo Uploading part " x "...\ncurl -# -k -X PUT -T " $1 " -H \"Content-Type: application/octet-stream\" -H \"X-Auth-Token: TOKEN\" https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_d3125ab9-8601-45ba-a432-edf3728673bb/Backup/FNN/" x " --data-binary \'" x "\'" }' | sed -e s/FNN/%1/g | sed -e s/TOKEN/%TOKEN%/g > _1.bat


Простым трюком ls %1.parts.* | awk мы на каждый кусочек получим свою команду. Вот такую


Скрытый текст


curl -# -k -X PUT -T foo.parts.0 -H "Content-Type: application/octet-stream" -H "X-Auth-Token: %TOKEN%" https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_d3125ab9-8601-45ba-a432-edf3728673bb/Backup/foo.0 --data-binary 0
curl -# -k -X PUT -T foo.parts.1 -H "Content-Type: application/octet-stream" -H "X-Auth-Token: %TOKEN%" https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_d3125ab9-8601-45ba-a432-edf3728673bb/Backup/foo.1 --data-binary 1
curl -# -k -X PUT -T foo.parts.2 -H "Content-Type: application/octet-stream" -H "X-Auth-Token: %TOKEN%" https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_d3125ab9-8601-45ba-a432-edf3728673bb/Backup/foo.2 --data-binary 2
...







где foo — имя переданного нам файла в комстроке.

Остался последний штрих — склеить это все воедино:



echo curl -# -k -X PUT -H "X-Auth-Token: TOKEN" -H "X-Object-Manifest: Backup/%1/" https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_d3125ab9-8601-45ba-a432-edf3728673bb/Backup/%1 --data-binary '' | sed -e s/TOKEN/%TOKEN%/g >> _1.bat




что нам даст в свежегенерированном батнике вот такое последней строчкой:

curl -# -k -X PUT -H "X-Auth-Token: %TOKEN%" -H "X-Object-Manifest: Backup/foo/" https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_d3125ab9-8601-45ba-a432-edf3728673bb/Backup/%1 --data-binary




Профит! Мы таки научились заливать большие файлы в облако и доставать их оттуда.

Надеюсь, этот поток индусского кода окажется кому-то полезным.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers.


Комментариев нет:

Отправить комментарий