Apakah ada metode memperlambat proses penyalinan di Linux?
Saya memiliki file besar, katakanlah 10GB, dan saya ingin menyalinnya ke direktori lain, tetapi saya tidak ingin menyalinnya dengan kecepatan penuh. Katakanlah saya ingin menyalinnya dengan kecepatan 1mb / s, tidak lebih cepat. Saya ingin menggunakan cp
perintah Linux standar .
Apakah ini mungkin? (Jika ya, bagaimana?)
Sunting : jadi, saya akan menambahkan lebih banyak konteks ke apa yang saya coba capai.
Saya memiliki masalah pada sistem ArchLinux ketika menyalin file besar melalui USB (ke flashdisk, disk usb, dll). Setelah mengisi cache buffer usb, sistem saya berhenti merespons (bahkan mouse berhenti; hanya bergerak secara sporadis). Operasi penyalinan masih berlangsung, tetapi membutuhkan sumber daya 100% dari kotak. Ketika operasi penyalinan selesai, semuanya kembali normal - semuanya kembali responsif sempurna.
Mungkin itu adalah kesalahan perangkat keras, saya tidak tahu, tapi saya tahu saya punya dua mesin dengan masalah ini (keduanya ada di ArchLinux, satu adalah kotak desktop, kedua adalah laptop).
"Solusi" termudah dan tercepat untuk ini (saya setuju itu bukan solusi 'nyata', hanya 'hack' jelek) akan mencegah buffer ini dari mengisi dengan menyalin file dengan kecepatan tulis rata-rata dari drive USB, untuk saya itu sudah cukup.
sumber
ionice
dapat digunakan untuk memastikan bahwa proses penyalinan disk-ke-disk Anda dijadwalkan I / O pada prioritas yang lebih rendah daripada proses biasa.cat file | pv -L 3k > outfile
. Namun, keduanya tidak sama dengan menggunakan cp (1).Jawaban:
Anda dapat menekan pipa dengan
pv -qL
(ataucstream -t
menyediakan fungsi serupa)-q
menghapus pelaporan kemajuan stderr.The
-L
batas dalam bytes.Lebih lanjut tentang
--rate-limit/-L
bendera dariman pv
:Jawaban ini awalnya menunjuk
throttle
tetapi proyek itu tidak lagi tersedia sehingga telah keluar dari beberapa sistem paket.sumber
cp
tidak dapat diperlambat, maka menggunakan perintah khusus adalah satu-satunya pilihan yang saya kira.rsync
pv
. Terima kasih.Alih-alih
cp -a /foo /bar
Anda juga dapat menggunakanrsync
dan membatasi bandwidth yang Anda butuhkan.Dari
rsync
manual:Jadi, perintah yang sebenarnya, juga menunjukkan kemajuan, akan terlihat seperti ini:
sumber
/dev/zero
atau/dev/random
rsync -a --bwlimit=1500 /source /destination
berfungsi dengan sempurna untuk menyalin folder raksasa dengan kecepatan 1,5 MB / s (yang merupakan pertukaran yang baik antara menghindari server yang melambat dan tidak mengambil terlalu banyak waktu)20m
, itu tidak didukung pada semua platform, jadi lebih baik tetap berpegang pada notasi KBytes.cgexec -g ... cp /in /out
tidak berfungsi sepanjang waktu (dari terminal bekerja beberapa kali, dari script tidak pernah) dan saya tidak tahu mengapa ...Saya menganggap Anda berusaha untuk tidak mengganggu aktivitas lainnya. Versi Linux terbaru termasuk
ionice
yang memungkinkan Anda untuk mengontrol penjadwalan IO.Selain memungkinkan berbagai prioritas, ada opsi tambahan untuk membatasi IO hingga saat-saat disk tidak digunakan. Perintah
man ionice
akan menampilkan dokumentasi.Coba salin file menggunakan perintah seperti:
Jika dua direktori berada di perangkat yang sama Anda mungkin menemukan menautkan file melakukan apa yang Anda inginkan. Jika Anda menyalin untuk tujuan cadangan, jangan gunakan opsi ini.
ln
sangat cepat karena file itu sendiri tidak dapat disalin. Mencoba:Atau jika Anda hanya ingin mengaksesnya dari direktori di perangkat lain, cobalah:
sumber
Jika
ionice
solusinya tidak cukup (mengapa) dan Anda benar-benar ingin membatasi I / O ke nilai absolut ada beberapa kemungkinan:yang mungkin paling mudah:
ssh
. Ini memiliki batas bandwidth bawaan. Anda akan menggunakan misalnyatar
(bukancp
) atauscp
(jika itu cukup baik; Saya tidak tahu bagaimana menangani symlink dan tautan keras) ataursync
. Perintah-perintah ini dapat menyalurkan data merekassh
. Jikatar
Anda menulis ke/dev/stdout
(atau-
) dan mengirimkannya kessh
klien yang mengeksekusi orang laintar
di sisi "remote".elegan tetapi tidak di kernel vanilla (AFAIK): Target mapper perangkat
ioband
. Ini, tentu saja, hanya berfungsi jika Anda dapat membuat umount sumber atau volume target.beberapa kesenangan yang ditulis sendiri:
grep "^write_bytes: " /proc/$PID/io
memberi Anda jumlah data yang telah ditulis oleh suatu proses. Anda dapat menulis skrip yang dimulaicp
di latar belakang, tidur misalnya 1/10 detik, menghentikancp
proses latar belakang (kill -STOP $PID
), memeriksa jumlah yang telah ditulis (dan membaca? Tentang nilai yang sama dalam kasus ini), menghitung berapa lamacp
harus berhenti untuk menurunkan laju transfer rata-rata ke nilai yang dimaksud, tidur untuk waktu itu, banguncp
(kill -CONT $PID
), dan sebagainya.sumber
Masalah Anda mungkin tidak dengan komputer Anda, karena itu mungkin baik-baik saja. Tetapi lapisan transisi flash USB memiliki prosesor sendiri yang harus memetakan semua tulisan Anda untuk mengkompensasi apa yang bisa sebanyak 90% chip flash rusak, siapa tahu? Anda membanjiri lalu membanjiri buffer, lalu membanjiri seluruh bus, lalu terjebak, bung - setelah semua, di situlah semua barang Anda. Ini mungkin terdengar kontra-intuisi tetapi yang Anda butuhkan adalah memblokir I / O - Anda harus membiarkan FTL mengatur langkahnya dan terus mengikuti.
(Saat meretas mikrokontroler FTL: http://www.bunniestudios.com/blog/?p=3554 )
Semua jawaban di atas harus berfungsi sehingga ini lebih merupakan "saya juga!" lebih dari yang lain: Aku benar-benar pernah ke sana, kawan. Saya memecahkan masalah saya sendiri dengan rsync's --bwlimit arg (2.5mbs tampaknya menjadi sweet spot untuk menjalankan tunggal, bebas kesalahan - apa pun lebih dan saya akan berakhir dengan kesalahan tulis-lindungi). rsync sangat cocok untuk tujuan saya karena saya bekerja dengan seluruh filesystem - jadi ada banyak file - dan hanya menjalankan rsync untuk kedua kalinya akan memperbaiki semua masalah run pertama (yang diperlukan ketika saya menjadi tidak sabar dan mencoba untuk melewati 2.5mbs).
Namun, saya rasa itu tidak cukup praktis untuk satu file. Dalam kasus Anda, Anda bisa melakukan pipe ke dd set ke raw-write - Anda dapat menangani input apa pun dengan cara itu, tetapi hanya satu file target pada satu waktu (meskipun file tunggal itu bisa menjadi perangkat blok keseluruhan, tentu saja).
Anda mungkin menemukan netcat sedikit lebih cepat daripada ssh untuk transportasi data jika Anda mencobanya. Bagaimanapun, ide-ide lain sudah diambil, jadi mengapa tidak?
[EDIT]: Saya memperhatikan menyebutkan lftp, scp, dan ssh di pos lain dan berpikir kami sedang berbicara tentang salinan jarak jauh. Lokal jauh lebih mudah:
[EDIT2]: Kredit yang jatuh tempo: baru sadar ptman mengalahkan saya dalam hal ini selama lima jam di komentar.
Tentunya Anda dapat menyetel $ bs untuk kinerja di sini dengan pengganda - tetapi beberapa sistem file mungkin mengharuskannya untuk menjadi kelipatan dari ukuran sektor fs jadi ingatlah itu.
sumber
--getioopt
bukan--getoptio
Masalahnya adalah bahwa salinan mengisi memori Anda dengan blok "dalam penerbangan," crowding out "berguna" data. Bug yang dikenal (dan sangat sulit untuk diperbaiki) di kernel Linux menangani I / O untuk memperlambat perangkat (USB dalam kasus ini).
Mungkin Anda bisa mencoba membagi salinannya, misalnya dengan skrip seperti berikut (sketsa proof-of-concept, sama sekali belum diuji!):
menyesuaikan
seek
danskip
olehcount
setiap putaran. Perlu disetelcount
agar tidak mengisi (terlalu banyak) memori, dan5
membiarkannya mengalir.sumber
Turunkan batas halaman kotor. Batas defaultnya gila.
Buat /etc/sysctl.d/99-sysctl.conf dengan:
Kemudian jalankan sysctl -p atau reboot.
Apa yang terjadi adalah bahwa data sedang dibaca lebih cepat daripada yang dapat ditulis ke disk tujuan. Ketika linux menyalin file, yang dilakukannya adalah membacanya ke dalam RAM, kemudian menandai halaman sebagai kotor untuk menulis ke tujuan. Halaman kotor tidak dapat ditukar. Jadi jika disk sumber lebih cepat dari disk tujuan dan Anda menyalin lebih banyak data daripada RAM gratis, operasi penyalinan akan memakan semua RAM yang tersedia (atau setidaknya apa pun batas halaman kotornya, yang bisa lebih dari RAM yang tersedia) dan menyebabkan kelaparan karena halaman yang kotor tidak dapat ditukar dan halaman yang bersih digunakan dan ditandai kotor saat mereka dibebaskan.
Perhatikan bahwa ia tidak akan sepenuhnya menyelesaikan masalah ... apa yang benar-benar dibutuhkan linux adalah beberapa cara untuk menengahi pembuatan halaman kotor sehingga transfer besar yang terjadi tidak memakan semua RAM yang tersedia / semua halaman kotor yang diizinkan.
sumber
Masalah ini tidak ada hubungannya dengan kesalahan atau kesalahan pada perangkat keras atau perangkat lunak, itu hanya kernel Anda mencoba bersikap baik kepada Anda dan memberikan prompt Anda kembali dan menyalin di latar belakang (menggunakan cache di-kernel: lebih banyak RAM, lebih banyak cache, tetapi Anda dapat membatasi dengan menulis di suatu tempat di / proc - meskipun tidak direkomendasikan). Flash drive terlalu lambat dan ketika kernel menulis di atasnya, operasi IO lainnya tidak dapat dilakukan dengan cukup cepat.
ionice
disebutkan beberapa kali dalam jawaban lain ok. Tetapi apakah Anda sudah mencoba memasang drive-o sync
untuk menghindari buffering OS? Itu mungkin solusi paling sederhana di luar sana.sumber