Apakah ada alternatif yang lebih cepat daripada cp untuk menyalin file besar (~ 20 GB)?

40

Saya seorang mahasiswa pascasarjana, dan kelompok tempat saya bekerja mengelola sebuah cluster Linux. Setiap node cluster memiliki disk lokal sendiri, tetapi disk lokal ini relatif kecil dan tidak dilengkapi dengan cadangan otomatis. Jadi grup memiliki server file dengan banyak TB ruang penyimpanan. Saya seorang pemula Linux yang relatif, jadi saya tidak yakin apa spesifikasi dari server file dalam hal kecepatan, kemampuan jaringan, dll. Saya tahu dari pengalaman bahwa disk lokal secara signifikan lebih cepat daripada server file dalam hal I / O . Sekitar selusin orang menggunakan server file.

Menggunakan cpuntuk menyalin file ~ 20 GB dari server file ke salah satu disk lokal rata-rata membutuhkan waktu sekitar 11,5 menit (menurut time). Saya tahu bahwa cpoperasi ini tidak terlalu efisien karena (1) timememberi tahu saya bahwa waktu sistem untuk salinan seperti itu hanya ~ 45 detik; dan karena (2) ketika saya memeriksa topselama penyalinan, % CPU cukup rendah (dengan inspeksi, rata-rata 0-10% ).

Menggunakan cpuntuk menyalin file ~ 20 GB yang sama dari satu folder pada disk lokal ke folder lain pada disk lokal yang sama membutuhkan waktu lebih sedikit - sekitar 9 menit dalam waktu nyata (~ 51 detik dalam waktu sistem, menurut time). Jadi ternyata fileserver lebih lambat dari disk lokal, seperti yang diharapkan, tetapi mungkin tidak lebih lambat secara signifikan. Saya terkejut bahwa penyalinan dari lokal ke lokal yang sama tidak lebih cepat dari 9 menit.

Saya perlu menyalin ~ 200 file besar - masing-masing ~ 20 GB - dari server file ke salah satu disk lokal. Jadi, pertanyaan saya adalah: Apakah ada alternatif yang lebih cepat cpuntuk menyalin file besar di Linux? (Atau apakah ada bendera di dalam cpyang bisa saya gunakan yang akan mempercepat penyalinan?) Bahkan jika saya entah bagaimana bisa mencukur satu menit dari waktu penyalinan ini, itu akan sangat membantu.

Saya yakin itu membeli disk perangkat keras baru yang lebih cepat, tetapi saya tidak memiliki akses ke sumber daya seperti itu. Saya juga bukan administrator sistem - saya hanya pengguna (pemula) - jadi saya tidak memiliki akses ke informasi lebih rinci tentang beban yang ada di disk. Saya tahu bahwa sementara sekitar selusin orang menggunakan server file setiap hari, saya adalah satu-satunya orang yang menggunakan disk lokal / node ini.

Andrew
sumber
29
Itu membuat sekitar 29MB / s, yang cukup cepat jika Anda bertanya kepada saya. Saya tidak berpikir ada perintah yang akan mempercepat ini, "bottleneck" kemungkinan besar a) jaringan atau b) file-server.
tink
5
Tink 100% benar. Saya belum pernah melihat apa pun yang dapat meningkatkan ini. Satu-satunya hal yang telah saya lakukan di masa lalu adalah kompres data sebelum mengirimnya, tetapi itu berarti Anda menambahkan waktu dengan langkah kompresi dan langkah-langkah dekompresi, tetapi kadang-kadang itu layak jika data adalah kandidat yang baik untuk dijadikan terkompresi!
slm
3
Anda juga dapat mencoba dddan rsyncmembandingkan mana yang bekerja lebih cepat di lingkungan Anda
Raza
@Salton Terima kasih. Saya belum mencoba dd, tetapi saya hanya mencoba rsync. Waktu sebenarnya adalah sekitar 11,5 menit dan waktu sistem sekitar 1,5 menit, menurut time.
Andrew
2
Saya terkejut tidak ada yang menunjukkan bahwa disk lokal ke salinan disk lokal dapat dibuat lebih efisien dengan memiliki beberapa disk yang terpasang. Menyalin dari /dev/sda1ke /dev/sdb1akan lebih cepat daripada menyalin dari satu lokasi /dev/sda1ke lokasi lain pada /dev/sda1atau partisi lain /dev/sdakarena hard drive tidak perlu melakukan pencarian tambahan antara membaca dan menulis (dengan asumsi hard drive tradisional dengan disk berputar dan kepala bergerak; SSD jelas berbeda).
tripleee

