Değişmeyen büyük dizinin daha hızlı rsync'i


13

Sunucuları yedeklemek için rsync kullanıyoruz.

Maalesef bazı sunucuların ağı yavaş.

Rsync'in büyük dizinlerde hiçbir şeyin değişmediğini algılaması beş dakika kadar sürebilir. Bu devasa dizin ağaçları çok sayıda küçük dosya (yaklaşık 80 bin dosya) içerir.

Sanırım rsync istemcileri her 80k dosyaları için veri gönderir.

Ağ yavaş olduğundan, her dosya hakkında 80 bin kez bilgi göndermek istemiyorum.

Rsync'e bir alt dizin ağacının karma toplamını yapmasını söylemenin bir yolu var mı?

Bu şekilde rsync istemcisi büyük bir dizin ağacı için yalnızca birkaç bayt gönderir.

Güncelleme

Şimdiye kadar benim stratejim kullanmak rsync. Ama burada farklı bir araç daha uygunsa, geçiş yapabilirim. Her ikisi de (sunucu ve istemci) kontrolüm altında.

Update2

Bir dizin ağacında 80 bin dosya vardır . Her bir dizinde en fazla 2k dosya veya alt dizin yoktur

Update3

Ağın yavaşlığıyla ilgili ayrıntılar:

time ssh einswp 'cd attachments/200 && ls -lLR' >/tmp/list
real    0m2.645s

Tmp / list dosyasının boyutu: 2MByte

time scp einswp:/tmp/list tmp/
real    0m2.821s

Sonuç: scp aynı hıza sahiptir (sürpriz yok)

time scp einswp:tmp/100MB tmp/
real    1m24.049s

Hız: 1.2MB / s


1
Sen zsync okuyabilirsiniz. Kendim kullanmadım, ancak okuduğumdan, sunucu tarafında meta verileri önceden oluşturuyor ve durumunuzdaki aktarımları hızlandırabilir. Yine de test etmeye değer olabilir. Bunun ötesinde, farkında olduğum diğer tek çözüm, bazı san / nas çözümleriyle birlikte gelen gerçek zamanlı blok seviyesi senkronizasyonudur.
Aaron

Yanıtlar:


36

İlgisiz bazı noktalar:

80K birçok dosyadır.

Bir dizinde 80.000 dosya mı var? Hiçbir işletim sistemi veya uygulama varsayılan olarak bu durumu iyi işlemez. Sadece rsync ile bu sorunu fark ettiniz.

Rsync sürümünüzü kontrol edin

Modern rsync, büyük dizinleri geçmişe göre çok daha iyi işler. En son sürümü kullandığınızdan emin olun.

Eski rsync bile büyük dizinleri yüksek gecikme bağlantıları üzerinde oldukça iyi işler ... ama 80 bin dosya büyük değil ... çok büyük!

Bununla birlikte, rsync'in bellek kullanımı bir ağaçtaki dosya sayısıyla doğru orantılıdır. Büyük dizinler büyük miktarda RAM alır. Yavaşlık, her iki taraftaki RAM eksikliğinden kaynaklanabilir. Bellek kullanımını izlerken bir test çalıştırması yapın. Linux herhangi bir sol RAM'i disk önbelleği olarak kullanır, bu nedenle RAM'iniz azalırsa, disk önbelleği daha az olur. RAM'iniz biterse ve sistem takas kullanmaya başlarsa, performans gerçekten kötü olacaktır.

--Checksum'un kullanılmadığından emin olun

