Paralelkan rsync menggunakan GNU Parallel

18

Saya telah menggunakan rsyncskrip untuk menyinkronkan data di satu host dengan data di host lain. Data memiliki banyak file berukuran kecil yang berkontribusi hampir 1,2TB.

Untuk menyinkronkan file-file itu, saya telah menggunakan rsyncperintah sebagai berikut:

rsync -avzm --stats --human-readable --include-from proj.lst /data/projects REMOTEHOST:/data/

Isi proj.lst adalah sebagai berikut:

+ proj1
+ proj1/*
+ proj1/*/*
+ proj1/*/*/*.tar
+ proj1/*/*/*.pdf
+ proj2
+ proj2/*
+ proj2/*/*
+ proj2/*/*/*.tar
+ proj2/*/*/*.pdf
...
...
...
- *

Sebagai ujian, saya mengambil dua proyek tersebut (data 8.5GB) dan saya menjalankan perintah di atas. Menjadi proses berurutan, alat 14 menit 58 detik untuk menyelesaikan. Jadi, untuk 1.2TB data akan butuh beberapa jam.

Jika saya dapat melakukan banyak rsyncproses secara paralel (menggunakan &, xargsatau parallel), itu akan menghemat waktu saya.

Saya mencoba dengan perintah di bawah ini dengan parallel(setelah masuk cdke direktori sumber) dan butuh 12 menit 37 detik untuk mengeksekusi:

parallel --will-cite -j 5 rsync -avzm --stats --human-readable {} REMOTEHOST:/data/ ::: .

Ini seharusnya memakan waktu 5 kali lebih sedikit, tetapi tidak. Saya pikir, saya salah di suatu tempat.

Bagaimana saya bisa menjalankan banyak rsyncproses untuk mengurangi waktu eksekusi?

Mandar Shinde
sumber
1
Apakah Anda dibatasi oleh bandwidth jaringan? Iops disk? Bandwidth disk?
Ole Tange
Jika memungkinkan, kami ingin menggunakan 50% dari total bandwidth. Tetapi, memparalelkan banyak rsyncs adalah prioritas utama kami.
Mandar Shinde
Bisakah Anda beri tahu kami: Bandwidth jaringan, disk iop, bandwidth disk, dan bandwidth yang sebenarnya digunakan?
Ole Tange
Bahkan, saya tidak tahu tentang parameter di atas. Untuk saat ini, kami dapat mengabaikan bagian pengoptimalan. Multiple rsyncs secara paralel adalah fokus utama sekarang.
Mandar Shinde
Tidak ada gunanya paralel jika batasannya bukan CPU. Bahkan dapat / akan memperburuk masalah (gerakan lengan disk yang saling bertentangan pada sumber atau target disk)
xenoid

Jawaban:

16

Langkah-langkah berikut berhasil bagi saya:

  1. Jalankan rsync --dry-runterlebih dahulu untuk mendapatkan daftar file yang akan terpengaruh.
$ rsync -avzm --stats --safe-links --ignore-existing --dry-run \
    --human-readable /data/projects REMOTE-HOST:/data/ > /tmp/transfer.log
  1. Saya mengumpankan output cat transfer.logke paralleluntuk menjalankan 5 rsyncs secara paralel, sebagai berikut:
$ cat /tmp/transfer.log | \
    parallel --will-cite -j 5 rsync -avzm --relative \
      --stats --safe-links --ignore-existing \
      --human-readable {} REMOTE-HOST:/data/ > result.log

Di sini, --relativeopsi ( tautan ) memastikan bahwa struktur direktori untuk file yang terpengaruh, di sumber dan tujuan, tetap sama (di dalam /data/direktori), sehingga perintah harus dijalankan di folder sumber (misalnya, /data/projects).

