Есть ли готовое решения для инкрементного резервное копирования бакетов s3 и если нет, то почему это никому не нужно?
Довольно много статей о том, как настроить инкрементное резервное копирование данных из приложения в S3. Например, с помощью Restic.
Но как сделать резервное копирование самого S3 бакета?
Да, бакеты поддерживают версионирование, но чтобы откатиться на заданную дату придется колхозить свои скрипты.
Чтобы сделать бекап из s3 в тот же Restic надо либо сперва выкачать бакет полностью (включая те данные, которые не изменились), а потом уже делать резервное копирование - это долго и дорого (трафик + место на промежуточном сервере),
либо сперва подмонтировать бакет с помощью rclone, а потом уже делать его резервную копию с помощью restic.
Как правило, обилие требуемых костылей говорит о том, что сама постановка задачи не корректная. Иначе бы была куча готовых инструментов и инструкций.
Такое впечатление, что никому и никогда не требуется делать резервные копию своих бакетов или откатывать содержимое бакетов на заданную дату. Что странно, т.к. есть приложения, которые используют s3 для хранения статических файлов, а значит есть и потребность консистентно откатить состояние приложения (sql-база плюс бакет в s3) к какой-то предыдущей контрольной точке. Или нет?
rPman, какого, AWS?
В рамках стандарта S3 я нашел только возможность включить версионирование, но возможности сделать слепки или просто откатить состояние бакета на дату не видел. По крайней мере через консольные утилиты, такие как s3cmd и т.п.
Возможно эта опция есть в недрах веб-интерфейса AWS, но это не удобно (бекапы надо делать по крону) и не у всех "родной* AWS.
rPman, p.s. посмотрел ссылку - там та самая опция версионирования, которую я смотрел первой. Но вот для отката на предыдущий момент времени я не нашел никаких готовых решений, кроме как колхозить скрипт на питоне, который будет перебирать версии и давать команды на восстановление или удаление. Это меня и смущает: раз нет готовой команды, значит что-то я планирую использовать не так, как задумано разработчиками s3
Как вам уже ответили - S3 это object сторадж и, в общем и целом, бэкап набора объектов внутри бакета для него - нетипичная ситуация.
Поэтому придется поскриптовать
Из ваших комментариев к соседним ответам я понял ваш пайплайн следующим образом:
есть система которая работает с БД и S3 - через интерфейс приложения создается набор данных в БД и соответствующие объекты в S3. Вы хотите сохранять это состояние и восстанавливать его после определенных событий, причем с бэкапом БД у вас вопросов нет, а с S3 непонятно. Версионирование S3 включено.
Вообще, из БД у вас же есть список объектов которые созданы в S3
На этапе бэкапа вы можете создать таблицу соответствия "ключ(имя) объекта в S3" -> "ID версии объекта в S3" и при восстановлении каждый объект восстанавливать на правильную версию, соответствующую БД.
Да, полученные ответы и комментарии укрепили меня в мысли, что приложение, хранящее статический контент в S3 - не типовая история. Настолько не типовая, что большинство комментаторов даже не сразу понимают, что я хочу хранить в S3 не бекапы, а рабочие экземпляры данных.
Но мне остается не понятным - почему?
Схема "база + файлы" - это типовой паттерн. Так работает не только Moodle, но и большинство веб-приложений, которые я видел. При перемещении приложения в облако, вся архитектура Docker Swarm или K8S кричит нам: не храни файлы локально. А S3, вроде бы, специально создан для такого применения (хранить статические, не изменяемые файлы, которые приложение изредка добавляет, часто запрашивает только для того, чтобы сразу же отдать клиенту по http и никогда не изменяет). Но если бы это было так, то было бы и готовое решение для консистентного бекапа. Но его нет. Значит никто S3 не применяет для такой задачи. Не понятно только почему.
Из Вашего ответа выходит, что правильный паттерн - поправить драйвер s3 в приложении так, чтобы при извлечении он не обращал внимания на статус удаления, а если приложение запросило файл, просто извлекать его, не зависимо от статуса. Плюс написать сборщик мусора, который окончательно удаляет файлы, которые были удалены больше месяца назад (к примеру).
Это хоть и требует большой работы, но хотя бы выглядит логичным решением.
Однако, все-равно странно, почему при наличии такого большого количества унаследованных приложений (практически любые веб-приложения - ownCloud, Redmine, Drupal, Moodle, Bitrix, osTicket, Mediawiki - да вообще что ни возьми), хранят файлы таким образом. И многие умеют класть их в S3. Казалось бы, давно должно быть готовое и универсальное решение, которое позволяло бы не переписывать драйверы и не колхозить скрипт бекапа.
с применением S3 схема это "база + объекты" причем ссылки на объекты лучше хранить в базе =)
(хранить статические, не изменяемые файлы, которые приложение изредка добавляет, часто запрашивает только для того, чтобы сразу же отдать клиенту по http и никогда не изменяет)
ну, S3 скорее - высокодоступное, скалируемое, версионированное хранилище объектов. Про основное применение можно вести споры )
в AWS S3 для консистентных срезов на несколько миллионов файлов (восстановление данных на конкретную дату) я использовал инвентаризацию бакета. Не уверен что для S3 совместимых решений есть что-то подобное (почти не использовал кроме домашнего минио) поэтому и предложил вам вести инвентаризацию конкретного набора данных самостоятельно )
Решение для консистентного восстановления в S3 в общем случае выглядит, наверное, так:
1. перечислить все объекты, в том числе удаленные, находящиеся в бакете.
2. для каждого объекта выяснить есть ли версия на заданную дату (т.е. присутствовал ли он на заданную дату в бакете)
3. восстановить объекты с заданной даты на актуальную версию
любой "внешний" бэкап, о котором вы говорили в комментариях - это, по сути, перевод объектов в файловый вид (монтирование в фс, или выкачивание файлов), а затем стандартное бэкапирование уже файлов
Евгений Хлебников, да, описанный Вами скрипт - это первый вариант, который я рассматривал. Данные из приложения для него, по сути, и не нужны - вся необходимая информация о датах существования объектов и так есть в S3. Сам скрипт на питоне получается строк на 20 и написать него не проблема. Смущает именно то, что в том же s3cmd, minio-mc и т.п. нет готовой команды для этого. Нет готовых популярных утилит (хотя их просто написать, они получаются достаточно универсальными для данной задачи). Именно это и вызывает сомнения, потому что я привык исходить из предположения, что "если в Черногории не продается черный хлеб, так это потому что он там никому не нужен, а не потому что ты - единственный гений, кто придумал такой шикарный бизнес-план" :)
Данные из приложения для него, по сути, и не нужны - вся необходимая информация о датах существования объектов и так есть в S3
вот тут я бы все таки выбрал единственный источник правды. Например БД.
А не надеялся что "photo.jpg версия на 20-е декабря" в S3 окажется "photo.jpg созданное 18 декабря" в базе - мало ли что там в бакете произошло за эти два дня, а версия-то создается при изменении объекта.
Бэкапим базу - делаем срез состояния, содержащий точно соответствующую версию объекта в S3, уже не ориентируясь на дату
Заодно сужаем список объектов - которые надо терзать при восстановлении.
Пробегаться по всем (а вдруг у вас там через два года будут миллиарды их) - долго и, в случае облачных провайдеров(если не селфхост) - дорого.
Евгений Хлебников, а зачем?
Moodle никогда не меняет файлы, более того, у него есть собственный механизм дедубликации и перед записью в хранилище, файл переименовывается в md5 от своего содержимого (а все ссылки и используемые в контенте имена файлов хранятся в БД). Поэтому, если системе нужен объект из хранилища с определенным именем и такой объект в хранилище есть - то совершенно точно это тот объект, который нам нужен.
Ну или я не очень понял вашу идею, что там может произойти с файлом, да еще и не отразитсья в его версии?
Евгений Хлебников, то есть, в общем виде Вы предлагаете вместе с дампом БД сохранять срез списка актуальных объектов с номерами ревизий (не важно в какой форме - прямо в дампе БД или отдельно) и при восстановлении пробегаться по этому списку, восстанавливать объекты/ревизии, которые в нем указаны и удалять все объекты, которые в списке не указаны?
А сама эта процедура (особенно поиск отсутвтвующих в списке объектов) не является слишком ресурсоемкой? Мы ведь снова приходим к ситуации, когда нам надо пробежаться по всему списку объектов в хранилище, чтобы найти отсутвтвующие в нашем срезе.
Алексей, ну, в общем - да, операция будет менее ресурсоёмкой, поскольку не нужно будет проверять версии каждого объекта который вам не нужен
Возможно, есть лучшее решение. Но я его не знаю )
S3 - это объектное хранилище, поэтому "откат на заданную дату" одного объекта никаких костылей не требует - это стандартная функциональность. А нескольких объектов - это действительно весьма странная задача, исходящая скорее всего из кривой архитектуры где-то выше.
"Бэкапы самого бакета" никто не делает, потому что намного проще, если вы используете S3 в качестве хранилища бэкапов, положить эти данные в другое место прямо с источника. Вдобавок, тот же AWS S3 и так реплицирован, кажется, почти на всех тирах.
Я рассматриваю вот такой пример:
есть среда электронного обучения Moodle, каждый экземпляр системы имеет свою базу данных (MySQL или postgresql) и свой набор статических файлов (картинки, видео, загруженные в систему документы). Чтобы откатить состояние системы на прошлую дату (например, отменить неудачное обновление или если ученики подсмотрели пароль преподавателя и устроили вандализм в его курсах), нам нужно восстановить базу из дампа и вернуть файлы из бекапа.
Система умеет хранить файлы в S3, но встаёт вопрос, как решать задачу с бекапами и откатами, причем автоматизировано (то есть, чтобы бекап выполнялся скриптом по крону).
Заходить в админку AWS и делать бекапы и восстановление не вариант, тем более, если у нас не AWS, а какой-нибудь Minio или Ceph, поднятый провайдером хостинга, где мы получаем только реквизиты пользователя с правом создавать бакеты через api. Добавлять в скрипт бекапа команду, которая бы приказывала бы AWS сделать бекап бакета - тоже такое себе, если эта команда не входит в стандарт S3 и не поддерживается утилитами, такими как s3cmd или даже штатной от Амазона.
В общем, как не крути, везде получается много самописного кода, по сравнению с хранением файлов на диске. Это настолько экзотическая задача, что так и не возникло универсальных решений?
Алексей, в общем случае восстановление из бэкапа - это редкая операция и её удобство (по сравнению со скоростью восстановления) не главный критерий. Но допустим, что это важно:
В целом, можно абстрагировать логику бэкапирования от того, где лежат файлы - и S3, и Ceph, и любое другое хранилище можно примонтировать в линуксе как раздел. Операции бэкапа и восстановления автоматизируются вполне тривиально. Получить список бэкапов и задать потом вопрос пользователю, который из них разворачивать - дело пары десятков строчек кода.
upd. намного важнее в вашем контексте - чтобы бэкап представлял собой один объект, а не россыпь файлов. Тогда и все сложности с "откатом всего бакета" пропадают.
ky0, да, я накопал три варианта:
1. Написать скрипт, который, опираясь на штатное версионирование s3 откатит состояние бакета на нужную дату.
2. Монтировать бакет с помощь того же rclone в качестве раздела, а потом бекапировать этот раздел тем же самым restic.
3. Выкачать Bucket с помощью rclone, а потом сбекапить его через Restic или Borg
Они описаны в исходном вопросе.
Но все эти варианты выглядят костыльно и инородно. Это наводит на подозрение, что сама постановка задачи неверная. Иначе бы в Restic просто была бы опция "сбекапить Bucket напрямую из источника" (без примонтирования его к файловой системе, что для S3 само по себе не стандартное применение). Или в api S3 была бы не только команда "включить версионирование", но и "восстановить состояние Бакета на заданную дату". Но раз таких опций нет, значит это не типовая задача, что кажется мне странным.
Собственно, об этом и был вопрос
Алексей, все варианты "так себе", потому что вы зачем-то хотите трогать сразу весь бакет.
Я ещё раз говорю - если использовать бэкапы как одиночные объекты, из которых можно полностью восстановиться, никаких костылей не понадобится. Можно даже не использовать версионирование, а просто класть рядом архивы с разными именами и ротировать их периодически.
ky0, так у меня в бакетах не бекапы и не одиночный объекты. Там файлы одной инсталляции Moodle (грубо, это все файлы, которые загружены преподавателями и учителями в среду электронного обучения). Каждый файл - это отдельный объект. Консистентный набор данных включает в себя дамп SQL и весь набор загруженных в систему файлов сразу.
Например, преподаватель создает учебный материал и крепит к нему 3 картинки. Текст и параметры материала пойдут в SQL, а картинки в бакет (каждая - как отдельный объект).
Соответственно, мне нужно не один объект откатить, мне нужно чтобы бакет содержал ровно те объекты, о наличии которых "помнит" sql-дамп - ни одним файлом больше и ни одним файлом меньше.
Такая архитектура - это данность. Чтобы докеризировать это приложение, один из вариантов - переместить файлы из локального хранилища в бакет, но для этого надо решить проблему с бекапами. Ну либо не перемещать хранилище в бакет, а использовать тот же CephFS или NFS, но S3 выглядит привлекательным вариантом.
Неужели это такая не типичная задача? Казалось бы, любое приложение (сайт, crm и т.п.) которое хранит данные в S3 хранит не одтельные объекты, а сразу набор таких объектов и при восстановлении из бекапа надо восстановить не просто один объект, а весь их набор. Или нет?
вы храните только все что относится к moodle?а операционная система и другой софт? его дети не ломают?
p.s. сущность целиком можно было бы хранить в инкрементальных бакапах файловой системы, особенно если у вас есть возможность сервер баз данных останавливать на время бакапа (точнее создания снапшота - это секунды)
Инкрементальные бакапы же файловой системы (например btrfs/zfs, фича встроена в файловую систему) можно представить как файл и хранить его уже где угодно
рядышком держать развернутую копию и последовательность историй бакапов на нужную глубину (например еженедельные) а до нужной версии доводить последовательным восстановлением файла от ближайшей
rPman,
> вы храните только все что относится к moodle?а операционная система и другой софт? его дети не ломают?
Это проблема других людей :) Я занимаюсь только веб-приложениями
> p.s. сущность целиком можно было бы хранить в инкрементальных бакапах файловой системы, особенно если у вас есть возможность сервер баз данных останавливать на время бакапа (точнее создания снапшота - это секунды)
Для варианта, когда файлы хранятся в файловой системе эта задача давно решена. И для нее есть удобные решения. Можно хранить бекапы хоть локально, хоть в s3, хоть в специальном сервере бекапов, доступном по REST.
Но если мигрировать на S3, чтобы там лежали не бекапы, а сами файлы приложения (это нужно, например, если мы хотим кластеризовать наше приложение или если у нас облачный хостинг, где хостятся тысячи независимых экземпляров приложений с горячим резервированием и автоматической миграцией), то встает вопрос, как консистентно бекапировать и восстанавливать бакеты s3. Как я написал выше, я нашел 3 решения, но все они в равной степени неудобные и костыльные. И вопрос не в том, как это можно было бы сделать вообще, а в том, почему для этого нет готовых решений: неужели никто не хранит в s3 сами данные приложения (не бекапы, а именно рабочие копии) и не сталкивается с задачей резервного копирования не от общего сбоя хранения, а от порчи данных в отдельном экземпляре приложения.
Для понимания масштаба - один экземпляр Moodle среднего университета может запросто содержать террабайт данных, разбросанным по файлам, размером от пары килобайт до нескольких гигабайт. На этих масштабах "просто выкачать все файлы локально, чтобы потом сбекапить" выглядит довольно дорогостоящей и длительной операцией. А если каждый экземпляр нужно бекапить минимум ежедневно и хранить копии хотя бы за неделю, а лучше за месяц, то это становится вообще не реалистично.
Вариант, откатить единовременно все данные всех экземпляров, восстановив файлы сервера s3 из резервной копии тоже не годится, потому что редко когда бывает нужно восстановить больше одного экземпляра за раз.
Поэтому единственный жизнеспособный вариант - это либо инкрементно бекапить один бакет в другой, с дедубликацией и скачиванием только изменений, либо положиться на версионирования самих Bucket, с откатом на нужную дату. Но ни для того, ни для другого нет готовых решений и на это, очевидно, есть веская причина (раз задача есть, а стандартного решения нет). Вот эту причину я и пытаюсь понять.
Хм. Да похоже AWS.S3 действительно не поддерживает откат бакета в прошлое.
Но если рассматривать S3 как протокол поверх обычной файловой истемы
(Minio+BTRFS/ZFS) то вы можете задачу отката переформулировать в терминах
конкретной файловой системы. Там - это коробоная фича.
Да, Вы правы, но этот вариант годится только если у нас отдельный экземпляр Minio для каждого экземпляра приложения. Если S3 предоставляется как сервис облачным провайдером, который дает интерфейс только для создания новых пользователей с квотами, а работа с бакетами выполняется по протоколу s3, то воспользоваться бекапом самого сервера S3 не выйдет. Тем более, что каждый бакет привязан к отдельному приложению и его может понадобится откатить отдельно от остальных бакетов.