Перемещение данных в кластер vFXT — параллельная загрузка данных

После создания нового кластера vFXT ваша первая задача — переместить данные в новый том хранилища в Azure. Однако если обычный метод перемещения данных выдает простую команду копирования из одного клиента, скорее всего, вы увидите низкую производительность копирования. Однопоточное копирование не является хорошим вариантом для копирования данных в серверное хранилище кластера Avere vFXT.

Так как кластер Avere vFXT для Azure — это масштабируемый многопользовательский кэш, самый быстрый и эффективный способ копирования данных в него с несколькими клиентами. Этот метод параллелизирует прием файлов и объектов.

Схема многопоточного перемещения данных с несколькими клиентами: в левом верхнем углу значок для локального аппаратного обеспечения имеет несколько стрелок, исходящих из него. Стрелки указывают на четыре клиентских компьютера. От каждого клиентского компьютера три стрелки указывают на Avere vFXT. Из Avere vFXT несколько стрелок указывают на хранилище Blob.

cp Командыcopy, которые обычно используются для передачи данных из одной системы хранения в другую, являются однопоточными процессами, которые копируют только один файл одновременно. Это означает, что файловый сервер получает только один файл за раз — это отходы ресурсов кластера.

В этой статье описываются стратегии создания многопользовательской многопоточной системы копирования файлов для перемещения данных в кластер Avere vFXT. В нем описываются понятия передачи файлов и точки принятия решений, которые можно использовать для эффективного копирования данных с помощью нескольких клиентов и простых команд копирования.

Он также объясняет некоторые служебные программы, которые могут помочь. Служебную msrsync программу можно использовать для частичной автоматизации процесса разделения набора данных на контейнеры и использования rsync команд. Скрипт parallelcp — это другая программа, которая считывает исходный каталог и выдает команды копирования автоматически. Кроме того, средство rsync можно использовать на двух этапах, чтобы обеспечить быструю копию, которая по-прежнему обеспечивает согласованность данных.

Щелкните ссылку, чтобы перейти к разделу:

Шаблон виртуальной машины для обработки данных

Шаблон Resource Manager доступен на сайте GitHub для автоматического создания виртуальной машины с инструментами параллельного приема данных, упомянутыми в этой статье.

схема, на которой показаны несколько стрелок, ведущих из BLOB-хранилища, аппаратного хранилища и источников файлов Azure. Эти стрелки указывают на

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

Стратегическое планирование

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

  • Если файлы малы, то метрика интереса — это файлы в секунду.
  • Если файлы большие (10MiBi или больше), метрика интереса составляет байт в секунду.

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

Пример копирования вручную

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

Команда Linux/UNIX cp включает аргумент -p для сохранения владения и метаданных mtime. Добавление этого аргумента в приведенные ниже команды является необязательным. (Добавление аргумента увеличивает количество вызовов файловой системы, отправленных от клиента в целевую файловую систему для изменения метаданных.)

В этом простом примере два файла копируются параллельно:

cp /mnt/source/file1 /mnt/destination1/ & cp /mnt/source/file2 /mnt/destination1/ &

После выдачи этой команды jobs команда покажет, что выполняются два потока.

Прогнозируемая структура имени файла

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

Например, если ваш каталог содержит 1000 файлов, которые нумерованы последовательно от 0001 до 1000, можно использовать следующие выражения для создания десяти параллельных потоков, каждый из которых копирует по 100 файлов.

cp /mnt/source/file0* /mnt/destination1/ & \
cp /mnt/source/file1* /mnt/destination1/ & \
cp /mnt/source/file2* /mnt/destination1/ & \
cp /mnt/source/file3* /mnt/destination1/ & \
cp /mnt/source/file4* /mnt/destination1/ & \
cp /mnt/source/file5* /mnt/destination1/ & \
cp /mnt/source/file6* /mnt/destination1/ & \
cp /mnt/source/file7* /mnt/destination1/ & \
cp /mnt/source/file8* /mnt/destination1/ & \
cp /mnt/source/file9* /mnt/destination1/

Неизвестная структура имени файла

Если структура именования файлов не предсказуема, можно группировать файлы по именам каталогов.

