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.

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}/%/

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/

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!


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
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

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.


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.


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.


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.


-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.


1
Apakah Anda ingin memperluas itu untuk membuat jawaban Anda berguna?
Tog
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.