Mandar Shinde
sumber
5
Itu akan melakukan rsync per file. Mungkin akan lebih efisien untuk membagi seluruh daftar file menggunakan splitdan memberi makan nama file tersebut secara paralel. Kemudian gunakan rsync --files-fromuntuk mendapatkan nama file dari setiap file dan menyinkronkannya. rm backup. * split -l 3000 backup.list backup. ls backup. * | parallel --line-buffer --verbose -j 5 rsync --progress -av --files-from {} / LOCAL / PARENT / PATH / REMOTE_HOST: REMOTE_PATH /
Sandip Bhattacharya
1
Bagaimana perintah rsync kedua menangani baris di result.log yang bukan file? yaitu receiving file list ... done created directory /data/.
Mike D
1
Pada versi rsync (3.1.0+) yang lebih baru, Anda dapat menggunakannya --info=namesebagai pengganti -v, dan Anda hanya akan mendapatkan nama-nama file dan direktori. Anda mungkin ingin menggunakan --protect-args ke rsync 'inner' untuk mentransfer juga jika ada file yang mungkin memiliki spasi atau karakter meta shell di dalamnya.
Cheetah
13

Saya pribadi menggunakan yang sederhana ini:

ls -1 | parallel rsync -a {} /destination/directory/

Yang hanya berguna ketika Anda memiliki lebih dari beberapa direktori yang hampir kosong, jika tidak Anda akan berakhir hampir setiap rsyncterminasi dan yang terakhir melakukan semua pekerjaan sendirian.

Julien Palard
sumber
Ini bekerja dengan baik - sulit untuk mengetahui apakah itu melakukan sesuatu, jadi a-ke paralel membuatnya lebih cerewet. Juga, -j 30 ke paralel (yaitu sebelum perintah rsync) membuatnya menjalankan 30 pekerjaan, bukan hanya satu per inti CPU yang merupakan default.
Criggie
12

Saya akan sangat mencegah siapa pun dari menggunakan jawaban yang diterima, solusi yang lebih baik adalah dengan menjelajah direktori tingkat atas dan meluncurkan sejumlah operasi rync yang proporsional.

Saya memiliki volume zfs besar dan sumber saya adalah cifs mount. Keduanya terhubung dengan 10G, dan dalam beberapa tolok ukur dapat menjenuhkan tautan. Kinerja dievaluasi menggunakan zpool iostat 1.

Drive sumber dipasang seperti:

mount -t cifs -o username=,password= //static_ip/70tb /mnt/Datahoarder_Mount/ -o vers=3.0

Menggunakan satu rsyncproses:

rsync -h -v -r -P -t /mnt/Datahoarder_Mount/ /StoragePod

io meter berbunyi:

StoragePod  30.0T   144T      0  1.61K      0   130M
StoragePod  30.0T   144T      0  1.61K      0   130M
StoragePod  30.0T   144T      0  1.62K      0   130M

Ini dalam benchmark sintetis (disk kristal), kinerja untuk penulisan sekuensial mendekati 900 MB / s yang berarti tautannya jenuh. 130MB / s tidak terlalu baik, dan perbedaan antara menunggu akhir pekan dan dua minggu.

Jadi, saya membuat daftar file dan mencoba menjalankan sinkronisasi lagi (saya memiliki mesin 64 core):

cat /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount.log | parallel --will-cite -j 16 rsync -avzm --relative --stats --safe-links --size-only --human-readable {} /StoragePod/ > /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount_result.log

dan itu memiliki kinerja yang sama!

StoragePod  29.9T   144T      0  1.63K      0   130M
StoragePod  29.9T   144T      0  1.62K      0   130M
StoragePod  29.9T   144T      0  1.56K      0   129M

Sebagai alternatif, saya hanya menjalankan rsync pada folder root:

rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/Marcello_zinc_bone /StoragePod/Marcello_zinc_bone
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/fibroblast_growth /StoragePod/fibroblast_growth
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/QDIC /StoragePod/QDIC
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/sexy_dps_cell /StoragePod/sexy_dps_cell

