Добавление больших файлов с помощью Python-Swiftclient

Наша служба хранения файлов работает на базе OpenStack Swift. У Swift есть ограничение на размер каждого добавляемого файла. По умолчанию лимит равен 5 ГБ. Однако при использовании сегментации можно добавлять файлы почти неограниченного размера. 

Для добавления файла объемом более 5 ГБ используйте сегментацию. Это позволит разбить большой файл на сегменты. Например, файл размером 6 ГБ можно разбить на два сегмента по 3 ГБ каждый. 

Самый быстрый способ применения данной функции — это python-swiftclient. Информация об установке и использовании инструмента python-swiftclient приведена здесь!


Ниже приведен пример использования.

swift upload YOUR_STORAGE_NAME --segment-size 3221225472 LARGE_FILE --os-username YOUR_USERNAME --os-tenant-name YOUR_TENANT --os-password YOUR_FTP_PASSWORD --os-auth-url https://auth.files.us01.cloud.servers.com:5000/v3 --auth-version 3

Используйте опцию -S чтобы задать размер сегмента в байтах. Например, 1 гигабайт – это 1073741824 байт, 3 гигабайта – 3221225472 байта.

Самый быстрый способ применения данной функции — это python-swiftclient. Для дополнительной информации см. Загрузка с использованием Python-Swiftclient


Далее в бекенде хранилища OpenStack Swift выполняется следующее:


1. Разделение файла на сегменты указанного размера.

2. Добавление всех сегментов параллельно.

3. Создание файла манифеста, который позволяет загружать/получать доступ к файлу как к одному, не обращая внимания на сегментацию.


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

Python-swiftclient будет управлять этими файлами сегментов за вас, удаляя старые сегменты при удалении и перезаписи и т. д. При желании вы можете переопределить это поведение с помощью опции –leave-segment; это актуально, если вы хотите, чтобы было доступно несколько версий одного и того же большого объекта.


Где: 

--os-username

первая часть имени пользователя в Openstack Swift (–os-username), а вторая часть представляет собой имя арендатора (–os-tenant-name) в Openstack Swift (например, 1011131.1011131).

В соответствии с требованиями архитектуры службы Object Storage (swift) ваше имя пользователя FTP содержит две части аутентификации, разделенные точкой (.).

В приведенном примере имя пользователя Openstack Swift (–os-username) – 1011131.


--os-tenant-name

– вторая часть вашего имени пользователя FTP (–os-tenant-name).

В приведенном примере имя клиента Openstack Swift (–os-tenant-name) – 1011131


--os-password

пароль к FTP, который можно получить на панели управления Universal CDN (Universal CDN Control Panel).


--os-auth-url

– URL-адрес авторизации Swift.


Ниже приведены URL-адреса авторизации, которые следует использовать:


https://auth.files.nl01.cloud.servers.com:5000/v3 --auth-version 3
– для подключения к вашему европейскому контейнеру.


https://auth.files.us01.cloud.servers.com:5000/v3 --auth-version 3
– для подключения к вашему североамериканскому контейнеру.


Наша служба FTP/SFTP автоматически выполняет сегментацию для файлов большего размера.


DLO (Dynamic Large Objects – динамические большие объекты). Direct API


Сегменты и манифесты можно загружать напрямую с HTTP-запросами, вместо того, чтобы Python-swiftclient делал это. Вы можете просто загрузить сегменты, как любой другой объект, при этом манифест представляет собой просто файл с нулевым байтом (не принудительно) с дополнительным заголовком X-Object-Manifest.

Все сегменты должны находиться в одном контейнере, иметь общий префикс имени объекта и быть сортированы в том порядке, в котором они должны быть объединены. Имена объектов лексикографически сортируются как строки байтов UTF-8. Они не обязательно должны находиться в том же контейнере, что и файл манифеста, что актуально для поддержания чистоты списков контейнеров, как описано выше, с Python-swiftclient.

Файл манифеста – это просто файл с нулевым байтом (не принудительно) с дополнительным заголовком X-Object-Manifest: <container>/<prefix>, где <container> – это контейнер, в котором находятся сегменты объекта, а <prefix> – это общий префикс для всех сегментов.

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


Просмотрите приведенный ниже пример, где файл sample.mp4 имеет размер 96 МБ (100450390 байт):


