Soru Dosya sistemine bir milyon görüntü depolamak


Çok sayıda görüntü üretecek bir projem var. Başlangıç ​​için yaklaşık 1.000.000. Büyük görüntüler değiller, böylece hepsini tek bir makinede saklayacağım.

Bu görüntüleri verimli bir şekilde depolamanızı nasıl öneriyorsunuz? (Şu anda NTFS dosya sistemi)

Bir isimlendirme şeması düşünüyorum ... tüm görüntüleri başlatmak için 1'den artan bir ad olacaktır. Umarım gerektiğinde onları sıraya koymamı ve farklı klasörler halinde atmamı sağlar.

daha iyi bir adlandırma şeması ne olurdu?

a / b / c / 0 ... z / z / z / 999

veya

a / b / c / 000 ... z / z / z / 999

Bu konuda herhangi bir fikrin var mı?


75
2017-12-17 16:52


Menşei


Belirli kullanıcılara mı bağlı yoksa genel mi? Herhangi bir şekilde gruplandırılmışlar mı?
sadece jenerik. bazı teknik ekipman tarafından oluşturulan bir grup görüntü. Ben bir zaman armatürü hakkında fikir sahibi olmak için onları 1'den itibaren artan bir şekilde adlandırıyorum. - s.mihai
nasıl kullanacaklar / nasıl erişilecekler? ısmarlama bir uygulama ile ne? - dove
Bu sen misin? i46.tinypic.com/1z55k7q.jpg
:)) evet ... 1 mil. porno görüntüleri :)) - s.mihai


Cevaplar:


Veritabanları yerine düzenli bir dosya sistemi kullanmanızı tavsiye ederim. Dosya sistemini kullanmak bir veritabanından daha kolaydır, dosyalara erişmek için normal araçları kullanabilirsiniz, dosya sistemleri bu tür kullanım için tasarlanmıştır. NTFS bir depolama sistemi olarak iyi çalışmalıdır.

Asıl yolu veritabanına kaydetmeyin. Görüntünün sıra numarasını veritabanına kaydetmek ve sıra numarasından yol oluşturabilen işleve sahip olmak daha iyidir. Örneğin:

 File path = generatePathFromSequenceNumber(sequenceNumber);

Dizin yapısını değiştirmeniz gerektiğinde nasıl ele alınacağı daha kolaydır. Belki de görüntüleri farklı bir yere taşımanız gerekir, belki de alan biterse ve bazı görüntüler A diskinde ve bazılarında B diskinde saklanır. Veritabanındaki yolları değiştirmek için bir işlevi değiştirmek daha kolaydır. .

Dizin yapısını oluşturmak için bu tür bir algoritmayı kullanırdım:

  1. İlk pad, en az 12 basamaklı dizgeye sahip olana kadar sırayla sıfır olan sıra numarası. Dosyanızın adı bu. Bir sonek eklemek isteyebilirsiniz:
    • 12345 -> 000000012345.jpg
  2. Ardından dizeyi 2 veya 3 karakter bloğuna bölün, burada her blok bir dizin seviyesini gösterir. Sabit sayıda dizin seviyesi var (örneğin 3):
    • 000000012345 -> 000/000/012
  3. Dosyayı oluşturulan dizinin altına saklayın:
    • Böylece dizi kimliği ile dosya için tam yol ve dosya dosya adı 123 olduğu 000/000/012/00000000012345.jpg
    • Sıra kimliğine sahip dosya için 12345678901234 yol olurdu 123/456/789/12345678901234.jpg

Dizin yapıları ve dosya depolaması hakkında düşünülecek bazı şeyler:

  • Yukarıdaki algoritma, her yaprak dizininin maksimum 1000 dosyaya sahip olduğu bir sistem sunar (toplamda 1 000 000 000 000 dosyadan daha az varsa).
  • Örneğin bir dizinin kaç dosya ve alt dizin içerebileceğini sınırlayabilir. Linux'ta ext3 dosya sistemi bir dizin için 31998 alt dizin sınırlaması vardır.
  • Dizin başına çok sayıda dosya varsa, normal araçlar (WinZip, Windows Gezgini, komut satırı, bash kabuk vb.) Çok iyi çalışmayabilir (> 1000)
  • Dizin yapısının kendisi biraz disk alanı alacaktır, bu yüzden çok fazla dizin istemeyeceksiniz.
  • Yukarıdaki yapı ile, dizin yapılarınızı karmaşıklaştırırsanız, sadece dosya adına bakarak görüntü dosyası için doğru yolu bulabilirsiniz.
  • Birkaç makineden dosyaya erişmeniz gerekiyorsa, dosyaları bir ağ dosya sistemi aracılığıyla paylaşmayı düşünün.
  • Çok sayıda dosyayı silerseniz yukarıdaki dizin yapısı çalışmaz. Dizin yapısında "delikler" bırakır. Ancak, herhangi bir dosyayı silmediğinizden bu işlem tamamdır.

70
2017-12-17 17:32



çok ilginç! dosya ismini bölme ... bunu düşünmedim. Bunu yapmanın zarif bir yolu olduğunu varsayalım: -? - s.mihai
Dosya isminin yanı sıra bir dizin (MD5 gibi) kullanmak da işe yarar. Dosyaların bütünlüğü yalnızca adlandırma şemasının bir yan yararı olmakla kalmaz (ayrıca kolayca kontrol edilebilir), ancak dizin hiyerarşisi boyunca makul bir eşit dağılımınız olur. Yani "f6a5b1236dbba1647257cc4646308326.jpg" adlı bir dosyanız varsa, bunu "/ f / 6" (veya istediğiniz kadar derin) içinde saklarsınız. 2 seviye derin 256 dizinleri ya da ilk 1m dosyaları için dizin başına 4000'den az dosya verir. Yeniden dağıtımın daha derin bir plana otomatikleştirilmesi de çok kolay olacaktır.
+1 Az önce fark ettim ki bu cevap yeni gönderdiğim şeye benziyordu. - 3dinfluence
Dosya sistemini kullanmaya ve dosya isimlerine "dilimlemek" için bir yapay tanımlayıcı oluşturmaya kesinlikle katılıyorum. Ama aynı zamanda tanımlayıcıların rastgele bir dağılımını elde etmelisiniz, yani sıra numarası kullanmayın. Bu, daha dengeli bir klasör ağacına sahip olmanızı sağlar. Ayrıca, rasgele dağıtım ile ağacı birden fazla dosya sistemi arasında daha kolay bir şekilde bölümleyebilirsiniz. Ayrıca, her bir dosya sistemi için tekilleştirme açık ve bir yığın hacmi olan bir ZFS tabanlı SAN kullanıyorum. SAN'a erişmek için hala iSCSI kullanarak NTFS kullanabilirsiniz. - Michael Dillon
2. adımda sağdan sola giderseniz, dosyalar eşit olarak dağıtılır. Ayrıca, sınırsız sayıda dosyaya sahip olabileceğiniz için yeterli sayıda sıfır doldurmadığınız için endişelenmenize gerek yok. - ropo


2 sentimi bir parça olumsuz tavsiyede bulunmaya harcayacağım: Veritabanına gitme.

Ben yıllardır görüntü depolama veritabanları ile çalışıyorum: büyük (1 meg-> 1 gig) dosyaları, genellikle değiştirilen, çoğu kez, çoğu kez erişilen dosyanın sürümleri. Depolanan büyük dosyalar ile uğraştığınız veritabanı sorunları ile uğraşmak son derece sıkıcı, yazma ve işlem sorunları knotty ve büyük tren neden olabilir kilitleme sorunları içine koşmak batıklar. Dbcc betiklerini yazarken ve yedeklemeden tabloları normal bir kişiden daha geri yüklemek için daha fazla pratik yapıyorum hiç var.

Çalıştığım yeni sistemlerin çoğu dosya depolama sistemini dosya sistemine itti ve veri tabanlarına indekslemeden başka bir şey istemedi. Dosya sistemleri, bu tür bir kötüye kullanım için tasarlanmıştır, genişletmek için çok daha kolaydır ve bir girdi bozulursa, tüm dosya sistemini nadiren kaybedersiniz.


29
2017-12-17 17:12



Evet. not alındı! - s.mihai
SQL 2008'in FILESTREAM veri türüne baktınız mı? Veritabanı ve dosya sistemi depolaması arasında bir hatadır. - NotMe
Hızlı ve sık olmayan IO işlemleri yaparken bir veritabanı yerine dosya sunucusu ile yapıştırma +1.
Veritabanına sadece birkaç yüz dokümanı veya fotoğrafı saklıyorsanız, depolama için veritabanı kullanmanın herhangi bir dezavantajı var mı? - Beep beep
+1 ... bir dosya sistemi zaten bir "veritabanı" türüdür (elbette ntfs), bu yüzden neden aşırı karmaşık hale getirin. - akira


Ben bununla uğraşmak zorunda çoğu site dosyaları eşit olarak klasörlerde dağıtılmış olduğundan emin olmak için bir çeşit karma kullanın.

Öyleyse, böyle bir şey olan bir dosya karması olduğunu söyle 515d7eab9c29349e0cde90381ee8f810
Bunu aşağıdaki konumda depolayabilirsiniz ve her bir klasördeki dosya sayısını düşük tutmak için ne kadar çok seviyeye sahip olmanız gerektiğini kullanabilirsiniz.
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg

Bu yaklaşımı defalarca gördüm. Bu dosya karmalarını bir insan tarafından okunabilir adıyla ve saklamanız gereken diğer meta verilerle eşlemek için yine de bir veritabanına ihtiyacınız var. Ancak bu yaklaşım oldukça iyi ölçeklendirir, karma adres alanını birden fazla bilgisayar ve / veya depolama havuzu vb. Arasında dağıtmaya başlayabilirsiniz.


12
2017-12-17 20:17



Git benzer bir yaklaşım kullanır: git-scm.com/book/en/v2/Git-Internals-Git-Objects (Bu cevabı yedeklemek için) - aexl


İdeal olarak, belirli sabit disk kurulumunuz, önbelleğe alma, kullanılabilir bellek vb. Bu sonuçları değiştirebileceğinden, çeşitli yapılar için rasgele erişim zamanlarında bazı testler yapmanız gerekir.

Dosya adları üzerinde kontrole sahip olduğunuzu farz edersem, bunları dizin başına 1000s düzeyinde bölüşürüm. Eklediğiniz daha fazla dizin düzeyi, yaktığınız daha fazla düğüm, dolayısıyla burada bir itme-çekme var.

Örneğin.,

/ [0-99] / [0-99] / dosya / kök

Not, http://technet.microsoft.com/en-us/library/cc781134(WS.10).aspx NTFS kurulumu hakkında daha fazla bilgi var. Özellikle, "Çok sayıda dosyayı bir NTFS klasöründe (300.000 veya daha fazla) kullanırsanız, daha iyi performans için kısa dosya adı oluşturmayı devre dışı bırakın; özellikle de uzun dosya adlarının ilk altı karakteri aynıysa."

Gereksinim duymadığınız dosya sistemi özelliklerini de devre dışı bırakmalısınız (ör. Son erişim zamanı). http://www.pctools.com/guides/registry/detail/50/


11
2017-12-17 17:01



8.3 dosya adı oluşturma ve son erişim zamanını devre dışı bırakmak için +1; Bunlar "çok sayıda [files]" ve "NTFS" (Windows) okuduğumda akla gelen ilk şeydi. - rob
aşağı bağlantı ........................ - Pacerier


Ne yaparsanız yapın, hepsini bir dizinde saklamayın.

Bu görüntülerin adlarının dağılımına bağlı olarak, 2. harfli resim vb. İçin başka bir alt klasör kümesi kullanabileceğiniz tek harfli üst düzey klasörlere sahip olduğunuz bir dizin yapısı oluşturabilirsiniz.

Yani:

Klasör img\a\b\c\d\e\f\g\ 'abcdefg' ile başlayan görüntüleri vb. içerir.

Kendi uygun derinliğinizi gerekli kılabilirsiniz.

Bu çözümle ilgili en önemli şey, dizin yapısının etkili bir şekilde bir hashtable / sözlük gibi davranmasıdır. Bir görüntü dosyası adı verildiğinde, dizini bilecek ve bir dizin verilecektir, oraya giden görüntülerin bir alt kümesini bileceksiniz.


7
2017-12-17 16:58



\ a \ b \ c \ d \ e \ f \ Şimdi yapıyorum, bunu yapmanın akıllıca bir yolu olduğunu düşünüyordum. - s.mihai
Bu, onları fiziksel olarak depolamanın genel olarak kabul edilen bir çözümü. Resim URL'sini açıkça oluşturmak, görüntü dosyası adına göre dinamik olarak kolayca yapılabilen bir şeydir. Ayrıca, onlara hizmet etmek için, yükleme zamanlarını hızlandırmak için img-a, img-b alt etki alanlarını görüntü sunucusunda bile tanıtabilirsiniz.
Ve hepsini "bir dizinde saklamayın" için +1. Tek bir klasörde bir sunucuya 47000 dosya koyan eski bir sistemi destekliyorum ve Explorer'ın yalnızca klasörü açması yaklaşık bir dakika sürüyor. - Mark Ransom
\ B \ c \ d \ e \ f \ g yapmak dizin yapısını çok derin yapar ve her dizin yalnızca birkaç dosya içerir. Her dizin seviyesi için bir harf daha kullanmanız daha iyi örn. ab \ cd \ ef \ veya abc \ def \. Dizinler de diskten alan kaplarlar, böylece çok fazla istemezsiniz. - Juha Syrjälä
Bir dizinde 4 + milyon dosya bulunan bir uygulamayı desteklemeliydim; Şaşırtıcı derecede iyi çalıştı, ancak klasörü açmak için hiç bir zaman explorer alamazsınız, sürekli olarak yeni eklemeleri sıralar. NTFS için +1 ölmeden idare edebilir. - SqlACID


Bunları dosya sisteminde saklarım ama dosya sayısının ne kadar hızlı büyüyeceğine bağlı. Bu dosyalar web'de mi barındırılıyor? Bu dosyaya kaç kullanıcı erişecek? Size daha iyi bir öneri vermeden önce cevaplanması gereken sorular bunlar. Ayrıca Facebook'tan Haystack'a da bakıyorum, görüntüleri saklamak ve sunmak için çok iyi bir çözümü var.

Ayrıca, dosya sistemini seçerseniz, bu dosyaları dizinlerle bölmeniz gerekir. Bu konuya baktım ve bir çözüm önerdim ama hiçbir şekilde mükemmel değil. Hash tablosu ve kullanıcılarla bölümleme yapıyorum. Blog.


5
2017-12-17 16:59



görüntüler sık ​​erişim için kullanılmaz. bu yüzden sorun yok. sayıları oldukça hızlı büyüyecek. Orada 1mil olacağını varsayalım. 1 ayda işaretleyin. - s.mihai
Programcı görüşüyle ​​ilgileniyorum, bu yüzden fazla fazla düşünmüyorum - s.mihai
Hızlı erişime ihtiyacınız yoksa, Haystack muhtemelen sizin için değildir. Bölümler için Dizinleri kullanmak benim görüşüme göre en basit çözümdür. - Lukasz


4 milyon görüntüye sahip bir fotoğraf mağazamız var. Veritabanını sadece meta veri için kullanıyoruz ve tüm resimler dosya sisteminde, dosya adının son son basamağından oluşturulduğu tersine çevrilmiş bir adlandırma sistemi kullanılarak saklanıyor. Örneğin.: 000001234.jpg dizin yapısında 4 \ 3 \ 2 \ 1 \ 000001234.jpg gibi saklanır.

Bu şema, veritabanında kimlik indeksi ile çok iyi çalışır, çünkü eşit olarak tüm dizin yapısını doldurur.


5
2017-12-30 22:10





Hızlı nokta, size bir dosya yolu depolamanıza gerek yoktur. Dosyalarınız tanımladığınız şekilde adlandırılmışsa, sayısal bir değer depolayabilirsiniz. Daha sonra tartışılan iyi tanımlanmış depolama şemalarından birini kullanarak, dizini bir sayı olarak alabilir ve çok hızlı bir şekilde dizin yapısını geçerek dosyayı bulabilirsiniz.


4
2017-12-17 17:18



: -? iyi bir hızlı nokta. sadece şu anda yolu oluşturmak için bir algoritma yok. - s.mihai