Ini sebenarnya meningkatkan kinerja:

StoragePod  30.1T   144T     13  3.66K   112K   343M
StoragePod  30.1T   144T     24  5.11K   184K   469M
StoragePod  30.1T   144T     25  4.30K   196K   373M

Sebagai kesimpulan, ketika @Sandip Bhattacharya dibesarkan, tulislah sebuah skrip kecil untuk mendapatkan direktori dan paralel dengannya. Atau, kirimkan daftar file ke rsync. Tapi jangan membuat instance baru untuk setiap file.

Mikhail
sumber
5

Cara yang diuji untuk melakukan rsync yang diparalelkan adalah: http://www.gnu.org/software/parallel/man.html#EXAMPLE:-Parallelizing-rsync

rsync adalah alat yang hebat, tetapi kadang-kadang itu tidak akan mengisi bandwidth yang tersedia. Ini sering menjadi masalah ketika menyalin beberapa file besar melalui koneksi berkecepatan tinggi.

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

Direktori yang dibuat mungkin 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/ 

Jika Anda tidak dapat mendorong data, tetapi perlu menariknya dan file-file tersebut disebut digit.png (mis. 000000.png) Anda mungkin dapat melakukan:

seq -w 0 99 | parallel rsync -Havessh fooserver:src/*{}.png destdir/
Ole Tange
sumber
Ada alternatif lain untuk menghindari find?
Mandar Shinde
1
Batasi -maxdepth of find.
Ole Tange
Jika saya menggunakan --dry-runopsi rsync, saya akan memiliki daftar file yang akan ditransfer. Bisakah saya memberikan daftar file itu paralleluntuk memparalelkan proses?
Mandar Shinde
1
file kucing | parallel -v ssh fooserver mkdir -p / dest-dir / {//} \; rsync -s -Havessh {} fooserver: / dest-dir / {}
Ole Tange
Bisakah Anda jelaskan mkdir -p /dest-dir/{//}\;bagiannya? Terutama {//}masalahnya agak membingungkan.
Mandar Shinde
1

Untuk sinkronisasi multi tujuan, saya menggunakan

parallel rsync -avi /path/to/source ::: host1: host2: host3:

Petunjuk: Semua koneksi ssh dibuat dengan kunci publik di ~/.ssh/authorized_keys

ingopingo
sumber
1

Saya selalu google untuk rsync paralel karena saya selalu lupa perintah penuh, tetapi tidak ada solusi yang bekerja untuk saya seperti yang saya inginkan - baik itu termasuk beberapa langkah atau perlu menginstal parallel. Saya akhirnya menggunakan one-liner ini untuk menyinkronkan beberapa folder:

find dir/ -type d|xargs -P 5 -I % sh -c 'rsync -a --delete --bwlimit=50000 $(echo dir/%/ host:/dir/%/)'

-P 5 adalah jumlah proses yang ingin Anda spawn - gunakan 0 untuk tidak terbatas (jelas tidak disarankan).

--bwlimit untuk menghindari menggunakan semua bandwidth.

-I %argumen yang disediakan oleh find (direktori ditemukan di dir/)

$(echo dir/%/ host:/dir/%/)- mencetak direktori sumber dan tujuan yang dibaca oleh rsync sebagai argumen. % diganti xargsdengan nama direktori yang ditemukan oleh find.

Mari kita asumsikan saya memiliki dua direktori di /home: dir1dan dir2. Saya lari find /home -type d|xargs -P 5 -I % sh -c 'rsync -a --delete --bwlimit=50000 $(echo /home/%/ host:/home/%/)'. Jadi perintah rsync akan berjalan sebagai dua proses (dua proses karena /homememiliki dua direktori) dengan argumen berikut:

rsync -a --delete --bwlimit=50000 /home/dir1/ host:/home/dir1/
rsync -a --delete --bwlimit=50000 /home/dir1/ host:/home/dir1/
Sebastjanas
sumber