Jawaban:

53

% CPU harus rendah selama penyalinan. CPU memberi tahu pengontrol disk "ambil data dari sektor X – Y ke dalam buffer memori di Z". Lalu ia pergi dan melakukan sesuatu yang lain (atau tidur, jika tidak ada yang lain). Perangkat keras memicu interupsi ketika data ada di memori. Kemudian CPU harus menyalinnya beberapa kali, dan memberi tahu kartu jaringan "mengirimkan paket di lokasi memori A, B, dan C". Kemudian kembali melakukan sesuatu yang lain.

Anda mendorong ~ 240mbps. Pada LAN gigabit, Anda harus dapat melakukan setidaknya 800mbps, tetapi:

  1. Itu dibagikan di antara semua orang menggunakan server file (dan mungkin koneksi antar sakelar, dll.)
  2. Itu dibatasi oleh kecepatan file server dapat menangani penulisan, mengingat bandwidth I / O disk-nya dibagi oleh semua orang yang menggunakannya.
  3. Anda tidak menentukan bagaimana Anda mengakses server file (NFS, CIFS (Samba), AFS, dll.). Anda mungkin perlu menyetel pemasangan jaringan Anda, tetapi pada apa pun yang setengah-baru saja, standarnya biasanya cukup waras.

Untuk melacak kemacetan, iostat -kx 10akan menjadi perintah yang berguna. Ini akan menunjukkan kepada Anda pemanfaatan pada hard disk lokal Anda. Jika Anda dapat menjalankannya di server file, ini akan memberi tahu Anda seberapa sibuk file server itu.

Solusi umum akan mempercepat hambatan itu, yang tentu saja Anda tidak memiliki anggaran untuk itu. Tetapi, ada beberapa kasus khusus di mana Anda dapat menemukan pendekatan yang lebih cepat:

  • Jika file kompresibel, dan Anda memiliki CPU yang cepat, melakukan kompres minimal dengan cepat mungkin lebih cepat. Sesuatu seperti lzopatau mungkin gzip --fastest.
  • Jika Anda hanya mengubah beberapa bit di sana-sini, dan kemudian mengirim file kembali, hanya mengirim delta akan jauh lebih cepat. Sayangnya, rsynctidak akan terlalu membantu di sini, karena perlu membaca file di kedua sisi untuk menemukan delta. Sebaliknya, Anda memerlukan sesuatu yang melacak delta saat Anda mengubah file ... Sebagian besar pendekatan di sini adalah khusus aplikasi. Tapi mungkin saja Anda bisa melakukan sesuatu, misalnya, device-mapper (lihat target era dm baru ) atau btrfs.
  • Jika Anda menyalin data yang sama ke beberapa mesin, Anda dapat menggunakan sesuatu seperti udpcast untuk mengirimnya ke semua mesin sekaligus.

Dan, karena Anda perhatikan Anda bukan sysadmin, saya menduga itu berarti Anda memiliki sysadmin. Atau setidaknya seseorang yang bertanggung jawab untuk file server & jaringan. Anda mungkin harus bertanya kepadanya, mereka harus lebih akrab dengan spesifikasi pengaturan Anda. Sysadmin Anda setidaknya harus dapat memberi tahu Anda berapa nilai transfer yang dapat Anda harapkan.

derobert
sumber
+1 untuk iostat -kx 10 :-)
n611x007
16

Ini bisa, mungkin, menjadi alternatif yang lebih cepat, dan Anda tidak akan menyumbat jaringan selama dua hari: Ambil satu atau dua USB besar (USB 3 jika Anda memilikinya) atau disk FireWire, sambungkan ke server dan salin file ke disk. Bawa disk ke mesin lokal Anda. Salin file ke mesin.

Thomas Padron-McCarthy
sumber
23
Sneakernet ( en.wikipedia.org/wiki/Sneakernet ) bisa sangat cepat: Jangan pernah meremehkan bandwidth dari station wagon yang penuh dengan kaset yang meluncur deras di jalan raya.
SplinterReality
10

Definisi efisiensi Anda terbalik. Implementasi yang lebih efisien menghabiskan lebih sedikit waktu cpu. Pada salinan lokal Anda rata-rata sekitar 74 MB / s dari throughput (baca + tulis), yang sama baiknya dengan satu hard disk akan dapatkan.

psusi
sumber
1
Ups. Ketika saya berkata "efisien," maksud saya "cepat."
Andrew
10

