Disk / disk kopyasını yavaşlat


28

Linux'ta kopyalama işlemini yavaşlatan bir yöntem var mı?

Büyük bir dosyam var, 10GB diyelim ve başka bir dizine kopyalamak istiyorum, ancak tam hızda kopyalamak istemiyorum. Diyelim ki daha hızlı değil, 1mb / s hızında kopyalamak istiyorum. Standart bir Linux cpkomutu kullanmak istiyorum .

Mümkün mü? (Evet ise nasıl?)

Düzenleme : yani, elde etmeye çalıştığım şeye daha fazla bağlam ekleyeceğim.

Büyük dosyaları USB üzerinden (pendrive'a, usb diske, vb.) Kopyalarken ArchLinux sisteminde bir sorunum var. USB arabellek önbelleğini doldurduktan sonra, sistemim yanıt vermeyi kesiyor (fare bile duruyor; yalnızca düzensiz hareket ediyor). Kopyalama işlemi devam ediyor, ancak kutunun% 100 kaynaklarını alıyor. Kopyalama işlemi sona erdiğinde, her şey normale döner - her şey tekrar mükemmel şekilde yanıt verir.

Belki bir donanım hatasıdır, bilmiyorum ama bu sorunla karşılaştığım iki makinem olduğunu biliyorum (ikisi de ArchLinux'da, biri masaüstü kutusu, ikincisi dizüstü bilgisayar).

Bunun için en kolay ve en hızlı "çözüm" (bunun 'gerçek' çözüm değil, sadece çirkin bir 'kesmek' olduğunu kabul ediyorum), bu dosyanın USB sürücünün ortalama yazma hızında kopyalayarak bu arabellek doldurmasını engellemek olur. Bana bu yeterli olurdu.


7
Sistemdeki diğer G / Ç işlemlerine "iyi" olmak amacıyla diskten diske kopya hızını sınırlamak istiyorsanız, çekirdeğin G / Ç zamanlamasını ayarlama yeteneğinden yararlanmanız muhtemelen daha iyi olacaktır. yerine. Özellikle, ionicediskten diske kopyalama işleminizin normal işlemlerden daha düşük önceliğe sahip bir G / Ç olarak planlandığından emin olmak için kullanılabilir.
Steven Pazartesi

3
Bu klasik bir XY problemi sorusudur. Bunun yerine, dosyaları bir USB cihazına kopyalarken masaüstünüzün neden yanıt vermeyeceğini sormalısınız.
Michael Hampton

4
Linux bugünlerde gülünç derecede büyük G / Ç tamponlarına sahiptir. RAM boyutları, yığın depolama hızlarından daha hızlı büyümüştür. Belki kopyayı dd (1) kullanarak gerçekleştirebilir ve senkronize edebilirsiniz, böylece tamponlama yapmak yerine periyodik olarak senkronize edilebilir? Ve boru görüntüleyici (pv) bir hız sınırlama seçeneğine sahiptir. Gibi bir şey cat file | pv -L 3k > outfile. Yine de ikisi de cp (1) kullanmakla aynı değildir.
ptman

@MichaelHampton, bu konuda ArchLinux forumunda çözülmemiş birkaç konu var, bu yüzden sadece çalışmasını sağlamak için farklı bir yolla başa çıkacağımı düşündüm.
antonone

@antonone Ancak Unix.SE, ArchLinux'un forumları değildir. Buradaki birinin bir çözümü olabilir.
Izkata

Yanıtlar:


23

Bir boruyu kısaltabilirsiniz pv -qL(veya cstream -tbenzer işlevler sağlar)

tar -cf - . | pv -q -L 8192 | tar -C /your/usb -xvf -

-q stderr ilerleme raporlamasını kaldırır.

-LSınır bayt yer almaktadır.

--rate-limit/-LBayrakla ilgili daha fazlası man pv:

-L RATE, --rate-limit RATE

    Limit the transfer to a maximum of RATE bytes per second.
    A suffix of "k", "m", "g", or "t" can be added to denote
    kilobytes (*1024), megabytes, and so on.

Bu cevap aslında işaret etti throttleancak bu proje artık mevcut değil, bu nedenle bazı paket sistemlerinden kaçtı.


Eğer cpo zaman özel bir komutunu kullanarak, yavaşlamış olamaz sanırım tek seçenektir.
antonone

1
Kulağa çok karmaşık geliyorrsync
03'te LinuxSecurityFreak

daha karmaşık görünüyor ama benim için daha kullanışlı. Bir dosya kilitleme mekanizmasını test etmeniz ve rsync ile mümkün görünmeyen bazı bayt / sn'lere kopyalamayı yavaşlatmanız gerekir. Bir deneyin ve gaz kelebeği borusundan bir dosya 'kedi' ver
cljk

Söylemek üzücü ama proje öldü. bugs.debian.org/cgi-bin/bugreport.cgi?bug=426891
cljk

1
@cljk güncellendi pv. Teşekkürler.
Matt

23

Bunun yerine , bant genişliğini istediğiniz gibi cp -a /foo /barkullanabilir rsyncve sınırlandırabilirsiniz.

Kullanım rsynckılavuzundan:

--bwlimit=KBPS

limit I / O bant genişliği; Saniyede KByte

Böylece, ilerlemeyi gösteren actuall komutu şöyle görünür:

rsync -av --bwlimit=100 --progress /foo /bar

Bu, eski sürücüleri kopyalamak için güzel bir fikir gibi görünmek istemiyorum.
jeremyjjbrown

/dev/zeroVeya /dev/random
cdosborn'dan

rsync -a --bwlimit=1500 /source /destinationdev klasörleri 1,5 MB / s hızında kopyalamak için mükemmel şekilde çalışır (bu, herhangi bir sunucunun yavaşlamasını engellemek ve çok fazla zaman
almamak arasında başarılı bir işlemdir

Sidenote: man sayfası, birimler için harfler kullanabileceğinizi söylese bile, örneğin 20m, tüm platformlarda desteklenmiyor, bu yüzden KBytes notasyonuna daha iyi yapışmalısınız.
Hubert Grzeskowiak

günümü kurtardım! cgroup cgexec -g ... cp /in /outher zaman işe yaramadı (terminalden bazı zamanlarda çalıştı, asla senaryodan değildi) ve nedenini bilmiyorum ...
Kova Gücü

13

Başka bir etkinliği bozmamaya çalıştığını varsayardım. Linux'un son sürümleri arasında ionice, IO'nun zamanlamasını kontrol etmenize olanak tanıyan dahil .

Çeşitli önceliklere izin vermenin yanı sıra, diski boşta tuttuğunuz zamanları GÇ ile sınırlamak için ek bir seçenek de vardır. Komut man ionicedokümantasyonu gösterecektir.

Aşağıdaki gibi bir komut kullanarak dosyayı kopyalamayı deneyin:

ionice -c 3 cp largefile /new/directory

İki dizin aynı aygıttaysa, dosyayı bağlayarak istediğiniz şeyi yaparsınız. Yedekleme amacıyla kopyalama yapıyorsanız, bu seçeneği kullanmayın. lndosyanın kendisi kopyalanmadığı için oldukça hızlıdır. Deneyin:

ln largefile /new/directory

Veya farklı bir cihazdaki bir dizinden erişmek istiyorsanız:

ln -s largefile /new/directory

Ionice Linux'ta iyi çalışıyor mu? "taklit" çalışmasını okudum ve gerçek bir fark yok mu? Bağlantılar için +1
Nick

1
@Nick Kullandığımda, beklendiği gibi davrandı. İyonice uyguladığım süreç önemli ölçüde yavaşladı, I / O gerektiren diğer işlemler de beklendiği gibi gerçekleştirildi. Diğer işlemlerden orta derecede bir G / Ç yüküyle, beklendiği gibi maksimum 'şıklık' uygulayarak yüksek bir G / Ç işlemini etkili bir şekilde askıya aldım. Rekabetçi bir G / Ç olmadığında, iyonlaştırılmış işlem normal olarak gerçekleştirildi.
BillThor

400 MB'lık bir dosya ile bir HD'den bir SSD'ye kopyalamıştım, ilk 10s mükemmel çalıştı, sonra aniden yüksek IO yükü gördüm ve donmuş bir dakika beklemek zorunda kaldım: /. Cgroup'un bazen çalıştığı yerdeki gaz kelebeği yazmada ve bazılarında çalışmayacaksa da aynı sorunu yaşıyorum.
Kova Gücü

7

Eğer ioniceçözüm yeterli değilse (nedense) ve gerçekten G / Ç'yi mutlak bir değerle sınırlamak istiyorsanız, birkaç olasılık vardır:

  1. Muhtemelen en kolay: ssh. Dahili bir bant genişliği sınırlaması vardır. Örneğin tar(yerine cp) veya scp(yeterince iyi olsaydı; sembolik bağlantıları ve sert bağlantıları nasıl kullandığını bilmiyorum) ya da kullanırdınız rsync. Bu komutlar verilerini yönlendirebilir ssh. "Uzak" tarafta başka bir yürütme istemciye (veya ) taryazmak ve boruya yazmak durumunda ./dev/stdout-sshtar

  2. zarif ama vanilya çekirdeğinde değil (AFAIK): Cihaz eşleyici hedefi ioband. Bu, elbette, sadece kaynak veya hedef hacmi ayarlayabiliyorsanız çalışır.

  3. bazı yazılı yazılı eğlence: grep "^write_bytes: " /proc/$PID/iosize bir işlemin yazdığı veri miktarını verir. cpArka planda başlayan , örneğin 1/10 saniye boyunca uyuyan, arka plan cpişlemini durduran ( kill -STOP $PID), yazılan miktarı kontrol eden (ve bu durumda aynı değer hakkında okunan) bir komut dosyası yazabilirsiniz. cpOrtalama aktarım hızını istenen değere düşürmek için duraklatmanız, bu süre için uyuman, uyanmanız cp( kill -CONT $PID) vb.


Evet, normalde scp ile localhost'a bağlanmak için lftp kullanıyorum ve oradaki bandwich'i sınırlandırıyorum.
antonone

5

Sorununuz muhtemelen bilgisayarınızda değil, kendi başınıza, muhtemelen sorun değil. Ancak bu USB flaş geçiş katmanı,% 90 hatalı flaş çipinin ne kadar olabileceğini telafi etmek için tüm yazdıklarınızı ortaya çıkarmak zorunda olan kendi işlemcisine sahiptir, kim bilir? Su bastın, sonra tamponlarını su bastın, sonra bütün otobüsü suya attın, sonra sıkışıp kaldın, dostum - sonuçta, tüm eşyalarının olduğu yer orası. Karşı sezgisel gelebilir, ancak gerçekte ihtiyacınız olan G / Ç'yi engellemektir - FTL'nin hızı ayarlamasına ve sonra da devam etmesine izin vermeniz gerekir.

(FTL mikro denetleyicilerini hacklemek üzerine: http://www.bunniestudios.com/blog/?p=3554 )

Yukarıdaki cevapların hepsi işe yaramalı, bu daha çok "benim de!" Olmalı. her şeyden çok: Tamamen orada bulundum adamım. Rsync - bwlimit arg ile kendi sorunlarımı çözdüm (2.5 mbs, tek, hatasız bir çalışma için güzel bir nokta gibi görünüyordu - daha fazlası ve yazmaya karşı koruma hatalarıyla giderim). rsync özellikle amacım için uyguntu çünkü tüm dosya sistemleriyle çalışıyordum - bu yüzden çok fazla dosya vardı - ve basitçe rsync'i ikinci kez çalıştırmak, ilk çalışmamın tüm sorunlarını çözecekti (sabırsızlanıp denediğimde gerekliydi. 2.5 mbs geçmiş rampa).

Yine de, sanırım bu tek bir dosya için pek pratik değil. Sizin durumunuzda ham-yazmaya ayarlanmış sadece gg'ye geçebilirdiniz - herhangi bir girişi bu şekilde halledebilirsiniz, ancak bir seferde sadece bir hedef dosya (tek bir dosya elbette tüm bir blok cihaz olsa da).

## OBTAIN OPTIMAL IO VALUE FOR TARGET HOST DEV ##
## IT'S IMPORTANT THAT YOUR "bs" VALUE IS A MULTIPLE ##
## OF YOUR TARGET DEV'S SECTOR SIZE (USUALLY 512b) ##
% bs=$(blockdev --getoptio /local/target/dev)

## START LISTENING; PIPE OUT ON INPUT ##
% nc -l -p $PORT | lz4 |\ 
## PIPE THROUGH DECOMPRESSOR TO DD ## 
>    dd bs=$bs of=/mnt/local/target.file \
## AND BE SURE DD'S FLAGS DECLARE RAW IO ##
>        conv=fsync oflag=direct,sync,nocache

## OUR RECEIVER'S WAITING; DIAL REMOTE TO BEGIN ##
% ssh user@remote.host <<-REMOTECMD
## JUST REVERSED; NO RAW IO FLAGS NEEDED HERE, THOUGH ## 
>    dd if=/remote/source.file bs=$bs |\
>    lz4 -9 | nc local.target.domain $PORT
> REMOTECMD  

Netcat'ı bir veri çekerseniz veri aktarımı için ssh'den biraz daha hızlı bulabilirsiniz. Neyse, diğer fikirler çoktan alındı, öyleyse neden olmasın?

[EDIT]: Diğer yazıdaki lftp, scp ve ssh ifadelerinden bahsettim ve uzak bir kopyadan bahsettiğimizi düşündüm. Yerel çok daha kolay:

% bs=$(blockdev --getoptio /local/target/dev)
% dd if=/src/fi.le bs=$bs iflag=fullblock of=/tgt/fi.le \
>    conv=fsync oflag=direct,sync,nocache

[EDIT2]: Ödünç verildiği yerdeki kredi: fark etmeden önce ptman yorumda beni beş saat kadar dövdü.

Kesinlikle burada bs için performans için $ bs ayarlayabilirsin - ancak bazı dosya sistemleri hedef f'in sektör boyutunun bir katı olmasını gerektirebilir, bu yüzden bunu aklında tut.


--getioopt--getoptio
Makinemde

2

Sorun, kopyanın hafızanızı "uçuşta" "kalabalığa" yararlı "verilerle bloklarla doldurmasıdır. Linux çekirdeğinde I / O'nun yavaş aygıtlara taşınmasında bilinen bir (ve çok zor) bir hata (bu durumda USB).

Belki de kopyalamayı dağıtmayı deneyebilirsiniz, örneğin aşağıdaki gibi bir komut dosyasıyla (kavram kanıtı taslağı, tamamen denenmemiş!):

while true do
  dd if=infile of=outfile bs=4096 count=... seek=... skip=...
  sleep 5
done

ayarlayarak seekve skipile counther turda. Ayarlanması countgerekir, böylece belleği doldurmaz (çok fazla) ve 5boşaltmasına izin verin.


2

Kirli sayfa sınırını düşürün. Varsayılan sınır delilik.

/Etc/sysctl.d/99-sysctl.conf dosyasını şununla oluşturun:

vm.dirty_background_ratio = 3
vm.dirty_ratio = 10

Sonra sysctl -p komutunu çalıştırın veya yeniden başlatın.

Gerçek şu ki, veriler hedef diske yazıldığından daha hızlı okunuyor. Linux dosyaları kopyaladığında, yaptıkları RAM içine okunur, ardından sayfaları hedefe yazmak için kirli olarak işaretleyin. Kirli sayfalar değiştirilemez. Bu nedenle, kaynak disk hedef diskten daha hızlıysa ve ücretsiz RAM’izden daha fazla veri kopyalıyorsanız, kopyalama işlemi kullanılabilir tüm RAM’leri (veya en azından kirli sayfa sınırı ne olursa olsun Kullanılabilir RAM) ve kirli sayfalar değiştirilemediğinden ve temiz sayfalar serbest bırakıldıkça kirli ve işaretli olduklarından açlığa neden olur.

Onun sorunu tamamen çözemeyeceğine dikkat edin ... linux'un gerçekte ihtiyacı olan şey kirli sayfaların oluşturulmasını sağlamak için bir yoldur, bu nedenle büyük bir transfer gerçekleşmekte olan tüm RAM / tüm izin verilen kirli sayfaları yemez.


0

Bu problemin donanım veya yazılımdaki hatalar veya hatalarla ilgisi yoktur, sadece çekirdeğiniz size iyi davranmaya ve arka planınıza hemen geri vermeyi ve kopyalamayı sağlar (çekirdek içi önbellek kullanır: daha fazla RAM, daha fazla önbellek, ancak / proc içine bir yere yazarak bunu sınırlandırabilirsiniz - yine de tavsiye edilmez). Flash sürücüler çok yavaş ve çekirdek üzerine yazarken, diğer IO işlemleri yeterince hızlı gerçekleştirilemiyor. ionicediğer cevaplarda da birkaç kez bahsedilen tamam. Ancak, -o syncişletim sistemi tamponlamasını önlemek için sürücüyü yalnızca monte etmeyi denediniz mi? Muhtemelen buradaki en basit çözüm.


-O senkronizasyonu etkinleştirdikten sonra, İnternet'im bu USB sürücüye yazma hızından daha hızlı. Anlamadığım şey neden çekirdeğin önbellek sayfalarının ne kadar çabuk temizlendiğini izlememesi ve buna bağlı olarak gelecekteki yıkamaları planlamak. Sanki bu zayıf sürücü hıza ayak uyduramasa bile her zaman tam hızda ilerliyor. Ama bu sanırım başka bir soru için bir konu.
antonone
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.