Paralelisasi rsync

30

Saya baru saja pindah dan menemukan setelah beberapa percobaan dan kesalahan bahwa di suatu tempat antara rumah saya dan server jarak jauh saya, ada beberapa pelambatan yang terjadi ... tetapi pelambatan tidak terlalu cerdas. Ini hanya membatasi koneksi individual. Jadi jika saya menyalin satu file 1 GB, itu akan melanjutkan dengan gembira pada 150 kBps. Tetapi jika saya menginisialisasi 10 salinan, masing-masing akan mencapai 150 kBps (yaitu saya mendapatkan bandwidth agregat yang jauh lebih tinggi melalui beberapa koneksi).

Saya menggunakan rsync cukup sering untuk menyinkronkan beberapa dataset besar dari kantor ke rumah (untungnya dalam bentuk banyak file). Apakah ada cara untuk memberitahu rsync untuk mengunduh menggunakan banyak koneksi? Secara teoritis itu harus mungkin karena sejauh yang saya tahu, rsync pertama kali melakukan pass untuk menentukan perubahan yang diperlukan dan kemudian melakukan transmisi yang sebenarnya. Poin bonus jika ada cara ajaib untuk memberitahu rsync untuk mengiris file-file individual menjadi potongan-potongan N dan kemudian menyatukannya kembali. Saya percaya CuteFTP sebenarnya cukup pintar untuk melakukan itu.

stuyguy
sumber

Jawaban:

13

Saya hanya mengalami masalah yang sama karena harus memindahkan beberapa TB dari satu NAS ke NAS yang berbeda tanpa kemampuan cadangan / pemulihan yang memungkinkan saya untuk hanya memberi makan 1 set ke yang lain.

Jadi saya menulis skrip ini untuk menjalankan 1 rsync untuk setiap direktori yang dihadapinya. Itu tergantung pada kemampuan untuk mendaftar direktori sumber (hati-hati untuk keluar dari ARG 3) tapi saya pikir Anda bisa mengatur tahap itu dengan rsync non-rekursif yang hanya menyalin file dan direktori ke tingkat yang sesuai.

Ini juga menentukan berapa banyak rsync untuk dijalankan berdasarkan jumlah prosesor tetapi Anda mungkin ingin men-tweak itu.

Opsi lain yang mungkin muncul dalam pikiran adalah: jalankan rsync dalam mode --list-only.

Itu akan memberi Anda semua file yang perlu diperbarui Kemudian jalankan 1 rsync untuk setiap file dalam daftar Anda jika Anda menggunakan xargs untuk mengelola jumlah rsyncs yang Anda tuju ini bisa sangat elegan. Sebenarnya mungkin solusi yang lebih elegan daripada skrip kecilku di sini ...

#! /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}/%/
kkron
sumber
2
Ini berfungsi - Anda dapat membuat banyak peningkatan pada cara kerjanya, tetapi konsep menggunakan xargs untuk memparalelkan aplikasi Anda cukup baru.
MattPark
6

GNU Parallel memiliki solusinya

Saya telah memindahkan 15 TB hingga 1 Gbps dan itu dapat memenuhi tautan 1 Gbps.

Berikut ini akan memulai satu rsync per file besar dalam src-dir untuk dest-dir pada server fooserver:

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

Dir yang dibuat dapat berakhir dengan izin yang salah dan file yang lebih kecil tidak ditransfer. Untuk memperbaiki yang menjalankan rsync untuk yang terakhir kalinya:

rsync -Havessh src-dir/ fooserver:/dest-dir/
Ole Tange
sumber
1
Apakah Anda keberatan menempelkan bagian "EXAMPLE: Parallelizing rsync" ke dalam jawaban Anda. Untuk berjaga-jaga jika tautan rusak di masa depan.
picobit
3

Iya nih. Fitur seperti itu ada.

Ada utilitas bernama pssh yang menyediakan fungsionalitas yang dijelaskan.

Paket ini menyediakan versi paralel dari alat openssh. Termasuk dalam distribusi:

  • Ssh paralel (pssh)
  • Scp paralel (pscp)
  • Rsync paralel (prsync)
  • Nuke paralel (pnuke)
  • Slurp paralel (pslurp)

Saya tidak yakin betapa mudahnya mengatur, tetapi mungkin hanya melakukan trik!

Tim Bielawa
sumber
26
Utilitas pssh digunakan untuk menyebarkan perintah di beberapa server, tidak melakukan perintah yang sama beberapa kali pada satu server. Secara khusus, prsync hanya mendukung pengiriman file di komputer lokal Anda ke beberapa mesin eksternal. Itu tidak mendukung mengunduh file jarak jauh dengan banyak koneksi.
Derek Dahmer
1
Diberikan komentar @ DerekDahmer, poster jawaban ini mungkin ingin menariknya?
mc0e
3

Saya tidak dapat berkomentar, jadi saya telah menambahkan jawaban baru, dengan kode yang sedikit lebih baik daripada kode sebelumnya (bagus & pintar).

Periksa rsyncbarisnya, karena berisi ionicetweak opsional .

#!/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
[email protected]:/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
Widmo
sumber
2

Sepertinya seseorang telah menulis utilitas ini untuk Anda. Memecah transfer menjadi potongan paralel. Ini adalah implementasi yang lebih baik daripada versi "file besar paralel" yang tercantum di bawah GNU Parallel:

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

Juga, lftp dapat memparalelkan transfer file melalui ftp, ftps, http, https, hftp, fish, sftp. Banyak kali, ada beberapa keuntungan menggunakan lftp, karena mengelola izin, akses terbatas, dll untuk rsync dapat menjadi tantangan.

Erik Aronesty
sumber
Meskipun ini berfungsi, ini dapat menyebabkan sejumlah besar fragmentasi disk dengan cepat, karena Anda tidak hanya menggunakan banyak koneksi untuk mengunduh file yang sama.
bparker
1

Tidak. Tidak ada fitur seperti itu. Anda dapat membagi sinkronisasi menjadi beberapa panggilan rsyncjika Anda benar-benar menginginkannya.

Saya sarankan Anda menemukan apa pun yang melakukan pembatasan tingkat ini dan melakukan pembicaraan serius dengan siapa pun yang memelihara / mengelolanya.

David Schwartz
sumber
4
Seringkali pembatasan tersebut berasal dari beberapa ISP seperti Comcast. Semoga beruntung memiliki percakapan yang masuk akal dengan mereka.
James Moore
1

Saya ingin mentransfer beberapa direktori (dengan banyak file) secara bersamaan, jadi saya membuat skrip kecil ini:

#!/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."

Saya mengerjakan skrip ini dengan cukup cepat, jadi tolong perbaiki dan ujilah sebelum menggunakannya di lingkungan produksi.

lepe
sumber
0

Saya membuat skrip berikut untuk mengunggah banyak folder dengan gambar secara paralel. Anda menjalankannya terlebih dahulu dengan target sinkronisasi dan kemudian semua nama folder untuk disalin.

#!/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

Ini awalan nama folder dengan warna kuning untuk semua output konsol rsync agar terlihat cantik.

konrad
sumber
-1

Aria2 adalah program klien yang baik untuk mengunduh data menggunakan banyak koneksi dari banyak mirror. Itu tidak mendukung SFTP. Jadi, saya sudah menginstal server FTP - vsftpd . Koneksi 3g saya bekerja dengan daya penuh dengan 5 koneksi ke server FTP.

puchu
sumber
1
Apakah Anda ingin memperluas itu untuk membuat jawaban Anda berguna?
Tog