В этом примере собираются все каталоги для отправки в команды cp, выполняемые как фоновые задачи.

/root
|-/dir1
| |-/dir1a
| |-/dir1b
| |-/dir1c
   |-/dir1c1
|-/dir1d

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

cp /mnt/source/* /mnt/destination/
mkdir -p /mnt/destination/dir1 && cp /mnt/source/dir1/* mnt/destination/dir1/ &
cp -R /mnt/source/dir1/dir1a /mnt/destination/dir1/ &
cp -R /mnt/source/dir1/dir1b /mnt/destination/dir1/ &
cp -R /mnt/source/dir1/dir1c /mnt/destination/dir1/ & # this command copies dir1c1 via recursion
cp -R /mnt/source/dir1/dir1d /mnt/destination/dir1/ &

Когда добавлять точки подключения

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

В этом случае можно добавить точки подключения на стороне клиента к другим IP-адресам кластера vFXT, используя тот же путь подключения к удаленной файловой системе:

10.1.0.100:/nfs on /mnt/sourcetype nfs (rw,vers=3,proto=tcp,addr=10.1.0.100)
10.1.1.101:/nfs on /mnt/destination1type nfs (rw,vers=3,proto=tcp,addr=10.1.1.101)
10.1.1.102:/nfs on /mnt/destination2type nfs (rw,vers=3,proto=tcp,addr=10.1.1.102)
10.1.1.103:/nfs on /mnt/destination3type nfs (rw,vers=3,proto=tcp,addr=10.1.1.103)

Добавление точек монтирования на стороне клиента позволяет выполнять дополнительные команды копирования в эти дополнительные /mnt/destination[1-3] точки монтирования, что способствует дальнейшему параллелизму.

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

cp /mnt/source/file0* /mnt/destination1/ & \
cp /mnt/source/file1* /mnt/destination2/ & \
cp /mnt/source/file2* /mnt/destination3/ & \
cp /mnt/source/file3* /mnt/destination1/ & \
cp /mnt/source/file4* /mnt/destination2/ & \
cp /mnt/source/file5* /mnt/destination3/ & \
cp /mnt/source/file6* /mnt/destination1/ & \
cp /mnt/source/file7* /mnt/destination2/ & \
cp /mnt/source/file8* /mnt/destination3/ & \

В приведенном выше примере все три конечных точки подключения ориентированы на процессы копирования файлов клиента.

Когда добавлять клиентов

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

Пример:

Client1: cp -R /mnt/source/dir1/dir1a /mnt/destination/dir1/ &
Client1: cp -R /mnt/source/dir2/dir2a /mnt/destination/dir2/ &
Client1: cp -R /mnt/source/dir3/dir3a /mnt/destination/dir3/ &

Client2: cp -R /mnt/source/dir1/dir1b /mnt/destination/dir1/ &
Client2: cp -R /mnt/source/dir2/dir2b /mnt/destination/dir2/ &
Client2: cp -R /mnt/source/dir3/dir3b /mnt/destination/dir3/ &

Client3: cp -R /mnt/source/dir1/dir1c /mnt/destination/dir1/ &
Client3: cp -R /mnt/source/dir2/dir2c /mnt/destination/dir2/ &
Client3: cp -R /mnt/source/dir3/dir3c /mnt/destination/dir3/ &

Client4: cp -R /mnt/source/dir1/dir1d /mnt/destination/dir1/ &
Client4: cp -R /mnt/source/dir2/dir2d /mnt/destination/dir2/ &
Client4: cp -R /mnt/source/dir3/dir3d /mnt/destination/dir3/ &

Создание манифестов файлов

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

В этом сценарии используется команда UNIX find для создания манифестов файлов или каталогов:

user@build:/mnt/source > find . -mindepth 4 -maxdepth 4 -type d
./atj5b55c53be6-01/support/gsi/2018-07-22T21:12:06EDT
./atj5b55c53be6-01/support/pcap/2018-07-23T01:34:57UTC
./atj5b55c53be6-01/support/trace/rolling
./atj5b55c53be6-03/support/gsi/2018-07-22T21:12:06EDT
./atj5b55c53be6-03/support/pcap/2018-07-23T01:34:57UTC
./atj5b55c53be6-03/support/trace/rolling
./atj5b55c53be6-02/support/gsi/2018-07-22T21:12:06EDT
./atj5b55c53be6-02/support/pcap/2018-07-23T01:34:57UTC
./atj5b55c53be6-02/support/trace/rolling

Перенаправьте этот результат в файл: find . -mindepth 4 -maxdepth 4 -type d > /tmp/foo

Затем можно выполнить итерацию манифеста с помощью команд BASH для подсчета файлов и определения размеров подкаталогов:

ben@xlcycl1:/sps/internal/atj5b5ab44b7f > for i in $(cat /tmp/foo); do echo " `find ${i} |wc -l` `du -sh ${i}`"; done
244    3.5M    ./atj5b5ab44b7f-02/support/gsi/2018-07-18T00:07:03EDT
9      172K    ./atj5b5ab44b7f-02/support/gsi/stats_2018-07-18T05:01:00UTC
124    5.8M    ./atj5b5ab44b7f-02/support/gsi/stats_2018-07-19T01:01:01UTC
152    15M     ./atj5b5ab44b7f-02/support/gsi/stats_2018-07-20T01:01:00UTC
131    13M     ./atj5b5ab44b7f-02/support/gsi/stats_2018-07-20T21:59:41UTC_partial
789    6.2M    ./atj5b5ab44b7f-02/support/gsi/2018-07-20T21:59:41UTC
134    12M     ./atj5b5ab44b7f-02/support/gsi/stats_2018-07-20T22:22:55UTC_vfxt_catchup
7      16K     ./atj5b5ab44b7f-02/support/pcap/2018-07-18T17:12:19UTC
8      83K     ./atj5b5ab44b7f-02/support/pcap/2018-07-18T17:17:17UTC
575    7.7M    ./atj5b5ab44b7f-02/support/cores/armada_main.2000.1531980253.gsi
33     4.4G    ./atj5b5ab44b7f-02/support/trace/rolling
281    6.6M    ./atj5b5ab44b7f-01/support/gsi/2018-07-18T00:07:03EDT
15     182K    ./atj5b5ab44b7f-01/support/gsi/stats_2018-07-18T05:01:00UTC
244    17M     ./atj5b5ab44b7f-01/support/gsi/stats_2018-07-19T01:01:01UTC
299    31M     ./atj5b5ab44b7f-01/support/gsi/stats_2018-07-20T01:01:00UTC
256    29M     ./atj5b5ab44b7f-01/support/gsi/stats_2018-07-20T21:59:41UTC_partial
889    7.7M    ./atj5b5ab44b7f-01/support/gsi/2018-07-20T21:59:41UTC
262    29M     ./atj5b5ab44b7f-01/support/gsi/stats_2018-07-20T22:22:55UTC_vfxt_catchup
11     248K    ./atj5b5ab44b7f-01/support/pcap/2018-07-18T17:12:19UTC
11     88K     ./atj5b5ab44b7f-01/support/pcap/2018-07-18T17:17:17UTC
645    11M     ./atj5b5ab44b7f-01/support/cores/armada_main.2019.1531980253.gsi
33     4.0G    ./atj5b5ab44b7f-01/support/trace/rolling
244    2.1M    ./atj5b5ab44b7f-03/support/gsi/2018-07-18T00:07:03EDT
9      158K    ./atj5b5ab44b7f-03/support/gsi/stats_2018-07-18T05:01:00UTC
124    5.3M    ./atj5b5ab44b7f-03/support/gsi/stats_2018-07-19T01:01:01UTC
152    15M     ./atj5b5ab44b7f-03/support/gsi/stats_2018-07-20T01:01:00UTC
131    12M     ./atj5b5ab44b7f-03/support/gsi/stats_2018-07-20T21:59:41UTC_partial
789    8.4M    ./atj5b5ab44b7f-03/support/gsi/2018-07-20T21:59:41UTC
134    14M     ./atj5b5ab44b7f-03/support/gsi/stats_2018-07-20T22:25:58UTC_vfxt_catchup
7      159K    ./atj5b5ab44b7f-03/support/pcap/2018-07-18T17:12:19UTC
7      157K    ./atj5b5ab44b7f-03/support/pcap/2018-07-18T17:17:17UTC
576    12M     ./atj5b5ab44b7f-03/support/cores/armada_main.2013.1531980253.gsi
33     2.8G    ./atj5b5ab44b7f-03/support/trace/rolling

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

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

for i in 1 2 3 4 ; do sed -n ${i}~4p /tmp/foo > /tmp/client${i}; done

Если у вас есть пять клиентов, используйте следующее:

for i in 1 2 3 4 5; do sed -n ${i}~5p /tmp/foo > /tmp/client${i}; done

И для шести.... Экстраполируйте по мере необходимости.

for i in 1 2 3 4 5 6; do sed -n ${i}~6p /tmp/foo > /tmp/client${i}; done

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

Используйте каждый файл для создания команды копирования:

for i in 1 2 3 4 5 6; do for j in $(cat /tmp/client${i}); do echo "cp -p -R /mnt/source/${j} /mnt/destination/${j}" >> /tmp/client${i}_copy_commands ; done; done

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

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

Использование двухфазного процесса rsync

Стандартная rsync служебная программа не работает хорошо для заполнения облачного хранилища с помощью Avere vFXT для системы Azure, так как она создает большое количество операций создания и переименования файлов для обеспечения целостности данных. Однако вы можете безопасно использовать --inplace с rsync, чтобы пропустить более тщательную процедуру копирования, если затем выполните второй запуск для проверки целостности файлов.

Стандартная rsync операция копирования создает временный файл и заполняет его данными. Если передача данных завершена успешно, временный файл переименован в исходное имя файла. Этот метод гарантирует согласованность даже при доступе к файлам во время копирования. Но этот метод создает больше операций записи, что замедляет перемещение файлов через кэш.

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

Вторая rsync операция служит проверкой согласованности первой операции. Так как файлы уже скопированы, второй этап — это быстрая проверка, чтобы убедиться, что файлы в целевом расположении соответствуют файлам источника. Если какие-либо файлы не совпадают, они повторно используются.

Вы можете выполнить оба этапа вместе в одной команде.

rsync -azh --inplace <source> <destination> && rsync -azh <source> <destination>

Этот метод — это простой и эффективный метод для наборов данных до количества файлов, которые может обрабатывать внутренний диспетчер каталогов. (Обычно это 200 миллионов файлов для 3-узлового кластера, 500 миллионов файлов для кластера шести узлов и т. д.)

Использование служебной программы msrsync

Инструмент msrsync также можно использовать для переноса данных на базовый сервер хранения для кластера Avere. Это средство предназначено для оптимизации использования пропускной способности путем выполнения нескольких параллельных rsync процессов. Он доступен на сайте GitHub https://github.com/jbd/msrsync.

msrsync разбивает исходный каталог на отдельные "контейнеры", а затем выполняет отдельные rsync процессы в каждом контейнере.

Предварительное тестирование с помощью четырехядерных виртуальных машин показало лучшую эффективность при использовании 64 процессов. msrsync Используйте параметр-p, чтобы задать число процессов 64.

Аргумент --inplace также можно использовать с командами msrsync. Если этот параметр используется, попробуйте выполнить вторую команду (как и rsync, описанную выше), чтобы обеспечить целостность данных.

msrsync может записывать только на локальные тома и с них. Источник и назначение должны быть доступны как локальные подключения в виртуальной сети кластера.

msrsync Чтобы заполнить том облака Azure кластером Avere, выполните следующие инструкции:

  1. Установка msrsync и необходимые компоненты (rsync и Python 2.6 или более поздней версии)

  2. Определите общее количество файлов и каталогов для копирования.

    Например, используйте служебную программу Avere prime.py с аргументами prime.py --directory /path/to/some/directory (доступно по URL-адресу для скачивания https://github.com/Azure/Avere/blob/master/src/clientapps/dataingestor/prime.py).

    Если вы не используете prime.py, вы можете рассчитать количество элементов с помощью средства GNU find следующим образом:

    find <path> -type f |wc -l         # (counts files)
    find <path> -type d |wc -l         # (counts directories)
    find <path> |wc -l                 # (counts both)
    
  3. Разделите количество элементов на 64, чтобы определить количество элементов на каждый процесс. Используйте это число с параметром -f , чтобы задать размер контейнеров при выполнении команды.

  4. msrsync Выполните команду для копирования файлов:

    msrsync -P --stats -p 64 -f <ITEMS_DIV_64> --rsync "-ahv" <SOURCE_PATH> <DESTINATION_PATH>
    

    При использовании --inplaceдобавьте второе выполнение без параметра, чтобы проверить правильность копирования данных:

    msrsync -P --stats -p 64 -f <ITEMS_DIV_64> --rsync "-ahv --inplace" <SOURCE_PATH> <DESTINATION_PATH> && msrsync -P --stats -p 64 -f <ITEMS_DIV_64> --rsync "-ahv" <SOURCE_PATH> <DESTINATION_PATH>
    

    Например, эта команда предназначена для перемещения 11 000 файлов в 64 процессах из /test/source-репозитория в /mnt/vfxt/репозиторий:

    msrsync -P --stats -p 64 -f 170 --rsync "-ahv --inplace" /test/source-repository/ /mnt/vfxt/repository && msrsync -P --stats -p 64 -f 170 --rsync "-ahv --inplace" /test/source-repository/ /mnt/vfxt/repository

Использование скрипта параллельного копирования

Скрипт parallelcp также может быть полезен для перемещения данных в серверное хранилище кластера vFXT.

Приведенный ниже скрипт добавит исполняемый файл parallelcp. (Этот скрипт предназначен для Ubuntu; при использовании другого дистрибутива необходимо установить parallel отдельно.)

sudo touch /usr/bin/parallelcp && sudo chmod 755 /usr/bin/parallelcp && sudo sh -c "/bin/cat >/usr/bin/parallelcp" <<EOM
#!/bin/bash

display_usage() {
    echo -e "\nUsage: \$0 SOURCE_DIR DEST_DIR\n"
}

if [  \$# -le 1 ] ; then
    display_usage
    exit 1
fi

if [[ ( \$# == "--help") ||  \$# == "-h" ]] ; then
    display_usage
    exit 0
fi

SOURCE_DIR="\$1"
DEST_DIR="\$2"

if [ ! -d "\$SOURCE_DIR" ] ; then
    echo "Source directory \$SOURCE_DIR does not exist, or is not a directory"
    display_usage
    exit 2
fi

if [ ! -d "\$DEST_DIR" ] && ! mkdir -p \$DEST_DIR ; then
    echo "Destination directory \$DEST_DIR does not exist, or is not a directory"
    display_usage
    exit 2
fi

if [ ! -w "\$DEST_DIR" ] ; then
    echo "Destination directory \$DEST_DIR is not writeable, or is not a directory"
    display_usage
    exit 3
fi

if ! which parallel > /dev/null ; then
    sudo apt-get update && sudo apt install -y parallel
fi

DIRJOBS=225
JOBS=225
find \$SOURCE_DIR -mindepth 1 -type d -print0 | sed -z "s/\$SOURCE_DIR\///" | parallel --will-cite -j\$DIRJOBS -0 "mkdir -p \$DEST_DIR/{}"
find \$SOURCE_DIR -mindepth 1 ! -type d -print0 | sed -z "s/\$SOURCE_DIR\///" | parallel --will-cite -j\$JOBS -0 "cp -P \$SOURCE_DIR/{} \$DEST_DIR/{}"
EOM

Пример параллельного копирования

В этом примере используется сценарий параллельного копирования для компиляции glibc с использованием исходных файлов из кластера Avere.

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

Этот скрипт использует приведенный выше сценарий параллельного копирования. Этот параметр -j используется вместе с parallelcp и make для достижения параллелизации.

sudo apt-get update
sudo apt install -y gcc bison gcc binutils make parallel
cd
wget https://mirrors.kernel.org/gnu/libc/glibc-2.27.tar.bz2
tar jxf glibc-2.27.tar.bz2
ln -s /nfs/node1 avere
time parallelcp glibc-2.27 avere/glibc-2.27
cd
mkdir obj
mkdir usr
cd obj
/home/azureuser/avere/glibc-2.27/configure --prefix=/home/azureuser/usr
time make -j