Yüz milyonlarca küçük dosyayı verimli bir şekilde depolayın. Kendi Kendine Barındırılan çözüm

Yüz milyonlarca küçük dosyayı verimli bir şekilde depolayın. Kendi Kendine Barındırılan çözüm

Sevgili Topluluk, Bu makale yüz milyonlarca küçük dosyayı verimli bir şekilde depolamaya ve almaya odaklanacaktır. Bu aşamada, küme kilitleri de dahil olmak üzere kilitler için tam desteğe sahip ve görünüşte koltuk değneği olmayan POSIX uyumlu dosya sistemleri için nihai çözüm önerilmektedir.

Ben de bu amaçla kendi özel sunucumu yazdım.
Bu görevi yerine getirirken ana sorunu çözmeyi başardık ve aynı zamanda küme dosya sistemimizin acımasızca tükettiği disk alanı ve RAM'den tasarruf etmeyi başardık. Aslında bu kadar çok dosya kümelenmiş dosya sistemi için zararlıdır.

Fikir şu:

Basit bir deyişle, küçük dosyalar sunucu üzerinden yüklenir, doğrudan arşive kaydedilir ve ayrıca buradan okunur ve büyük dosyalar yan yana yerleştirilir. Şema: 1 klasör = 1 arşiv, toplamda küçük dosyalardan oluşan birkaç milyon arşivimiz var, birkaç yüz milyon dosya değil. Ve tüm bunlar, herhangi bir komut dosyası olmadan veya dosyaları tar/zip arşivlerine koymadan, tamamen uygulanır.

Kısa tutmaya çalışacağım, eğer yazı uzun olursa şimdiden özür dilerim.

Her şey, geleneksel arşivlerin ve nesne depolamanın doğasında var olan dezavantajlar olmadan, HTTP protokolü aracılığıyla alınan verileri doğrudan arşivlere kaydedebilecek uygun bir sunucuyu dünyada bulamamamla başladı. Ve aramanın nedeni, 10 küçük dosyanın zaten biriktiği, büyük bir ölçeğe ulaşan 250,000,000 sunucudan oluşan Origin kümesiydi ve büyüme eğilimi durmayacaktı.

Makale okumayı sevmeyenler için biraz dokümantasyon daha kolaydır:

burada и burada.

Ve aynı zamanda liman işçisi, her ihtimale karşı artık yalnızca nginx'in içinde olduğu bir seçenek var:

docker run -d --restart=always -e host=localhost -e root=/var/storage 
-v /var/storage:/var/storage --name wzd -p 80:80 eltaline/wzd

Sonraki:

Çok fazla dosya varsa, önemli kaynaklara ihtiyaç duyulur ve en kötü yanı, bunların bir kısmının boşa gitmesidir. Örneğin, kümelenmiş bir dosya sistemi (bu durumda MooseFS) kullanıldığında, dosya gerçek boyutundan bağımsız olarak her zaman en az 64 KB yer kaplar. Yani 3, 10 veya 30 KB boyutundaki dosyalar için diskte 64 KB gereklidir. Çeyrek milyar dosya varsa 2 ila 10 terabayttan kaybediyoruz. MooseFS'nin bir sınırlaması olduğundan, süresiz olarak yeni dosyalar oluşturmak mümkün olmayacaktır: her dosyanın bir kopyası ile 1 milyardan fazla olamaz.

Dosya sayısı arttıkça meta veriler için çok fazla RAM gerekir. Sık sık gerçekleşen büyük meta veri dökümleri, SSD sürücülerin aşınmasına ve yıpranmasına da katkıda bulunur.

wZD sunucusu. Disklerdeki işleri düzene koyuyoruz.

Sunucu Go'da yazılmıştır. Öncelikle dosya sayısını azaltmam gerekiyordu. Nasıl yapılır? Arşivleme nedeniyle, ancak bu durumda dosyalarım yalnızca sıkıştırılmış resimler olduğundan sıkıştırma olmadan. Hala eksikliklerinin giderilmesi gereken BoltDB kurtarmaya geldi, bu da belgelere yansıyor.

