Donanım kaynaklarına dökülmeyen anında akış sıkıştırma?


23

200 GB boş disk alanım var, 16 GB RAM (bunlardan ~ 1 GB masaüstü ve çekirdeğin kapladığı) ve 6 GB takas.

240 GB harici SSD'm var, 70 GB kullanılmış 1 ve gerisi ücretsiz, diskime yedeklemem gerekiyor.

Normalde, önce dd if=/dev/sdb of=Desktop/disk.imgdiski ve ardından sıkıştırırdım, ancak görüntüyü ilk yapmak bir seçenek değildir, çünkü bunu yapmak benimkinden çok daha fazla disk alanı gerektirir, ancak sıkıştırma adımı boş alanın ezilmesine neden olur. son arşiv diskime kolayca sığabiliyor.

ddvarsayılan olarak STDOUT'a yazar ve STDIN'den gzipokuyabilir, bu yüzden teoride yazabilirim dd if=/dev/sdb | gzip -9 -, ancak gzipbaytları okumak ddonları üretebileceklerinden çok daha uzun sürer .

Kimden man pipe:

Borunun yazma ucuna yazılan veriler, borunun okunan ucundan okunana kadar çekirdek tarafından tamponlanır.

|Birinin gerçek bir boru gibi göründüğünü hayal ediyorum - biri uygulamada veri toplayan, diğeri ise borunun kuyruğundan mümkün olan en kısa sürede veri alıyor.

Sol taraftaki program borunun diğer tarafına göre daha hızlı veri yazdığında ne işleyeceğini umarız? Aşırı belleğe mi yoksa takas kullanımına mı neden olacak, yoksa çekirdek diskte bir FIFO oluşturmaya çalışıp diski doldurmaya çalışacak mı? Yoksa SIGPIPE Broken pipetampon çok büyükse sadece başarısız olur ?

Temel olarak, bu iki soruya yol açar:

  1. Bir kerede okunandan daha fazla veriyi bir boruya aktarmanın sonuçları ve sonuçları nelerdir?
  2. Sıkıştırılmamış tüm veri akışını diske koymadan bir veri akışını diske sıkıştırmanın güvenilir yolu nedir?

Not 1: İlk kullanılan 70 GB'nin tamamını tam olarak kopyalayamıyorum ve tam bir içeriğin bozulmasını gerektiren parçalanma ve diğer şeyler nedeniyle bir çalışma sistemi veya dosya sistemi almayı umuyorum.


Neden sadece kullanıcı dizinleri yerine, belki de kurulu olan standart dışı yazılımların bir listesini yerine, bunun gibi bir dosya sistemini neden yedeklediniz?
jamesqf

5
@jamesqf Eg. çünkü restore etmek çok daha kolay ...
deviantfan

4
@jamesqf Çünkü o zaman önyükleme sektörünü ve takas bölümünü de alıyorum, böylece diski milyarlarca sinir bozucu dosya yerine tam olarak yeniden oluşturabilirim.
kedi

3
Rastgele ipucu: lzopyerine gzip; sadece biraz daha düşük sıkıştırma oranı ile çok daha hızlı sıkıştırır. Sıkıştırma hızının gerçek bir darboğaz olabileceği disk görüntüleri için ideal buluyorum.
marcelm

1
“Sol taraftaki program, borunun diğer tarafına göre daha hızlı veri yazdığında ne işleyeceğini umarız?” Çekirdek, boruda daha fazla yer alana kadar yazma işleminin uyumaya neden olur.
Tavian Barnes

Yanıtlar:


16

Teknik olarak ihtiyacınız yok bile dd:

gzip < /dev/drive > drive.img.gz

