Paralelleştirme rsync


30

Deneme ve yanılmadan sonra evim ile uzak sunucum arasında bir yerde bir miktar boğulma yaşanıyor ... ama boğulma çok akıllı değil. Sadece bireysel bağlantıları keser. Yani bir 1 GB dosya kopyalarsam, 150 kBps hızında nihayetinde ilerler. Ancak 10 kopya başlatırsam, her biri 150 kBps hızında olacaktır (yani, birden fazla bağlantı üzerinden daha yüksek toplam bant genişliği elde edeceğim).

Bazı büyük veri kümelerini işten eve (neyse ki birçok dosya biçiminde) eşitlemek için sık sık rsync kullanıyorum. Rsync'e birden fazla bağlantı kullanarak indirmesini söylemenin bir yolu var mı? Teorik olarak mümkün olmalı, çünkü söyleyebildiğim kadarıyla, rsync önce gerekli değişiklikleri belirlemek için bir pas atıyor ve ardından fiili aktarımı gerçekleştiriyor. Bonus, rsync'e ayrı ayrı dosyaları N parçaya bölmesini ve daha sonra onları birbirine eklemesini söylemenin sihirli bir yolu varsa. CuteFTP'nin bunu çıkaracak kadar akıllı olduğuna inanıyorum.

Yanıtlar:


13

Ben sadece bir setten diğerine beslememe izin verecek yedekleme / geri yükleme özelliği olmayan birkaç TB'yi bir NAS'tan farklı bir NAS'a taşımak zorunda kaldım.

Bu yüzden, bu betiği karşılaştığı her dizin için 1 rsync çalıştırmak üzere yazdım. Kaynak dizinleri listelemeye bağlıdır (ARG 3'den kaçma konusunda dikkatli olun), ancak bu aşamayı sadece dosyaları ve dizinleri uygun seviyeye kopyalayan özyinelemeli olmayan bir rsync ile ayarlayabileceğinizi düşünüyorum.

Ayrıca, işlemci sayısına bağlı olarak kaç rsync çalıştırılacağını da belirler, ancak bunu düzeltmek isteyebilirsiniz.

Akla gelen diğer olası seçenek ise: - sadece liste modunda bir rsync çalıştırmak.

Bu, güncellenmesi gereken tüm dosyaları size verir. Ardından, gittiğiniz rsync sayısını yönetmek için xargs kullandıysanız, listenizdeki her dosya için 1 rsync çalıştırın, bu çok zarif olabilir. Aslında buradaki küçük senaryomdan daha zarif bir çözüm ...

#! /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
Bu işe yarar - nasıl çalıştığı konusunda pek çok iyileştirme yapabilirsiniz, ancak uygulamanızı paralelleştirmek için xargs kullanma kavramı oldukça yenidir.
MattPark

6

GNU Parallel'ın bir çözümü var

15 TB'ı 1 Gbps'ye kadar taşıdım ve 1 Gbps bağlantısını doyabilir.

Aşağıdakiler, sunucu fooserver'ındaki dest-dir dizinine src-dir içindeki büyük dosya başına bir rsync başlatacaktır:

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

Oluşturulan dizinler yanlış izinlerle sonuçlanabilir ve daha küçük dosyalar aktarılmaz. Bu rsync komutunu son kez düzeltmek için:

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

1
"ÖRNEK: Paralelleştirme rsync" bölümünü yanıtınıza yapıştırır mısınız? Sadece gelecekte bağlantı koparsa diye.
picobit

3

Evet. Böyle bir özellik var.

Açıklanan işlevselliği sağlayan pssh adlı bir yardımcı program vardır .

Bu paket openssh araçlarının paralel versiyonlarını sunar. Dağıtıma dahil olanlar:

  • Paralel ssh (pssh)
  • Paralel scp (pscp)
  • Paralel rsync (prsync)
  • Paralel nuke (pnuke)
  • Paralel slurp (pslurp)

Kurulumu ne kadar kolay olduğundan emin değilim, ama hile yapabilir!


26
Pssh yardımcı programları komutları birden fazla sunucuya yaymak için kullanılır, aynı komutu bir sunucuda birkaç kez yapmaz. Özellikle, prsync yalnızca yerel makinenizdeki bir dosyayı birden fazla harici makineye göndermeyi destekler. Birden fazla bağlantıya sahip uzak bir dosyanın indirilmesini desteklemez.
Derek Dahmer,

1
@ DerekDahmer'ın yorumuna göre, bu cevabın posteri geri çekmek isteyebilir mi?
mc0e

3

Yorum yapamam, bu yüzden önceki (hoş ve akıllı) koddan biraz daha iyi bir kodla yeni bir cevap ekledim .

rsyncÇizgiyi kontrol edin , çünkü isteğe bağlı bir ioniceince ayar içerir .

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

Bu yardımcı programı sizin için yazmış gibi görünüyor. Paralel parçalara aktarımı keser. Bu, GNU Parallel altında listelenen "paralel büyük dosya" sürümünden daha iyi bir uygulamadır:

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

Ayrıca, lftp ftp, ftps, http, https, hftp, balık, sftp üzerinden dosya transferlerini paralelleştirebilir. Bir çok kez, lftp kullanmanın bazı avantajları vardır, çünkü rsync için izinleri, sınırlı erişimi vb. Yönetmek zor olabilir.


Bu işe yaramasına rağmen, aynı dosyayı indirmek için birden fazla bağlantı kullanmadığınız için hızlıca büyük miktarda disk parçalanmasına neden olabilir.
bparker

1

Hayır. Böyle bir özellik yoktur. rsyncGerçekten isterseniz , senkronizasyonu çoklu aramalara bölebilirsiniz .

Bu oranı sınırlayıcı olanı bulmanızı ve onu koruyan / yönetenle ciddi bir konuşma yapmanızı öneririm.


4
Sık sık bu kısıtlamalar Comcast benzeri bazı ISS'lerdendir. Onlarla her türlü makul konuşmayı başarıyor.
James Moore

1

Aynı anda birkaç dizini (birçok dosyayla) aktarmak istedim, bu yüzden bu küçük betiği yarattım:

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

Bu betiği oldukça hızlı yaptım, bu yüzden lütfen bir revizyon ortamında ve üretim ortamında kullanmadan önce test edin .


0

Paralel resim içeren birçok klasör yüklemek için aşağıdaki betiği oluşturdum. Önce senkronizasyon hedefi, sonra kopyalanacak tüm klasör adları ile çalıştırın.

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

Güzel görünmesi için klasör adını sarı renkte tüm rsync konsolu çıkışına ön ekler.


-1

Aria2 , birçok aynadan birçok bağlantı kullanarak veri indirmek için iyi bir istemci programıdır. SFTP'yi desteklemiyor. Böylece, FTP sunucusu kurdum - vsftpd . 3g bağlantım, FTP sunucusuna 5 bağlantıyla tam güçle çalışıyor.


1
Cevabınızı yararlı kılmak için bu konuya odaklanmak ister misiniz?
Tog
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.