--checksum(veya -c) her dosyanın her bloğunun okunmasını gerektirir. Muhtemelen sadece değişiklik sürelerini (inode'da saklanan) okuma varsayılan davranışıyla başa çıkabilirsiniz.

İşi küçük gruplar halinde bölün.

Gigasync gibi "dizin ağacını geri almak için perl kullanarak iş yükünü doğrayarak , rsync ile aktarılacak küçük dosya listeleri oluşturacak" gibi bazı projeler var .

Ekstra dizin taraması büyük miktarda ek yük olacak, ancak belki de net bir kazanç olacaktır.

İşletim sistemi varsayılanları bu durum için yapılmamıştır.

Tüm varsayılanlarla Linux / FreeBSD / etc kullanıyorsanız, performans tüm uygulamalarınız için korkunç olacaktır. Varsayılanlar, daha büyük dizinlerde RAM'i boşa harcamamak için daha küçük dizinleri varsayar.

Büyük dizinleri daha iyi işlemek için dosya sisteminizi ayarlayın: Büyük klasör boyutları GÇ performansını yavaşlatır mı?

"Namei önbelleğine" bakın

BSD benzeri işletim sistemleri, inode ("namei" önbellek ") için bir isim aramayı hızlandıran bir önbelleğe sahiptir.Her dizin için bir namei önbellek vardır.Çok küçükse, bir optimizasyondan daha fazla bir engeldir. Her dosyada rsync bir lstat () yaptığı için, 80k dosyalarının her biri için inode'a erişilir.Bu önbelleğinizi patlatabilir. Sisteminizdeki dosya dizini performansını nasıl ayarlayacağınızı araştırın.

Farklı bir dosya sistemi düşünün

XFS, daha büyük dizinleri işlemek için tasarlanmıştır. Bkz. Dosya sistemi tek bir dizindeki çok sayıda dosya

Belki yapabileceğiniz en iyi şey 5 dakikadır.

Kaç tane blok bloğunun okunduğunu ve donanımın bu kadar çok bloğu okuyabilmesini ne kadar hızlı bekleyeceğinizi hesaplayın.

Belki beklentileriniz çok yüksek. Değişen dosyaları olmayan bir rsync yapmak için kaç disk bloğunun okunması gerektiğini düşünün: her sunucunun dizini okuması ve dosya başına bir inode okuması gerekir. Hiçbir şeyin önbelleğe alınmadığını varsayalım, çünkü 80k dosya muhtemelen önbelleğinizi patlattı. Diyelim ki matematiği basit tutmak 80k blok. Bu, birkaç saniye içinde okunması gereken yaklaşık 40M veri. Ancak, her blok arasında bir disk araması olması gerekiyorsa, bu çok daha uzun sürebilir.

Yani yaklaşık 80.000 disk bloğunu okumanız gerekecek. Sabit sürücünüz bunu ne kadar hızlı yapabilir? Bunun rastgele bir I / O olduğu göz önüne alındığında, uzun bir doğrusal okuma değil, 5 dakika oldukça mükemmel olabilir. Bu 1 / (80000/600) veya her 7,5 ms'de bir disk okunur. Sabit sürücünüz için hızlı mı yoksa yavaş mı? Modele bağlıdır.

Benzer bir şeye karşı karşılaştırma

Bunu düşünmenin başka bir yolu da bu. Hiçbir dosya değişmediyse, ls -Llraynı miktarda disk etkinliği yapar ancak hiçbir zaman dosya verisi okumaz (yalnızca meta veriler). ls -LlrKoşmak için gereken zaman üst sınırınızdır.

  • Rsync (dosya değiştirilmeden) önemli ölçüde yavaş ls -Llrmı? Ardından rsync için kullandığınız seçenekler geliştirilebilir. Belki -cetkinleştirilir veya yalnızca dizinlerden ve meta verilerden (inode verileri) daha fazlasını okuyan başka bir işaret.

  • Rsync neredeyse kadar hızlı (hiçbir dosya değişmiş ile) mı ls -Llr? Sonra rsync'i olabildiğince iyi ayarladınız. İşletim sistemini ayarlamanız, RAM eklemeniz, daha hızlı sürücüler almanız, dosya sistemlerini değiştirmeniz vb.

Geliştiricilerinizle konuşun

80k dosyaları sadece kötü tasarım. Çok az dosya sistemi ve sistem aracı bu tür büyük dizinleri çok iyi idare eder. Dosya adları abcdefg.txt ise, onları abdc / abcdefg.txt dosyasında saklamayı düşünün (tekrarlamaya dikkat edin). Bu, dizinleri daha küçük dizinlere ayırır, ancak kodda büyük bir değişiklik gerektirmez.

Ayrıca .... bir veritabanı kullanmayı düşünün. Bir dizinde 80 bin dosya varsa, geliştiricileriniz gerçekten istedikleri bir veritabanı olduğu gerçeğini araştırıyor olabilir. MariaDB veya MySQL veya PostgreSQL, büyük miktarda veri depolamak için çok daha iyi bir seçenek olacaktır.

Hey, 5 dakikadaki sorun ne?

Son olarak, 5 dakika gerçekten çok mu kötü? Bu yedeklemeyi günde bir kez çalıştırırsanız, 5 dakika çok zaman almaz. Evet, hızı seviyorum. Ancak 5 dakika müşterileriniz için "yeterince iyi" ise, o zaman sizin için yeterince iyidir. Yazılı bir SLA'nız yoksa, yedeklemelerin ne kadar hızlı gerçekleşmesini beklediklerini öğrenmek için kullanıcılarınızla resmi olmayan bir görüşme yapmaya ne dersiniz?

Performansı artırmaya ihtiyaç duyulmadıysa bu soruyu sormadığınızı varsayıyorum. Ancak, müşterileriniz 5 dakikadan memnunsa, zaferi beyan edin ve çabalarınızı gerektiren diğer projelere geçin.

Güncelleme: Bazı tartışmalardan sonra darboğazın ağ olduğunu belirledik. Ben vazgeçmeden önce 2 şey tavsiye edeceğim :-).

  • Sıkıştırma ile borudan daha fazla bant genişliği sıkmaya çalışın. Ancak sıkıştırma daha fazla CPU gerektirir, bu nedenle CPU'nuz aşırı yüklenmişse performansı daha da kötüleştirebilir. Rsync'i olsun ve olmasın deneyin ve -zssh'nizi sıkıştırma ile ve sıkıştırma olmadan yapılandırın. Herhangi birinin diğerlerinden önemli ölçüde daha iyi performans gösterip göstermediğini görmek için 4 kombinasyonun hepsini zamanlayın.
  • Duraklama olup olmadığını görmek için ağ trafiğini izleyin. Duraklamalar varsa, bunlara neyin neden olduğunu bulabilir ve orada optimize edebilirsiniz. Eğer rsync her zaman gönderiyorsa, o zaman gerçekten sınırınızdasın. Seçimleriniz:
    • daha hızlı bir ağ
    • rsync dışında bir şey
    • kaynağı ve hedefi birbirine yaklaştırın. Bunu yapamazsanız, yerel bir makineye rsync sonra gerçek hedefe rsync yapabilir misiniz? İlk rsync sırasında sistemin kapalı olması gerekiyorsa, bunu yapmanın faydaları olabilir.

80K çok dosya var . : Bir dizin ağacında 80k dosya var . Her bir dizinde 2k'den fazla dosya / alt dizin yoktur.
guettli

Rsync sürümünüzü kontrol edin: tamam, --checksum'un kullanılmadığından emin olun: tamam. İşi küçük gruplara ayırın: Teşekkür ederim gigasync'e bir göz atacağım. Bu durumda işletim sistemi varsayılanları yapılmaz: yapılır (darboğaz işletim sistemi değil ağdır). "Namei cache" ye bakın: tamam (işletim sistemi değil, net). Farklı bir dosya sistemi düşünün: OS değil, yine net. Belki 5 dakika yapabileceğiniz en iyisidir .: Bence çok daha hızlı olabilir. Geliştiricilerinizle konuşun (DB kullanın): Bu dev bir değişiklik olacaktır. Belki daha iyi yedekleme desteğine sahip bir dosya sistemi bu sorunu çözebilir.
guettli

Dizin başına 2k dosya çok daha iyi. Güncelleme için teşekkürler. Ağın yavaş olduğunu söylememiştiniz. Düşük bant genişliği, yüksek gecikme süresi veya her ikisi birden mi? rsync genellikle yüksek gecikmeli bağlantılar üzerinde iyi performans gösterir (ABD'deki bilgisayarlarla uğraşırken Avustralya'dan doktorası üzerinde çalışan biri tarafından geliştirilmiştir). Bu "ls -lLR" ssh üzerinden ve sonucu iletmek için ne kadar zaman geçmesini deneyin. msgstr "zaman ssh uzak ana bilgisayarı 'cd / dest && ls -lLR'> / tmp / list". Yerel ana bilgisayarda / tmp / list oluşturulduğundan emin olun.
TomOnTime

evet ağ yavaş. Çok yazık.
guettli

Ne kadar yavaş? 100M dosyasını kopyalamak için "scp" kullanırsanız, ne kadar sürer? Ayrıca, "time ssh remotehost 'cd / dest && ls -lLR'> / tmp / list" çıktısı nedir?
TomOnTime

2

Hayır, bu rsync ile mümkün değildir ve başka bir açıdan oldukça verimsiz olacaktır:

Normalde, rsyncyalnızca dosya değiştirme tarihlerini ve dosya boyutlarını karşılaştırır. Yaklaşımınız, değiştirilen dizinleri bulmak için tüm dosyaları (yerel ve uzak sistemde) iki kez okumak ve kontrol etmek için zorlar .


1
AFAIK rsync, mtime ve boyutu kontrol eder. Her ikisi de eşleşirse, dosya tekrar aktarılmaz (en azından varsayılan ayarlarda). Tüplerin karmasını göndermek için yeterli olacaktır (dosya adı, boyut, mtime). İçeriğin kontrol toplamına gerek yoktur.
guettli

Evet, haklısın, ama yine de, rsyncbunu yapmıyor.
Sven

2

Çok sayıda dosyanın senkronizasyonu için (çok az değişiklik olduğu yerde), noatimekaynak ve hedef bölümlerde de ayarlamaya değer . Bu, değişmeyen her dosya için diske yazma erişim sürelerini kaydeder.


Evet, noatime seçeneği mantıklı. Birkaç yıldan beri kullanıyoruz. Sanırım rsync'e bir alternatif gerekli.
guettli

2

Ayrıca, yalnızca dosya sisteminde ve yalnızca değiştirilen alt dizinlerde değişiklikler algılandığında rsync'i çalıştıracak olan lsyncd'yi de deneyebilirsiniz. İyi bir sunucuda iki milyona kadar dosya içeren dizinler için kullanıyorum.


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.