Eğer kullanımını yaparsanız dd, her zaman gibi varsayılan blok boyutundan daha büyük ile gitmeli dd bs=1Mveya syscall cehennem acı ( ddo zamandan beri 'ın varsayılan blokboyu, 512 bayt read()s ve write()var ler 4096başına syscalls MiBçok fazla havai).

gzip -9bunun için göstermek için çok az bir LOT daha fazla CPU kullanır. Eğer gzipsizi yavaşlatıyor, sıkıştırma düzeyini düşürmek veya farklı (daha hızlı) sıkıştırma yöntemini kullanın.

ddGörüntüler yerine dosya tabanlı yedeklemeler yapıyorsanız , sıkıştırıp sıkıştırmamaya karar veren bir mantığa sahip olabilirsiniz (çeşitli dosya türleri için bunu yapmanın bir anlamı yoktur). dar( taralternatif`) bunu yapma seçeneği olan bir örnektir.

Boş yer SIFIR ise (bir SSD çünkü güvenilir döner TRIM sonra sıfır ve kaçtın o fstrimve önbelleklerini düştü) ayrıca kullanabilirsiniz ddile conv=sparsekullanımları sıfır alanlar için disk alanı sıfır olduğu sıkıştırılmamış, döngü monte, seyrek bir görüntü oluşturmak için bayrak . Görüntü dosyasının, seyrek dosyaları destekleyen bir dosya sistemi tarafından desteklenmesini gerektirir.

Alternatif olarak, bazı dosya sistemlerinde yalnızca kullanılan alanları görüntüleyebilecek programlar vardır.


1
"Dd kullanıyorsanız, her zamanki gibi varsayılan blok boyutundan daha büyükdd bs=1M olmalısınız " - Yapabilirsiniz, ancak çok fazla beklemeyin. Bilgisayarımda dd512 baytlık bloklarla yaklaşık 2GB / sn yapacak. Bu darboğaz olmayacak; gzipolacak.
marcelm

@ marcelm Ne tür bir makine kullandığını asla bilemeyiz. dd512 baytlık bloklarla 2GB / sn'ye sahipseniz , işlem sırasında% 100'lük bir CPU çekirdeğini maksimuma çıkarmamış olsam şaşırırdım. Şimdi, kutunuz zaten boşta oturan bir quadcore ise, bir fark görmeyebilirsiniz. Yine de herkes hala var.
frostschutz

9
İç çekmek. Her zaman ddblokboyu insanlar nitpicking gelip, bahsedilmiştir. gzipCPU yoğun olmak da benim cevabımın bir parçasıydı, tamam mı? Üzgünüm, "önemsiz" ile aynı fikirde değilim. Sadece konser başına 1-2s ekleyebilir gzip -9(ancak yüzlerce konser işlenirken yine de dakika lzop -1tutarındadır ) ancak konser başına 1s vs konser başına tavsiyelerde bulunmak . Patates üzerinde test edilmiştir (tek çekirdekli vserver). Aklı başında bir engelleme eklemek ddhiçbir maliyeti yoktur ve sıfır dezavantajı vardır. Nitpick yapmayın. Sadece yap. ymmv
frostschutz

19

ddher seferinde bir blok veri okur ve yazar ve sadece bir blok üstündür. Yani

valgrind dd if=/dev/zero status=progress of=/dev/null bs=1M

ddyaklaşık 1 MB hafıza kullandığını gösterir . Hızı valgrindüzerindeki etkisini görmek için blok büyüklüğü ile oynayabilir ve düşürebilirsiniz dd.

İçine girdiğinde gzip, ddhızını eşleştirmek için yavaşla gzip. Onun bellek kullanımı artmaz, ne de (çekirdek dışında bunun nasıl bilmiyor diskteki tamponlarını saklamak için çekirdek neden vermez aracılığıyla takas). Kırık bir boru yalnızca borunun uçlarından biri öldüğünde gerçekleşir; ayrıntılar için bkz. signal(7)ve write(2).

Böylece

dd if=... iconv=fullblock bs=1M | gzip -9 > ...

peşinde olanı yapmak için güvenli bir yoldur.

Borularda, okuma işlemi devam etmiyorsa, yazma işlemi çekirdek tarafından engellenir. Bunu çalıştırarak görebilirsiniz

strace dd if=/dev/zero bs=1M | (sleep 60; cat > /dev/null)

1 ddMB okuduğunu görüyorsunuz , daha sonra yayınlanırken write()orada bir dakika beklediğini görüyorsunuz sleep. Borunun her iki tarafı da böyle dengelendi: Çekirdek blokları, yazma işleminin çok hızlı olup olmadığını ve okuma işleminin çok hızlı olup olmadığını da okur.


1
Bu oldukça havalı. Hangi mekanizma ile hızını ddeşleştirmek için yavaşlamayı biliyor gzip? Çekirdek tarafından olduğu gibi otomatik mi yoksa çıktı dosyası tanımlayıcısı hakkında meta verilerden hesaplıyor mu?
kedi,

9
@ cat Bu otomatik; boruya veri koymak için ddçağırır write(). write()aslında kontrolü çekirdeğe aktarır, böylece boru belleğini değiştirebilir. Çekirdek borunun dolu olduğunu görürse, boru yeterince yer alana kadar bekleyecektir ("blok"). Ancak o zaman write()çağrı sona erecek ve kontrolü tekrar kontrol edecek dd, bu şekilde tekrar boruya veri yazacaktır.
marcelm

9

Performanstan başka olumsuz bir çıkarım yoktur: borunun genellikle 64K olan bir tamponu vardır ve bundan sonra boruya bir yazma işlemi gzipdaha fazla veri okuyana kadar bloke olur .


8

Asıl soruyu nasıl çalıştığına göre cevaplamak: "eğer sol taraftaki program borunun diğer tarafından daha hızlı veri yazıyorsa, işleyebileceğini umar?"

Bu olmaz. Boruda oldukça küçük, sınırlı boyutlu bir tampon var; bkz . Boru tamponu ne kadar büyük?

Boru tamponu dolduğunda, gönderen program bloke eder . Yazma çağrısı yaptığında, veriler arabellek içine yazılana kadar çekirdek programa kontrolü geri döndürmez. Bu, okuma programına CPU'nun arabellek boşaltılacağı zamanı verir.


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.