30

Я просто переехал и обнаружил после некоторой проб и ошибок, что где-то между моим домом и моим удаленным сервером происходит некоторое регулирование ... но регулирование не очень разумно. Это только душит отдельные связи. Поэтому, если я скопирую один файл размером 1 ГБ, он будет работать со скоростью 150 кбит / с. Но если я инициализирую 10 копий, каждая из них будет работать со скоростью 150 кбит / с (т. Е. Я получаю гораздо более высокую совокупную пропускную способность по нескольким соединениям).

Я использую rsync довольно часто для синхронизации некоторых больших наборов данных с работы на дом (к счастью, в виде множества файлов). Есть ли способ сообщить rsync о загрузке, используя несколько соединений? Теоретически это должно быть возможно, поскольку, насколько я могу судить, rsync сначала делает проход, чтобы определить необходимые изменения, а затем выполняет фактическую передачу. Бонусные баллы, если есть волшебный способ сказать rsync нарезать отдельные файлы на N частей, а затем соединить их вместе. Я считаю, что CuteFTP на самом деле достаточно умен, чтобы справиться с этим.

9 ответов9

13

У меня просто была похожая проблема, связанная с переносом нескольких ТБ с одного NAS на другой NAS без возможности резервного копирования / восстановления, которая позволила бы мне просто передать 1 набор другому.

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

Он также определяет, сколько Rsync нужно запустить, основываясь на количестве процессоров, но вы можете настроить это.

Другой возможный вариант: запустить rsync в режиме --list-only.

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

#! /bin/bash
SRC_DIR=$1
DEST_DIR=$2
LIST=$3
CPU_CNT=`cat /proc/cpuinfo|grep processor |wc -l`
#  pseudo random heuristic
let JOB_CNT=CPU_CNT*4
[ -z "$LIST" ] && LIST="-tPavW --exclude .snapshot --exclude hourly.?"
echo "rsyncing From=$SRC_DIR To=$DEST_DIR DIR_LIST=$LIST"
mkdir -p /{OLD,NEW}_NAS/home
[ -z "$RSYNC_OPTS" ] && RSYNC_OPTS="-tPavW --delete-during --exclude .snapshot --exclude hourly.?"
cd $SRC_DIR
echo $LIST|xargs -n1 echo|xargs -n1 -P $JOB_CNT -I% rsync ${RSYNC_OPTS} ${SRC_DIR}/%/ ${DEST_DIR}/%/
7

У GNU Parallel есть решение

Я переместил 15 ТБ через 1 Гбит / с, и это может насытить канал 1 Гбит / с.

Следующее запустит один rsync для большого файла в src-dir для dest-dir на сервере fooserver:

cd src-dir; find . -type f -size +100000 | \
parallel -v ssh fooserver mkdir -p /dest-dir/{//}\; \
  rsync -s -Havessh {} fooserver:/dest-dir/{}

Созданные каталоги могут иметь неправильные разрешения, а файлы меньшего размера не передаются. Чтобы исправить это, запустите rsync в последний раз:

rsync -Havessh src-dir/ fooserver:/dest-dir/
3

Да. Такая особенность существует.

Существует утилита pssh, которая обеспечивает описанную функциональность.

Этот пакет предоставляет параллельные версии инструментов openssh. Включено в дистрибутив:

  • Параллельный ssh (pssh)
  • Параллельный scp (pscp)
  • Параллельный rsync (prsync)
  • Параллельная нукэ (pnuke)
  • Параллельный хлеб (пслурп)

Я не уверен, насколько это легко настроить, но это может помочь!

3

Я не могу комментировать, поэтому я добавил новый ответ с немного лучшим кодом, чем предыдущий (хороший и умный) код.

Проверьте строку rsync , поскольку она содержит опциональную настройку ionice .

#!/bin/bash
start_time=$(date +%s.%N)
# Transfer files in parallel using rsync (simple script)
# MAXCONN: maximum number "rsync" processes running at the same time:
MAXCONN=6
# Source and destination base paths. (not need to end with "/")
SRC_BASE=/home/user/public_html/images
DST_BASE=user@hostname.domain.local:/home/user/public_html/images
RSYNC_OPTS="-ah --partial"
# Main loop:
for FULLDIR in $SRC_BASE/*; do
    NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
    while [ $NUMRSYNC -ge $MAXCONN ]; do
        NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
        sleep 1
    done
    DIR=`basename $FULLDIR`
    echo "Start: " $DIR
    ionice -c2 -n5 rsync $RSYNC_OPTS $SRC_BASE/${DIR}/ $DST_BASE/${DIR}/ &
    # rsync $RSYNC_OPTS $SRC_BASE/${DIR}/ $DST_BASE/${DIR}/ &
    sleep 5
done

execution_time=$(echo "$(date +%s.%N) - $start" | bc)
printf "Done. Execution time: %.6f seconds\n" $execution_time
2

Похоже, кто-то написал эту утилиту для вас. Это разбивает передачу на параллельные куски. Это лучшая реализация, чем версия "параллельного большого файла", перечисленная в разделе GNU Parallel:

https://gist.github.com/rcoup/5358786

Кроме того, lftp может распараллеливать передачу файлов через ftp, ftps, http, https, hftp, fish, sftp. Часто есть некоторые преимущества использования lftp, потому что управление разрешениями, ограниченным доступом и т.д. Для rsync может быть сложной задачей.

1

Нет, такой функции не существует. Вы можете разделить синхронизацию на несколько вызовов rsync если действительно хотите.

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

1

Я хотел перенести несколько каталогов (со многими файлами) одновременно, поэтому я создал этот небольшой скрипт:

#!/bin/bash
# Transfer files in parallel using rsync (simple script)
# MAXCONN: maximum number "rsync" processes running at the same time:
MAXCONN=10
# Source and destination base paths. (not need to end with "/")
SRC_BASE=/home/sites
DST_BASE=user@example.com:/var/www
RSYNC_OPTS="--stats -ilrtpog"
# Main loop:
for FULLDIR in $SRC_BASE/*/; do
    NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
    while [ $NUMRSYNC -ge $MAXCONN ]; do
        NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
        sleep 10
    done
    DIR=`basename $FULLDIR`
    rsync $RSYNC_OPTS $SRC_BASE/${DIR}/ $DST_BASE/${DIR}/ & 
    sleep 1 
done
echo "Done."

Я сделал этот скрипт довольно быстро, поэтому, пожалуйста, пересмотрите его и протестируйте перед использованием в производственной среде.

0

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

#!/bin/sh

dest="$1"
shift

if [ "$dest" = "" ]; then
    echo "USAGE: $0 TARGET:/foo/bar <dir1> [dir2] [dir3]"
    exit 1
fi

RCol='\x1B[0m' # Text Reset
BYel='\x1B[1;33m';

for i in "$@"; do
    prefix=`printf "$BYel%50s:$RCol" "$i"`
    echo "$prefix * Starting $i"
    echo "$prefix -> syncing '$i/' to '$dest/$i/'"
    (rsync -rv "$i/" "$dest/$i/") 2>&1 | sed "s/^/$prefix /g" &
    sleep 0.5
done

echo "* Waiting for all to complete"
wait

Он добавляет префикс имени папки в желтом цвете ко всем выводам консоли rsync, чтобы он выглядел красиво.

-1

Aria2 - это хорошая клиентская программа для загрузки данных с использованием множества соединений с множества зеркал. Он не поддерживает SFTP. Итак, я установил FTP-сервер - vsftpd. Мое 3g соединение работает на полную мощность с 5 подключениями к FTP-серверу.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .