programing

동시/동시 파일 전송 속도 향상

megabox 2023. 5. 29. 10:29
반응형

동시/동시 파일 전송 속도 향상

갈아타야 합니다15TB가능한 한 빨리 한 서버에서 다른 서버로 데이터를 전송할 수 있습니다.현재사중입니다용다중니입▁using▁currently를 사용하고 .rsync하지만 우리는 단지 대략 12시간 정도의 속도를 얻을 뿐입니다.150Mb/s우리의 네트워크가 할 수 있을 때.900+Mb/s)로 됩니다.iperf가 한 가 느려지는 디스크, 네트워크 등을 테스트한 결과 rsync가 한 번에 하나의 파일만 전송하므로 속도가 느려지는 것으로 나타났습니다.

디렉터리 트리의 각 폴더에 대해 다른 rsync를 실행하는 스크립트를 찾았지만(x 숫자로 제한할 수 있음) 작동할 수 없습니다. 여전히 한 번에 하나의 rsync만 실행됩니다.

나는 찾았습니다.script 여기(아래 참조)

디렉터리 트리는 다음과 같습니다.

/main
   - /files
      - /1
         - 343
            - 123.wav
            - 76.wav
         - 772
            - 122.wav
         - 55
            - 555.wav
            - 324.wav
            - 1209.wav
         - 43
            - 999.wav
            - 111.wav
            - 222.wav
      - /2
         - 346
            - 9993.wav
         - 4242
            - 827.wav
      - /3
         - 2545
            - 76.wav
            - 199.wav
            - 183.wav
         - 23
            - 33.wav
            - 876.wav
         - 4256
            - 998.wav
            - 1665.wav
            - 332.wav
            - 112.wav
            - 5584.wav

따라서 /main/files의 각 디렉토리에 대해 한 번에 최대 5개의 rsync를 생성합니다. 이되는데, 이 경우에는 3개의 rsync가 실행됩니다./main/files/1,/main/files/2그리고./main/files/3.

이렇게 사용해봤는데, 한 번에 1개씩만 rsync가 실행됩니다./main/files/2폴더:

#!/bin/bash

# Define source, target, maxdepth and cd to source
source="/main/files"
target="/main/filesTest"
depth=1
cd "${source}"

# Set the maximum number of concurrent rsync threads
maxthreads=5
# How long to wait before checking the number of rsync threads again
sleeptime=5

# Find all folders in the source directory within the maxdepth level
find . -maxdepth ${depth} -type d | while read dir
do
    # Make sure to ignore the parent folder
    if [ `echo "${dir}" | awk -F'/' '{print NF}'` -gt ${depth} ]
    then
        # Strip leading dot slash
        subfolder=$(echo "${dir}" | sed 's@^\./@@g')
        if [ ! -d "${target}/${subfolder}" ]
        then
            # Create destination folder and set ownership and permissions to match source
            mkdir -p "${target}/${subfolder}"
            chown --reference="${source}/${subfolder}" "${target}/${subfolder}"
            chmod --reference="${source}/${subfolder}" "${target}/${subfolder}"
        fi
        # Make sure the number of rsync threads running is below the threshold
        while [ `ps -ef | grep -c [r]sync` -gt ${maxthreads} ]
        do
            echo "Sleeping ${sleeptime} seconds"
            sleep ${sleeptime}
        done
        # Run rsync in background for the current subfolder and move one to the next one
        nohup rsync -a "${source}/${subfolder}/" "${target}/${subfolder}/" </dev/null >/dev/null 2>&1 &
    fi
done

# Find all files above the maxdepth level and rsync them as well
find . -maxdepth ${depth} -type f -print0 | rsync -a --files-from=- --from0 ./ "${target}/"

업데이트된 답변(2020년 1월)

xargs는 이제 병렬 실행을 위해 권장되는 도구입니다.거의 모든 곳에 사전 설치되어 있습니다. 개의 중실용을 rsync다음과 같은 작업을 수행합니다.

ls /srv/mail | xargs -n1 -P4 -I% rsync -Pa % myserver.com:/srv/mail/

가 나모열다니에 됩니다./srv/mail그들을 파이프로 연결합니다.xargs 4번을 합니다.rsync프로세스를 한 번에 수행합니다.%char는 각 명령 호출에 대한 입력 인수를 대체합니다.

▁using를 사용한 .parallel:

ls /srv/mail | parallel -v -j8 rsync -raz --progress {} myserver.com:/srv/mail/{}

rclone.org 을 사용해 본 적이 있습니까?

와 함께rclone당신은 다음과 같은 것을 할 수 있습니다.

rclone copy "${source}/${subfolder}/" "${target}/${subfolder}/" --progress --multi-thread-streams=N

--multi-thread-streams=N생성할 스레드 수를 나타냅니다.

rsync네트워크를 통해 최대한 빨리 파일을 전송합니다.예를 들어, 대상에 전혀 없는 하나의 큰 파일을 복사하는 데 사용해 보십시오.이 속도는 rsync가 데이터를 전송할 수 있는 최대 속도입니다. 해교보오시십의 .scp(예를 들어). rsync대상 파일이 존재하는 경우 원시 전송 속도가 더욱 느려집니다. 양쪽 모두 파일의 어떤 부분이 변경되었는지에 대해 양방향 채팅을 해야 하지만 전송할 필요가 없는 데이터를 식별하여 비용을 지불하기 때문입니다.

편한행rsync동시에 사용할 수 있습니다.아래 명령은 최대 5개까지 실행됩니다.rsync로 각각 디렉토리를 하는 것입니다.병목 현상은 네트워크가 아니라 CPU와 디스크의 속도와 병렬로 실행하는 속도 때문일 수 있습니다. 속도가 빨라지는 것이 아니라 속도가 느려질 뿐입니다.

run_rsync() {
    # e.g. copies /main/files/blah to /main/filesTest/blah
    rsync -av "$1" "/main/filesTest/${1#/main/files/}"
}
export -f run_rsync
parallel -j5 run_rsync ::: /main/files/*

사용할 수 있습니다.xargs한 번에 여러 프로세스를 실행할 수 있습니다.귀하의 경우 다음과 같습니다.

ls -1 /main/files | xargs -I {} -P 5 -n 1 rsync -avh /main/files/{} /main/filesTest/

이 작업을 수행하기 위한 여러 가지 대체 도구와 접근 방식이 웹 곳곳에 나열되어 있습니다.예:

  • NCSA 블로그에는 다음에 대한 설명이 있습니다.xargs그리고.find대부분의 *nix 시스템에 대해 새 소프트웨어를 설치할 필요 없이 병렬 동기화할 수 있습니다.

  • Parsync는 병렬 rsync를 위한 풍부한 Perl 래퍼 기능을 제공합니다.

저는 parallel_sync라는 파이썬 패키지를 개발했습니다.

https://pythonhosted.org/parallel_sync/pages/examples.html

다음은 사용 방법의 샘플 코드입니다.

from parallel_sync import rsync
creds = {'user': 'myusername', 'key':'~/.ssh/id_rsa', 'host':'192.168.16.31'}
rsync.upload('/tmp/local_dir', '/tmp/remote_dir', creds=creds)

병렬 처리는 기본적으로 10이며, 증가시킬 수 있습니다.

from parallel_sync import rsync
creds = {'user': 'myusername', 'key':'~/.ssh/id_rsa', 'host':'192.168.16.31'}
rsync.upload('/tmp/local_dir', '/tmp/remote_dir', creds=creds, parallelism=20)

그러나 일반적으로 ssh의 MaxSessions는 기본적으로 10으로 설정되므로 10 이상으로 늘리려면 ssh 설정을 수정해야 합니다.

가장 간단한 방법은 셸에서 백그라운드 작업을 사용하는 것입니다.

for d in /main/files/*; do
    rsync -a "$d" remote:/main/files/ &
done

그것이 일자리의 양을 제한하지 않는다는 것을 주의하세요!네트워크에 연결된 경우에는 문제가 없지만 녹이 슬기를 기다리는 경우에는 디스크가 녹슬게 됩니다.

추가할 수 있습니다.

while [ $(jobs | wc -l | xargs) -gt 10 ]; do sleep 1; done

작업 제어의 원시적인 형태를 위한 루프 내부.

로컬 넷에서 rsync 속도를 높이는 3가지 요령.

네트워크에서로 복사: 함: 사용 안 함ssh!

서버를 다른 서버에 로컬로 복사하는 경우, 전송하는 동안 데이터를 암호화할 필요가 없습니다!

는 "rsync"를 사용합니다.ssh네트워크를 통해 데이터를 전송합니다.이 문제를 방지하려면 대상 호스트를 생성해야 합니다.다음과 같은 방법으로 데몬을 제시간에 실행할 수 있습니다.

rsync --daemon --no-detach --config filename.conf

서 최소 은 다음과 수 ).man rsyncd.conf)

filename.conf

port = 12345
[data]
       path = /some/path
       use chroot = false

그리고나서

rsync -ax rsync://remotehost:12345/data/. /path/to/target/.
rsync -ax /path/to/source/. rsync://remotehost:12345/data/.

z 표준 사용 zstd

Z 표준은 일반적인 표준보다 최대 8배 더 빠를 수 있습니다. gzip따라서 이 새로운 압축 알고리즘을 사용하면 전송 성능이 크게 향상됩니다!

rsync -axz --zc=zstd rsync://remotehost:12345/data/. /path/to/target/.
rsync -axz --zc=zstd /path/to/source/. rsync://remotehost:12345/data/.

기능rsync브라우징 시간으로 인한 비활성화를 줄이기 위해

이러한 최적화는 디스크 액세스 및 파일 시스템 구조에 관한 것입니다.CPU 수와 함께 볼 수 있는 것이 없습니다!따라서 호스트가 단일 코어 CPU를 사용하는 경우에도 전송 성능이 향상될 수 있습니다.

다른 작업이 파일 시스템을 탐색하는 동안 최대 데이터가 대역폭을 사용하도록 하는 것이 목표이기 때문에 가장 적합한 동시 프로세스 수는 제공되는 작은 파일 수에 따라 달라집니다.

다음은 다음을 사용한 bash 스크립트입니다.wait -n -p PID:

#!/bin/bash

maxProc=3
source=''
destination='rsync://remotehost:12345/data/'

declare -ai start elap results order
wait4oneTask() {
    local _i
    wait -np epid
    results[epid]=$?
    elap[epid]=" ${EPOCHREALTIME/.} - ${start[epid]} "
    unset "running[$epid]"
    while [ -v elap[${order[0]}] ];do
        _i=${order[0]}
        printf " - %(%a %d %T)T.%06.0f %-36s %4d %12d\n" "${start[_i]:0:-6}" \
               "${start[_i]: -6}" "${paths[_i]}" "${results[_i]}" "${elap[_i]}"
        order=(${order[@]:1})
    done
}
printf "   %-22s %-36s %4s %12s\n" Started Path Rslt 'microseconds'
for path; do
    rsync -axz --zc zstd "$source$path/." "$destination$path/." &
    lpid=$!
    paths[lpid]="$path" 
    start[lpid]=${EPOCHREALTIME/.}
    running[lpid]=''
    order+=($lpid)
    ((${#running[@]}>=maxProc)) && wait4oneTask
done
while ((${#running[@]})); do
    wait4oneTask
done

출력은 다음과 같습니다.

myRsyncP.sh files/*/*
   Started                Path                                 Rslt microseconds
 - Fri 03 09:20:44.673637 files/1/343                             0      1186903
 - Fri 03 09:20:44.673914 files/1/43                              0      2276767
 - Fri 03 09:20:44.674147 files/1/55                              0      2172830
 - Fri 03 09:20:45.861041 files/1/772                             0      1279463
 - Fri 03 09:20:46.847241 files/2/346                             0      2363101
 - Fri 03 09:20:46.951192 files/2/4242                            0      2180573
 - Fri 03 09:20:47.140953 files/3/23                              0      1789049
 - Fri 03 09:20:48.930306 files/3/2545                            0      3259273
 - Fri 03 09:20:49.132076 files/3/4256                            0      2263019

빠른 확인:

printf "%'d\n" $(( 49132076 + 2263019 - 44673637)) \
    $((1186903+2276767+2172830+1279463+2363101+2180573+1789049+3259273+2263019))
6’721’458
18’770’978

최대 3개의 하위 프로세스에서 18,77초를 처리하는 데 6,72초가 걸렸습니다.

참고: musec2str을 사용하여 첫 번째 길이를 교체하여 출력을 개선할 수 있습니다.printf바꿈:줄 바꿈:

        musec2str -v elapsed "${elap[i]}"
        printf " - %(%a %d %T)T.%06.0f %-36s %4d %12s\n" "${start[i]:0:-6}" \
               "${start[i]: -6}" "${paths[i]}" "${results[i]}" "$elapsed"
myRsyncP.sh files/*/*
   Started                Path                                 Rslt      Elapsed
 - Fri 03 09:27:33.463009 files/1/343                             0   18.249400"
 - Fri 03 09:27:33.463264 files/1/43                              0   18.153972"
 - Fri 03 09:27:33.463502 files/1/55                             93   10.104106"
 - Fri 03 09:27:43.567882 files/1/772                           122   14.748798"
 - Fri 03 09:27:51.617515 files/2/346                             0   19.286811"
 - Fri 03 09:27:51.715848 files/2/4242                            0    3.292849"
 - Fri 03 09:27:55.008983 files/3/23                              0    5.325229"
 - Fri 03 09:27:58.317356 files/3/2545                            0   10.141078"
 - Fri 03 09:28:00.334848 files/3/4256                            0   15.306145"

추가 정보: 이 스크립트에서 일부 편집을 통해 전체 통계 라인을 추가할 수 있습니다.

#!/bin/bash

maxProc=3  source=''  destination='rsync://remotehost:12345/data/'

. musec2str.bash # See https://stackoverflow.com/a/72316403/1765658

declare -ai start elap results order
declare -i sumElap totElap

wait4oneTask() {
    wait -np epid
    results[epid]=$?
    local -i _i crtelap=" ${EPOCHREALTIME/.} - ${start[epid]} "
    elap[epid]=crtelap sumElap+=crtelap
    unset "running[$epid]"
    while [ -v elap[${order[0]}] ];do  # Print status lines in command order.
        _i=${order[0]}
    musec2str -v helap ${elap[_i]}
        printf " - %(%a %d %T)T.%06.f %-36s %4d %12s\n" "${start[_i]:0:-6}" \
               "${start[_i]: -6}" "${paths[_i]}" "${results[_i]}" "${helap}"
        order=(${order[@]:1})
    done
}
printf "   %-22s %-36s %4s %12s\n" Started Path Rslt 'microseconds'
for path;do
    rsync -axz --zc zstd "$source$path/." "$destination$path/." &
    lpid=$! paths[lpid]="$path" start[lpid]=${EPOCHREALTIME/.}
    running[lpid]='' order+=($lpid)
    ((${#running[@]}>=maxProc)) &&
        wait4oneTask
done
while ((${#running[@]})) ;do
    wait4oneTask
done

totElap=${EPOCHREALTIME/.}
for i in ${!start[@]};do  sortstart[${start[i]}]=$i;done
sortstartstr=${!sortstart[*]}
fstarted=${sortstartstr%% *}
totElap+=-fstarted
musec2str -v hTotElap $totElap
musec2str -v hSumElap $sumElap
printf " = %(%a %d %T)T.%06.0f %-41s %12s\n" "${fstarted:0:-6}" \
   "${fstarted: -6}" "Real: $hTotElap, Total:" "$hSumElap"

생성 가능:

$ ./parallelRsync Data\ dirs-{1..4}/Sub\ dir{A..D}
   Started                Path                                 Rslt microseconds
 - Sat 10 16:57:46.188195 Data dirs-1/Sub dirA                    0     1.69131"
 - Sat 10 16:57:46.188337 Data dirs-1/Sub dirB                  116    2.256086"
 - Sat 10 16:57:46.188473 Data dirs-1/Sub dirC                    0      1.1722"
 - Sat 10 16:57:47.361047 Data dirs-1/Sub dirD                    0    2.222638"
 - Sat 10 16:57:47.880674 Data dirs-2/Sub dirA                    0    2.193557"
 - Sat 10 16:57:48.446484 Data dirs-2/Sub dirB                    0    1.615003"
 - Sat 10 16:57:49.584670 Data dirs-2/Sub dirC                    0    2.201602"
 - Sat 10 16:57:50.061832 Data dirs-2/Sub dirD                    0    2.176913"
 - Sat 10 16:57:50.075178 Data dirs-3/Sub dirA                    0    1.952396"
 - Sat 10 16:57:51.786967 Data dirs-3/Sub dirB                    0    1.123764"
 - Sat 10 16:57:52.028138 Data dirs-3/Sub dirC                    0    2.531878"
 - Sat 10 16:57:52.239866 Data dirs-3/Sub dirD                    0    2.297417"
 - Sat 10 16:57:52.911924 Data dirs-4/Sub dirA                   14    1.290787"
 - Sat 10 16:57:54.203172 Data dirs-4/Sub dirB                    0    2.236149"
 - Sat 10 16:57:54.537597 Data dirs-4/Sub dirC                   14    2.125793"
 - Sat 10 16:57:54.561454 Data dirs-4/Sub dirD                    0     2.49632"
 = Sat 10 16:57:46.188195 Real: 10.870221", Total:                    31.583813"

가짜rsync 스크립트를 " ▁for"

참고: 이를 테스트하기 위해 가짜 rsync를 사용했습니다.

## Fake rsync wait 1.0 - 2.99 seconds and return 0-255 ~ 1x/10
rsync() { sleep $((RANDOM%2+1)).$RANDOM;exit $(( RANDOM%10==3?RANDOM%128:0));}
export -f rsync

은 제가찾짧버은전을 입니다.--cat.parallel 같이는서를에사이용않기고다다의버전만존니합능하여 사용을 피합니다.parallel:

cat files.txt | \
  parallel -n 500 --lb --pipe --cat rsync --files-from={} user@remote:/dir /dir -avPi

#### Arg explainer
# -n 500           :: split input into chunks of 500 entries
#
# --cat            :: create a tmp file referenced by {} containing the 500 
#                     entry content for each process
#
# user@remote:/dir :: the root relative to which entries in files.txt are considered
#
# /dir             :: local root relative to which files are copied

의 샘플 files.txt:

/dir/file-1
/dir/subdir/file-2
....

이옵은사않습다니지되를 사용하지 .-j 50일자리 숫자를 위해, 그것은 여기서 제 쪽에서 작동하지 않았습니다.대신에 나는 사용했습니다.-n 500작업당 레코드 수에 대한 것으로, 총 레코드 수에 주어진 적절한 수로 계산됩니다.

UDR/UDT가 놀라운 도구라는 것을 알게 되었습니다.TLDR: 단일 TCP 연결이 아닌 여러 UPD 연결을 사용하는 rsync용 UDT 래퍼입니다.

참고 자료: https://udt.sourceforge.io/ & https://github.com/jaystevens/UDR#udr

만약 당신이 RHEL 디스트리뷰터를 사용한다면, 그들은 당신을 위해 그것을 미리 컴파일했습니다.http://hgdownload.soe.ucsc.edu/admin/udr

다른 SSH 포트를 지정할 수 없으므로 원격 서버에서 22개를 사용해야 한다는 단점이 있습니다.

어쨌든 RPM을 설치한 후에는 문자 그대로 다음과 같이 간단합니다.

udr rsync -aP user@IpOrFqdn:/source/files/* /dest/folder/

전송 속도가 10배 증가하는 서버에 따라 대부분의 경우 전송 속도가 크게 증가합니다.

참고: 모든 항목을 먼저 gzip으로 선택한 경우 변경된 내용만 업데이트되도록 --rsyncable arg를 사용해야 합니다.

일반 디스크에서 병렬 rsync를 사용하면 I/O를 놓고 경쟁하게 되어 순차적 읽기가 비효율적인 랜덤 읽기로 전환됩니다.대신 대상 서버에서 ssh pull을 통해 디렉터리를 스트림으로 tar한 다음 스트림을 tar 추출로 파이프링할 수 있습니다.

언급URL : https://stackoverflow.com/questions/24058544/speed-up-rsync-with-simultaneous-concurrent-file-transfers

반응형