В заметке описан простой способ копировать\переместить\синхронизировать файлы, расположенные в облачных хранилищах разных провайдеров при помощи утилиты rclone
Немного описания
Rclone поддерживает большое количество провайдеров как облачных, так и локальных. Список проще посмотреть на сайте проекта, чем перечислять. Проекту уже пять лет, наткнулся на него в поиске удобного инструмента, который бы умел работать одновременно с несколькими облачными провайдерами и синхронизировать их сразу, не делая копию на локальном диске. Иначе можно было просто использовать специфические утилиты, работающие с каждым из провайдеров по отдельности, типа nova и awscli.
Конфиг
Сначала надо настроить rclone для обращения к провайдерам. Делается командой rclone config
, но это как-то по детски и применить можно только для создания файла конфига или уточнения его параметров. Удобнее просто его отредактировать ~/.config/rclone/rclone.conf
:
[AWS] type = s3 env_auth = false access_key_id = <aws_access_key> secret_access_key = <aws_secret_key> region = <aws_region> [RS] type = swift env_auth = false user = <rackspace_user_name> key = <rackspace_api_key> tenant = <rackspace_account_number> auth = https://identity.api.rackspacecloud.com/v2.0 domain = Default region = <rackspace_region>
Вообще, у rclone вполне годная и понятная документация, но пару слов о параметрах сказать все же надо. В общем случае команда для копирования выглядит следующем образом:
rclone copy <source> <destination>
Применительно к примеру будет выглядеть так:
rclone copy RS:container_name AWS:bucket_name
Важные параметры
Обращаю внимание, что:
rclone sync
- удаляет все в destination и заменяет содержимым из source
rclone copy
- копирует все содержимое из source в destination, по умолчанию пропускает уже имеющиеся в файлы при совпадении их размера и времени изменения.
Полезные ключи:
-v
- verbose. Показывает действие над каждым файлом. Как бы сомнительно, но еще каждую минуту показывает промежуточную статистику, что имеет смысл. Если флаг не стоит, то просто молча работает (за исключением ошибок и варнингов) и так же молча завершается без какого-либо отчета. При использовании параметра --log-file
все сообщения пишет в файл.
--transfers
- количество параллельно загружаемых файлов, по дефолту 4. Удобная опция при большом количестве файлов.
--ignore-existing
- не трогать существующие файлы в destination. Не трогать, значит не проверять их время модификации и размер, ускоряя при этом процесс копирования. При изменении файла в source он не будет скопирован в destination, если там уже существует его предыдущая версия. Полезно при условии, что файлы в source не изменяются. Т.е. используется для копирования только новых файлов.
Я не шарю в golang чтобы выяснить точно, но похоже, что копию на диск утилиты все же делает, но не хранит файлы, а сразу отправляет в destination облако, т.е. диск использется в качестве кэша. Поэтому при копировании не хило так нагружается и диск, и сеть. Сеть грузится на 80-90 MBit/s при тарифе в 100, а SSD диск на 30% по данным iotop. Конечно, много зависит от скорости передачи, которую можно ограничить параметром --bwlimit
. Таким образом, если данных достаточно много, то желательно запускать rclone на сервере с минимальным удалением от одного из облачных хранилищ. Некоторые провайдеры поддерживают server side copy, т.е. копирование внутри одного провайдера между разными бакетами происходит по их внутреннему интерфейсу и делает это быстро. На S3, 30GB в 1100 файлах скопировались за 30 секунд.
Практика
Итак, случилось мне переезжать хранилище размером 350GB с двумя миллионами файлов из облака Rackspace Cloud Files в Amazon S3.
Первый раз заливал файлы так:
rclone copy -v --log-file=rclone.log --transfers=500 RS:container_name AWS:bucket_name
Поскольку в моем кейсе файлы в source не изменяются, то заливка новых файлов выглядит иначе:
rclone copy --ignore-existing -v --log-file=rclone.log --transfers=500 RS:container_name AWS:bucket_name
При --transfers=500
в лимиты ни одного из провайдеров не уперся.
Чуть позже будет статистика от боевого копирования.