1. Разделение файла Для разделения файла на сегменты мы использовали инструмент командной строки для разделения (http://www.gnu.org/software/coreutils/split): 

split -b 30000000 sample.mp4

Поскольку размер примера составляет 100450390 байт, файл был разделен на 4 следующих сегмента:

xaa: 30000000 байт
xab: 30000000 байт
xac: 30000000 байт
xad: 10450390 байт

2. Добавление сегментов

curl -i -T xaa -X PUT -H "X-Auth-Token: 1op7ca65a00b4bar94ff9a4cc577f67b" https://storage.files.nl01.cloud.servers.com:8080/v1/SERVERSCOM_36c657231f83401ebc46e770e0cd449h/container_name/directory_name/xaa


Где:

xaa – это имя первого сегмента.

/container_name/directory_name/xaa – это путь URI вместе с именем первого сегмента. В приведенном выше примере сегмент загружается в отдельный каталог с именем directory_name в основном контейнере с именем container_name.

Чтобы узнать, как получить X-Auth-Token и URL авторизации (например, https://storage.files.nl01.cloud.servers.com:8080/v1/SERVERSCOM_36c657231f83401ebc46e770e0cd449h) для вашего контейнера хранилища, перейдите по адресу Как получить X-Auth-Token в Identity API v3?

Та же схема была использована для загрузки остальных сегментов – xab, xac, xad.


Чтобы подтвердить, что все четыре сегмента были загружены в указанный контейнер, мы использовали следующую swift-команду:

swift list container_name --verbose --os-username 1011131 --os-tenant-name 1011131 --os-password MHwfJMGbmyqabFau  --os-auth-url https://auth.files.nl01.cloud.servers.com:5000/v3 --auth-version 3

Выход:

directory_name
directory_name/xaa
directory_name/xab
directory_name/xac
directory_name/xad

Более подробную информацию о swift-командах вы можете найти здесь:

Загрузка с использованием Python-Swiftclient


3. Создание файла манифеста Он должен быть с нулевым байтом (не принудительно) с дополнительным заголовком X-Object-Manifest: <container>/<prefix>, где <container> – это контейнер, в котором находятся сегменты объекта, а <prefix> – это общий префикс для всех сегментов.

curl -i -XPUT -H "Content-Length: 0" -H "X-Auth-Token: 1op7ca65a00b4bar94ff9a4cc577f67b" -H "X-Object-Manifest: container_name/example_dirictory" https://storage.files.nl01.cloud.servers.com:8080/v1/SERVERSCOM_36c657231f83401ebc46e770e0cd449h/container_name/sample.mp4

Обратите внимание, что путь в дополнительном заголовке X-Object-Manifest должен указывать расположение загруженных сегментов (-H “X-Object-Manifest: container_name/example_dirictory” ).

Чтобы подтвердить, что файл манифеста был добавлен в указанный контейнер, мы использовали следующую swift-команду:

swift list container_name --verbose --os-username 1011131 --os-tenant-name 1011131 --os-password MHwfJMGbmyqabFau  --os-auth-url https://auth.files.nl01.cloud.servers.com:5000/v3 --auth-version 3

Выход:

sample.mp4     
example_dirictory       
example_dirictory/xaa    
example_dirictory/xab   
example_dirictory/xac   
example_dirictory/xad

где sample.mp4 – это файл манифеста, example_dirictory – это директория, в которую были добавлены сегменты. 

В приведенном выше примере мы добавили сегменты файла sample.mp4 в example_dirictory, но манифест был добавлен в container_name. 

Все сегменты должны находиться в одном контейнере хранилища, иметь общий префикс имени объекта и быть сортированы в том порядке, в котором они должны быть объединены. Имена объектов лексикографически сортируются как строки байтов UTF-8. Они не обязательно должны находиться в том же контейнере, что и файл манифеста, что актуально для поддержания чистоты списков контейнеров, как описано выше, с swift.


Static Large Object (SLO) – статический большой объект 

Эта функция очень похожа на поддержку Dynamic Large Object (DLO) в том, что она позволяет пользователю добавлять множество объектов одновременно, а затем загружать их как один объект. Она отличается тем, что для этого она не полагается на согласованные в конечном итоге списки контейнеров. Вместо этого используется определяемый пользователем манифест сегментов объекта.


Добавление манифеста

После того, как пользователь добавил объединяемые объекты, загружается манифест. Запрос должен представлять собой PUT с параметром запроса:

Тело этого запроса будет упорядоченным списком описаний сегментов в формате JSON. Для каждого сегмента предоставляются следующие данные:

КлючОписание
pathпуть к объекту сегмента (не включая аккаунт) /container/object_nam
etag(необязательно) ETag, возвращаемый, когда объект сегмента представлял собой PUТ
size_bytes(необязательно) размер всего объекта сегмента в байтах
range(необязательно) диапазон (включительно) внутри объекта для использования в качестве сегмента. Если не указан, используется весь объект.

Формат списка будет следующим:

[{"path": "/cont/object",
  "etag": "etagoftheobjectsegment",
  "size_bytes": 10485760,
  "range": "1048576-2097151"}, ...]

Просмотрите приведенный ниже пример, где файл sample.mp4 был разделен и добавлен в ту же директорию /container_name/directory_name/


1. Добавление сегментов

curl -i -T xaa -X PUT -H "X-Auth-Token: 1op7ca65a00b4bar94ff9a4cc577f67b" https://storage.files.nl01.cloud.servers.com:8080/v1/SERVERSCOM_36c657231f83401ebc46e770e0cd449h/container_name/directory_name/xaa

Та же схема была использована для загрузки остальных сегментов – xab, xac, xad. 

Чтобы подтвердить, что все четыре сегмента были загружены в указанный контейнер, мы использовали следующую swift-команду:

swift list container_name --verbose --os-username 1011131 --os-tenant-name 1011131 --os-password MHwfJMGbmyqabFau  --os-auth-url https://auth.files.nl01.cloud.servers.com:5000/v3 --auth-version 3

Выход:

directory_name
directory_name/xaa
directory_name/xab
directory_name/xac
directory_name/xad

2. Создание файлф манифеста (sample.mp4) с содержимым:

[
{ 
"path": "container_name/directory_name/xaa" 
}, 
{ 
"path": "container_name/directory_name/xab" 
}, 
{ 
"path": "container_name/directory_name/xac" 
},
{ 
"path": "container_name/directory_name/xad" 
}
]

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


3. Добавление файлф манифеста SLO.

curl -i -T manifest.mp4 -XPUT -H "X-Auth-Token: 1op7ca65a00b4bar94ff9a4cc577f67b" "https://storage.files.nl01.cloud.servers.com:8080/v1/SERVERSCOM_36c657231f83401ebc46e770e0cd449h/container_name/sample.mp4?multipart-manifest=put&heartbeat=on"

Пример выхода:

HTTP/1.1 100 Continue
HTTP/1.1 202 Accepted
Content-Type: text/plain
X-Trans-Id: tx0243b9c72be64698b1728-00613f60db
X-Openstack-Request-Id: tx0243b9c72be64698b1728-00613f60db
Date: Mon, 13 Sep 2021 14:31:55 GMT
Transfer-Encoding: chunked
Etag: "d5b93f74bffb6c2e001703d84fd58ffd"
Last Modified: Mon, 13 Sep 2021 14:31:56 GMT
Response Body:
Response Status: 201 Created
Errors:

Чтобы загрузить сгенерированный файл манифеста с наших серверов хранилища объектов, используйте следующую команду:

curl --output sample.txt -H "X-Auth-Token: 1op7ca65a00b4bar94ff9a4cc577f67b" https://storage.files.nl01.cloud.servers.com:8080/v1/SERVERSCOM_36c657231f83401ebc46e770e0cd449h/container_name/sample.mp4?multipart-manifest=get

Пример выхода:

% Total     % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   788  100   788    0     0   1819      0 --:--:-- --:--:-- --:--:--  1815

Чтобы распечатать содержимое сгенерированного файла манифеста с наших серверов хранилища объектов, мы использовали cat и передачу стандартного вывода в jq (процессор JSON командной строки – https://stedolan.github.io/jq/).

cat sample.txt | jq
[
  {
    "hash": "e746e11a6eac1acd797e55dd757fcd8a",
    "last_modified": "2021-09-13T13:03:11.000000",
    "bytes": 30000000,
    "name": "/container_name/directory_name/xaa",
    "content_type": "application/octet-stream"
  },
  {
    "hash": "beb2380ea9e1289bf5caa2767dfcebb9",
    "last_modified": "2021-09-13T13:03:31.000000",
    "bytes": 30000000,
    "name": "/container_name/directory_name/xab",
    "content_type": "application/octet-stream"
  },
  {
    "hash": "f321f53cea68cf5d17913bceb444d009",
    "last_modified": "2021-09-13T13:04:22.000000",
    "bytes": 30000000,
    "name": "/container_name/directory_name/xac",
    "content_type": "application/octet-stream"
  },
  {
    "hash": "90c45fe87cb74a28ec40a704e8995fe9",
    "last_modified": "2021-09-13T13:04:40.000000",
    "bytes": 10450390,
    "name": "/container_name/directory_name/xad",
    "content_type": "application/octet-stream"
  }
]


Для дополнительной информации о OpenStack Large Object Support (DLO/SLO) перейдите по ссылке:

https://docs.openstack.org/swift/latest/api/large_objects.html

https://docs.openstack.org/swift/latest/overview_large_objects.html



Загрузка файлов по FTP

Загрузка с использованием Python-Swiftclient

Загрузка файлов с помощью OpenStack Swift API

Загрузка файлов с помощью Rclone