Переместить миллионы файлов в корень S3 - PullRequest
0 голосов
/ 03 сентября 2018

У меня 20 миллионов локальных файлов. Каждый файл представлен числовым идентификатором, который хэшируется.

Файл 1 называется 356a192b7913b04c54574d18c28d46e6395428ab (sha1 из "1")

Файл 2 имеет имя da4b9237bacccdf19c0760cab7aec4a8359010b0 (sha1 из "2")

и т.д.. и т.д.

Не каждое число представляет файл, но у меня есть список всех чисел, которые делают.

Файлы помещаются в папки, названные в честь первых двух символов в хэше, затем идут следующие два, а затем следующие два.

Для файла 1 (da4b9237bacccdf19c0760cab7aec4a8359010b0) структура папок

da/4b/92/

В эту папку помещается файл, который называется полным хэшем, поэтому полный путь к файлу

da/4b/92/da4b9237bacccdf19c0760cab7aec4a8359010b0

Теперь я хочу переместить все файлы из файловой системы в корзину на Amazon S3, и при этом я хочу переместить их в корень этой корзины.

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

Мой план состоит в том, чтобы создать таблицу в mysql с именем moved_files, а затем запустить скрипт PHP, который извлекает число X идентификаторов из таблицы files, и использовать AWS SDK для PHP для копирования файл на S3, если это успешно, добавить этот идентификатор в таблицу moved_files. Однако я не уверен, что это будет самый быстрый способ сделать это, может быть, мне стоит заняться написанием сценария bash с использованием AWS Cli .

Будем благодарны за любые предложения!

1 Ответ

0 голосов
/ 03 сентября 2018

Я не использую AWS S3, но небольшое прибегание к поиску подсказывает, что вам нужна команда типа:

aws s3 cp test.txt s3://mybucket/test2.txt

Итак, если вы хотите запустить это для всех ваших файлов, я бы посоветовал вам использовать GNU Parallel , чтобы полностью использовать ваше соединение и уменьшить задержки.

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

find . -type f -print0 | parallel -0 --dry-run aws s3 cp {} s3://rootbucket/{/}

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

aws s3 cp ./da/4b/92/da4b9237bacccdf19c0760cab7aec4a8359010b0 s3://rootbucket/da4b9237bacccdf19c0760cab7aec4a8359010b0
aws s3 cp ./da/4b/92/da4b9237bacccdf19c0760cab7aec4a8359010b1 s3://rootbucket/da4b9237bacccdf19c0760cab7aec4a8359010b1

Если у вас есть 8 ядер ЦП, они будут запускать 8 параллельных копий aws за один раз, пока все ваши файлы не будут скопированы.

{} расширяется до значения «текущий файл» , а {/} расширяется до значения «текущий файл без его каталога» . Вы также можете добавить --bar, чтобы получить индикатор выполнения.

Если это выглядит обнадеживающе, мы можем добавить небольшую функцию bash для каждого файла, который обновляет вашу базу данных или удаляет локальный файл, при условии успешного выполнения команды aws. Похоже на это - начните читать снизу; -)

#!/bin/bash

# bash function to upload single file
upload() {
   local="$1"                                         # Pick up parameters
   remote="$2"                                        # Pick up parameters
   echo aws s3 cp "$local" "s3://rootbucket/$remote"  # Upload to AWS
   if [ $? -eq 0 ] ; then
      : # Delete locally or update database with success
   else
      : # Log error somewhere
   fi
}

# Export the upload function so processes started by GNU Parallel can find it
export -f upload

# Run GNU Parallel on all files
find . -type f -print0 | parallel -0 upload {} {/}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...