Jika Anda memiliki akses SSH (atau SFTP) langsung (tanyakan sysadmin Anda), Anda dapat menggunakan scpdengan kompresi ( -C):

scp -C you@server:/path/to/yourfile .

Tentu saja, itu hanya berguna jika file tersebut dapat dikompres, dan ini akan menggunakan lebih banyak waktu CPU, karena akan menggunakan enkripsi (karena ini lebih dari SSH), dan mengompresi.

Pasang kembali Monica
sumber
Dalam hal ini, akan sangat berguna untuk menonaktifkan enkripsi. Ingatlah bahwa kami berusaha membuat salinan lebih cepat .
lgeorget
3
@ Lgeorget Saya menduga overhead enkripsi tidak akan signifikan, mengingat betapa lambatnya hard drive. Saya mempertimbangkan untuk menambahkan sesuatu -c none, tetapi itu tampaknya tidak standar .
Pasang kembali Monica
1
Kami berurusan sedang dengan file ~ 20G sehingga adalah sangat tidak efisien untuk menggunakan enkripsi jika tidak dibutuhkan.
lgeorget
1
@lgeorget Enkripsi dapat dilakukan jauh lebih cepat daripada throughput yang didapatnya, sehingga tidak akan memperlambat apa pun. Tapi sepertinya tidak perlu melalui SSH di sini. Jika Anda hanya butuh kompresi pasti ada alat lain?
Thomas
@ Thomas Keuntungan dari SSH adalah bahwa jika Anda seharusnya memiliki akses ke server jauh, maka hampir pasti menjalankan SSH. Pilihan lain adalah mengompres file secara lokal, menyalinnya ke server, lalu sshmasuk dan mendekompresnya ..
Pasang kembali Monica
8

The cppelaksanaan kemungkinan besar tidak hambatan. Cobalah untuk mengamati penggunaan IO melalui iotopserver dan node cluster. Ini akan memberi Anda ide di mana Anda dapat meningkatkan kinerja.

Kiat lain, adalah menghindari menyalin data yang sama dari host yang sama. Misalnya, jika Anda memiliki file 20G yang identik untuk didistribusikan dari server file ke semua node cluster, itu akan bekerja lebih cepat jika Anda menyalin file dengan cara peer-to-peer daripada satu server-ke-semua-klien. Agak lebih rumit untuk diimplementasikan, tetapi Anda bahkan dapat mencoba menggunakan beberapa baris perintah p2p seperti hub koneksi langsung.

Jika dalam file 20G itu, beberapa bagian adalah umum, dan beberapa lainnya adalah cluster node spesifik, pertimbangkan untuk membaginya menjadi bagian yang umum, dan bagian tertentu, dan kemudian bagikan bagian yang umum dengan cara P2P.

Michał Šrajer
sumber
1
Jika Anda menggunakan LAN, Anda harus bisa melakukan multicast daripada peer-to-peer. Yang harus lebih cepat, dan lebih sedikit memuat di jaringan.
derobert
8

Sifat / isi dari file-file itu dapat membuat perbedaan. Saya mengerti bahwa Anda perlu menyalin 200 file, masing-masing ~ 20 GB, dari satu komputer ke komputer lain, apakah itu?

Jika file-file itu kompresibel atau dengan potongan yang serupa / identik, Anda memiliki dua pendekatan:

  • zip mereka sebelum menyalin, atau membuat terowongan antara komputer dengan zip memungkinkannya. Jadi, jika jaringan adalah hambatan, itu akan menjadi sedikit lebih cepat

  • jika file sangat mirip, atau berbagi beberapa konten umum di antara mereka, coba gunakan rsync . Ini akan menghabiskan waktu mencari apa yang umum di antara file, dan tidak perlu menyalinnya secara harfiah , karena itu akan merekonstruksi berdasarkan apa yang umum.

sunting

Apakah Anda perlu menyalin file-file itu berkali-kali ?? (seperti salinan -> gunakan file-file itu -> ubah sesuatu di file di komputer A -> salin file lagi ke komputer B)

Jika demikian, rsync akan membantu, karena ia akan mencoba mendeteksi apa yang sama di antara versi-versi dan tidak menyalin apa yang tidak berubah.

Dan metode ketiga: jika hal di atas benar (perubahan dalam file, kemudian salin semua file lagi ke komputer kedua) Anda dapat mencoba beberapa binary diffuntuk hanya mengubah di komputer kedua apa yang diubah di komputer pertama.