Toplamda çeyrek milyar dosya yerine, benim durumumda yalnızca 10 milyon Bolt arşivi kalmıştı. Mevcut dizin dosya yapısını değiştirme imkanım olsaydı bunu yaklaşık 1 milyon dosyaya indirmek mümkün olurdu.

Tüm küçük dosyalar, bulundukları dizinlerin adlarını otomatik olarak alan Bolt arşivlerine paketlenir ve tüm büyük dosyalar arşivlerin yanında kalır; bunları paketlemenin bir anlamı yoktur, bu özelleştirilebilir. Küçükleri arşivlenir, büyükleri ise değiştirilmez. Sunucu her ikisiyle de şeffaf bir şekilde çalışır.

wZD sunucusunun mimarisi ve özellikleri.

Yüz milyonlarca küçük dosyayı verimli bir şekilde depolayın. Kendi Kendine Barındırılan çözüm

Sunucu Linux, BSD, Solaris ve OSX işletim sistemleri altında çalışmaktadır. Linux altında yalnızca AMD64 mimarisini test ettim ancak ARM64, PPC64, MIPS64 için çalışması gerekiyor.

Ana Özellikler:

  • Çoklu iş parçacığı;
  • Hata toleransı ve yük dengeleme sağlayan çoklu sunucu;
  • Kullanıcı veya geliştirici için maksimum şeffaflık;
  • Desteklenen HTTP yöntemleri: GET, HEAD, PUT ve DELETE;
  • İstemci başlıkları aracılığıyla okuma ve yazma davranışının kontrolü;
  • Esnek sanal ana bilgisayarlar için destek;
  • Yazarken/okurken CRC veri bütünlüğünü destekleyin;
  • Minimum bellek tüketimi ve optimum ağ performansı ayarı için yarı dinamik arabellekler;
  • Ertelenmiş veri sıkıştırma;
  • Ayrıca, hizmeti durdurmadan dosyaları taşımak için çok iş parçacıklı bir arşivleyici wZA sunulmaktadır.

Gerçek Deneyim:

Sunucuyu ve arşivleyiciyi uzun süredir canlı veriler üzerinde geliştiriyor ve test ediyorum, şimdi ayrı SATA sürücülerinde 250,000,000 dizinde bulunan 15,000,000 küçük dosya (resim) içeren bir küme üzerinde başarıyla çalışıyor. 10 sunucudan oluşan bir küme, bir CDN ağının arkasına kurulan bir Origin sunucusudur. Hizmet vermek için 2 Nginx sunucusu + 2 wZD sunucusu kullanılır.

Bu sunucuyu kullanmaya karar verenler için, eğer uygunsa, kullanımdan önce dizin yapısını planlamak akıllıca olacaktır. Sunucunun her şeyi 1 Bolt arşivine sıkıştırma amacı taşımadığına dair hemen bir rezervasyon yapayım.

Performans testi:

Sıkıştırılmış dosyanın boyutu ne kadar küçük olursa, üzerinde GET ve PUT işlemleri o kadar hızlı gerçekleştirilir. HTTP istemcisinin yazma ve okumanın yanı sıra normal dosyalar ve Bolt arşivleriyle ilgili toplam süreyi karşılaştıralım. 32 KB, 256 KB, 1024 KB, 4096 KB ve 32768 KB boyutlarındaki dosyalarla çalışmalar karşılaştırılmıştır.

Bolt arşivleriyle çalışırken, her dosyanın veri bütünlüğü kontrol edilir (CRC kullanılır), kayıttan önce ve ayrıca kayıttan sonra, anında okuma ve yeniden hesaplama gerçekleşir, bu doğal olarak gecikmelere neden olur, ancak asıl önemli olan veri güvenliğidir.

SATA sürücüler üzerinde yapılan testler net bir fark göstermediği için SSD sürücüler üzerinde performans testleri yaptım.

Test sonuçlarına dayalı grafikler:

Yüz milyonlarca küçük dosyayı verimli bir şekilde depolayın. Kendi Kendine Barındırılan çözüm
Yüz milyonlarca küçük dosyayı verimli bir şekilde depolayın. Kendi Kendine Barındırılan çözüm

Gördüğünüz gibi, küçük dosyalar için arşivlenmiş ve arşivlenmemiş dosyalar arasındaki okuma ve yazma süreleri arasındaki fark küçüktür.

32 MB boyutunda dosyaları okumayı ve yazmayı test ederken tamamen farklı bir resim elde ediyoruz:

Yüz milyonlarca küçük dosyayı verimli bir şekilde depolayın. Kendi Kendine Barındırılan çözüm

Dosyaların okunması arasındaki zaman farkı 5-25 ms arasındadır. Kayıtta işler daha da kötü, fark yaklaşık 150 ms. Ancak bu durumda büyük dosyaların yüklenmesine gerek yoktur, bunu yapmanın hiçbir anlamı yoktur, arşivlerden ayrı olarak yaşayabilirler.

*Teknik olarak bu sunucuyu NoSQL gerektiren görevler için kullanabilirsiniz.

wZD sunucusuyla çalışmanın temel yöntemleri:

Normal bir dosya yükleniyor:

curl -X PUT --data-binary @test.jpg http://localhost/test/test.jpg

Bolt arşivine dosya yükleme (arşivde yer alabilecek maksimum dosya boyutunu belirleyen fmaxsize sunucu parametresi aşılmamışsa; aşılırsa dosya her zamanki gibi arşivin yanına yüklenecektir):

curl -X PUT -H "Archive: 1" --data-binary @test.jpg http://localhost/test/test.jpg

Bir dosya indirme (diskte ve arşivde aynı adlara sahip dosyalar varsa, indirirken öncelik varsayılan olarak arşivlenmemiş dosyaya verilir):

curl -o test.jpg http://localhost/test/test.jpg

Bolt arşivinden bir dosya indirme (zorunlu):

curl -o test.jpg -H "FromArchive: 1" http://localhost/test/test.jpg

Diğer yöntemlerin açıklamaları belgelerde bulunmaktadır.

wZD Belgeleri
wZA Belgeleri

Sunucu şu anda yalnızca HTTP protokolünü desteklemektedir; henüz HTTPS ile çalışmamaktadır. POST yöntemi de desteklenmiyor (gerekli olup olmadığına henüz karar verilmedi).

Kaynak kodunu kim araştırırsa orada karamela bulacaktır, herkes bundan hoşlanmaz, ancak ana kodu, kesme işleyicisi dışında web çerçevesinin işlevlerine bağlamadım, bu nedenle gelecekte hemen hemen her şey için hızlı bir şekilde yeniden yazabilirim. motor.

Yapılacaklar:

  • Küme dosya sistemleri olmayan büyük sistemlerde kullanım imkanı için kendi çoğaltıcınızın ve dağıtıcınızın + coğrafi bölgenin geliştirilmesi (Yetişkinler için her şey)
  • Tamamen kaybolması durumunda meta verilerin tamamen tersine kurtarılması imkanı (bir distribütör kullanılıyorsa)
  • Farklı programlama dilleri için kalıcı ağ bağlantılarını ve sürücüleri kullanma becerisine yönelik yerel protokol
  • NoSQL bileşenini kullanmaya yönelik gelişmiş olanaklar
  • Bolt arşivlerindeki dosyalar veya değerler ve normal dosyalar için farklı türlerde (gzip, zstd, snappy) sıkıştırmalar
  • Bolt arşivlerindeki dosyalar veya değerler ve normal dosyalar için farklı türde şifreleme
  • GPU da dahil olmak üzere gecikmeli sunucu tarafı video dönüştürme

Her şeye sahibim, umarım bu sunucu birilerine faydalı olur, BSD-3 lisansı, çift telif hakkı, çünkü çalıştığım şirket olmasaydı sunucu yazılmazdı. Tek geliştirici benim. Bulduğunuz hatalar ve özellik istekleri için minnettar olurum.

Kaynak: habr.com

Yorum ekle