woliveirajr
sumber
6

Saya melihat yang berikut di sini, enkripsi bukan ide yang baik karena mungkin MENINGKATKAN jumlah data yang akan ditransfer.

Jika Anda menyalin antara dua sistem, maka bottleneck tentu saja koneksi antara server.

Jika Anda menyalin secara lokal, lihat bagaimana prosesnya, itu adalah ulir TUNGGAL, jadi gunakan utilitas Linux standar:

- for all blocks in a file
      read a block
      write a block

Tidak ada konkurensi untuk operasi ini.

Untuk mempercepat, Anda dapat menggunakan sesuatu seperti ini:

  buffer -i infile -o outfile -m size-of-shared-memory-default-1MByte

Lihat halaman manual buffer (1) untuk informasi lebih lanjut.

Perintah buffer mengatur dua proses untuk menjalankan proses penyalinan secara bersamaan: satu untuk membaca, dan yang lainnya untuk menulis, dan itu menggunakan buffer memori bersama untuk mengkomunikasikan data antara dua proses. Buffer memori bersama adalah buffer melingkar klasik Anda yang mencegah menimpa data tidak tertulis dan penulisan data yang sudah ditulis. Saya telah menggunakan program ini untuk memotong sekitar 10-20% waktu penyalinan dalam transfer dari disk ke tape.

mdpc
sumber
Sebenarnya, ada konkurensi dalam "baca blok / tulis blok" karena "tulis blok" sebenarnya hanya menempatkannya di buffer kernel, dan kernel menangani blok tulis aktual di latar belakang (setidaknya, sampai Anda mulai kehabisan RAM). Atau jika Anda menggunakan O_DSYNC / O_SYNC karena beberapa alasan.
derobert
3

Mengapa tidak mencoba algoritme propagasi P2P, jika Anda perlu memperbarui seluruh cluster Anda secara bersamaan?

https://github.com/lg/murder adalah yang digunakan twitter

Ada BTSync yang bisa Anda coba juga.

Gui13
sumber
1

Jika Anda sering menyalin set file yang sama dari komputer lokal Anda ke server dengan sedikit perubahan di sana-sini. Anda dapat mempercepat transfer dengan menggunakan rsync atau DVCS (mis. Hg atau git).

git atau hg dapat melacak dan mendeteksi delta dan hanya mentransfer delta-delta itu. Dalam kasus menggunakan git, karena kedua belah pihak memiliki sejarah repositori, mencari tahu delta sangat murah.

rsync menggunakan bentuk algoritma rolling checksumming untuk mendeteksi delta tanpa pengetahuan sebelumnya tentang apa yang ada di sisi lain. Meskipun dibutuhkan lebih banyak pekerjaan untuk rsync untuk menghitung delta, ia tidak perlu menyimpan seluruh riwayat file.

Lie Ryan
sumber
1

Anda mungkin ingin mencoba mengemas semua file menjadi satu arsip (tidak perlu dikompres). Dalam pengalaman saya, menyalin satu arsip lebih cepat daripada menyalin sejumlah besar file individual

Munim
sumber
3
Pengamatan generik yang baik, tetapi seperti pertanyaan mengatakan "~ 200 file besar - masing-masing ~ 20 GB", saya tidak percaya ini dapat dianggap sebagai jawaban aktual untuk masalah ini .
manatwork
@manatwork ah .. saya tidak membaca dengan jelas. Saya pikir dia memiliki 200 file total 20gb
Munim
0

Coba bbcp . Pengujian di lingkungan kami mengungkapkan bahwa cp memiliki semacam built in governer. Berhati-hatilah karena ketika Anda melepas gubernur, Anda dapat membuat garis merah server Anda dan menyebabkan pemadaman. Dalam kasus kami, kami membuat server offline untuk menyalin, jadi lebih cepat lebih baik. Ini meningkatkan waktu transfer beberapa jam.

James Shewey
sumber
0

Pastikan file target tidak ada sebelum menyalin.

Terkadang mengejutkan betapa banyak waktu yang dihabiskan bahkan hanya menyalin pada host yang sama (tidak ada jaringan yang terlibat).

Lihat jawaban saya untuk pertanyaan cp lain di sini . Singkatnya, menimpa file yang sudah ada jauh lebih lambat daripada memotongnya atau memutuskan tautannya terlebih dahulu, lalu menyalin. Yang terakhir adalah 8x lebih cepat untuk file 1.2GB.

Pierre D
sumber