Przechowywanie miliona obrazów w systemie plików

79

Mam projekt, który wygeneruje ogromną liczbę obrazów. Na początek około 1 000 000. Nie są to duże obrazy, więc na początku będę je przechowywać na jednym komputerze.

Jak zaleciłeś efektywne przechowywanie tych obrazów? (Obecnie system plików NTFS)

Rozważam schemat nazewnictwa ... na początek wszystkie obrazy będą miały przyrostową nazwę od 1 w górę. Mam nadzieję, że pomoże mi to posortować je później, jeśli zajdzie taka potrzeba, i wrzucić je do różnych folderów.

jaki byłby lepszy schemat nazewnictwa:

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

lub

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

jakiś pomysł na ten temat?

s.mihai
źródło
1
Czy są one powiązane z konkretnymi użytkownikami, czy tylko ogólne? Czy są zgrupowane w jakikolwiek sposób?
tylko ogólny. kilka zdjęć wygenerowanych przez niektóre urządzenia techniczne. nazywam je przyrostowo od 1 do góry, aby mieć pomysł na czas.
s.mihai,
w jaki sposób będą wykorzystywane / dostępne? poprzez aplikację na zamówienie czy co?
dove
1
:)) tak ... 1 mil. zdjęcia porno :))
s.mihai

Odpowiedzi:

73

Polecam używanie zwykłego systemu plików zamiast baz danych. Korzystanie z systemu plików jest łatwiejsze niż baza danych, możesz używać normalnych narzędzi do uzyskiwania dostępu do plików, systemy plików są zaprojektowane do tego rodzaju zastosowań itp. NTFS powinien działać dobrze jako system pamięci masowej.

Nie przechowuj rzeczywistej ścieżki do bazy danych. Lepiej przechowywać numer sekwencji obrazu w bazie danych i mieć funkcję, która może wygenerować ścieżkę z numeru sekwencji. na przykład:

 File path = generatePathFromSequenceNumber(sequenceNumber);

Łatwiej jest sobie poradzić, jeśli musisz zmienić strukturę katalogów. Być może trzeba przenieść obrazy w inne miejsce, może zabraknie miejsca i zaczniesz przechowywać niektóre obrazy na dysku A, a niektóre na dysku B itp. Łatwiej jest zmienić jedną funkcję niż zmienić ścieżki w bazie danych .

Użyłbym tego rodzaju algorytmu do generowania struktury katalogów:

  1. Najpierw wpisz numer sekwencyjny z wiodącymi zerami, aż będziesz mieć co najmniej 12-cyfrowy ciąg. To jest nazwa twojego pliku. Możesz dodać przyrostek:
    • 12345 -> 000000012345.jpg
  2. Następnie podziel ciąg na 2 lub 3 znaki, gdzie każdy blok oznacza poziom katalogu. Posiadaj stałą liczbę poziomów katalogów (na przykład 3):
    • 000000012345 -> 000/000/012
  3. Zapisz plik w wygenerowanym katalogu:
    • Zatem pełna ścieżka i nazwa pliku dla pliku o identyfikatorze sekwencji 123to 000/000/012/00000000012345.jpg
    • Dla pliku o identyfikatorze sekwencji 12345678901234będzie to ścieżka123/456/789/12345678901234.jpg

Kilka rzeczy do rozważenia na temat struktur katalogów i przechowywania plików:

  • Powyższy algorytm daje system, w którym każdy katalog liści ma maksymalnie 1000 plików (jeśli masz mniej niż 1 000 000 000 000 plików)
  • Mogą istnieć ograniczenia dotyczące liczby plików i podkatalogów, które może zawierać katalog, na przykład system plików ext3 w systemie Linux ma limit 31998 podkatalogów na jeden katalog.
  • Normalne narzędzia (WinZip, Eksplorator Windows, wiersz poleceń, powłoka bash itp.) Mogą nie działać bardzo dobrze, jeśli masz dużą liczbę plików w katalogu (> 1000)
  • Sama struktura katalogów zajmie trochę miejsca na dysku, więc nie będziesz chciał zbyt wielu katalogów.
  • W powyższej strukturze zawsze możesz znaleźć poprawną ścieżkę do pliku obrazu, po prostu patrząc na nazwę pliku, jeśli zdarzy Ci się popsuć struktury katalogów.
  • Jeśli chcesz uzyskać dostęp do plików z kilku komputerów, rozważ udostępnienie plików za pośrednictwem sieciowego systemu plików.
  • Powyższa struktura katalogów nie będzie działać, jeśli usuniesz wiele plików. Pozostawia „dziury” w strukturze katalogów. Ale ponieważ nie usuwasz żadnych plików, powinno być w porządku.
Juha Syrjälä
źródło
1
bardzo interesujące! dzielenie nazwy pliku ... nie myślałem o tym. zakładam, że jest to elegancki sposób: -?
s.mihai,
37
Używanie skrótu (takiego jak MD5) jako nazwy pliku, a także dystrybucji katalogu, działałoby. Nie tylko integralność plików byłaby dodatkową korzyścią dla schematu nazewnictwa (łatwym do sprawdzenia), ale będziesz miał dość równomierną dystrybucję w całej hierarchii katalogów. Więc jeśli masz plik o nazwie „f6a5b1236dbba1647257cc4646308326.jpg”, zapisz go w „/ f / 6” (lub tak głęboko, jak potrzebujesz). Głębokość 2 poziomów daje 256 katalogów, czyli nieco mniej niż 4000 plików na katalog dla początkowych plików 1m. Bardzo łatwo byłoby również zautomatyzować redystrybucję do głębszego programu.
+1 Właśnie zauważyłem, że ta odpowiedź była podobna do tej, którą właśnie opublikowałem.
3dinfluence
1
Zdecydowanie zgadzam się na użycie systemu plików i stworzenie sztucznego identyfikatora, aby „pokroić” na nazwy folderów. Ale powinieneś także spróbować uzyskać losowy rozkład identyfikatorów, tzn. Nie używaj numeru sekwencyjnego. To pozwoli ci mieć bardziej zrównoważone drzewo folderów. Ponadto dzięki losowej dystrybucji można łatwiej podzielić drzewo na wiele systemów plików. Używałbym także SAN opartej na ZFS z włączoną deduplikacją i rzadkim woluminem dla każdego systemu plików. Nadal możesz korzystać z NTFS, używając iSCSI, aby uzyskać dostęp do SAN.
Michael Dillon,
Jeśli przejdziesz od prawej do lewej w kroku 2, pliki są równomiernie rozmieszczone. Ponadto nie musisz się martwić, że nie wypełniasz wystarczającą liczbą zer, ponieważ możesz nieograniczoną liczbę plików
ropo
31

Zamierzam umieścić moje 2 centy na negatywnej radzie: nie idź z bazą danych.

Od lat pracuję z bazami danych do przechowywania obrazów: duże (1 meg-> 1 gig) pliki, często zmieniane, wiele wersji pliku, do których dostęp jest dość często. Problemy z bazą danych, na które napotykasz przechowywanie dużych plików, są niezwykle żmudne, problemy z pisaniem i transakcjami są zawiłe i napotykasz problemy z blokowaniem, które mogą powodować poważne wraki pociągów. Mam więcej praktyki w pisaniu skryptów DBCC i przywracanie kopii zapasowych z tabel niż każdy normalny człowiek powinien zawsze mieć.

Większość nowszych systemów, z którymi pracowałem, przekazała pamięć plików do systemu plików i polegała na bazach danych jedynie na indeksowaniu. Systemy plików są zaprojektowane tak, aby znosić tego rodzaju nadużycia, są one znacznie łatwiejsze do rozszerzenia, a rzadko tracisz cały system plików, jeśli jeden wpis zostanie uszkodzony.

Satanicpuppy
źródło
tak. uwaga wzięta!
s.mihai,
5
Czy sprawdziłeś typ danych FILESTREAM w SQL 2008? Jest to skrzyżowanie bazy danych z pamięcią systemu plików.
NotMe,
+1 za trzymanie się serwera plików zamiast bazy danych, ponieważ wykonujesz szybkie i rzadkie operacje IO.
Co zrobić, jeśli przechowuje się tylko kilkaset dokumentów lub zdjęć na bazę danych - co jest wadą korzystania z bazy danych do przechowywania?
Sygnał dźwiękowy
1
+1 ... system plików i tak jest swego rodzaju „bazą danych” (na pewno NTFS), więc po co to nadmiernie komplikować.
akira
12

Myślę, że większość witryn, które muszą sobie z tym poradzić, używa pewnego rodzaju skrótu, aby mieć pewność, że pliki zostaną równomiernie rozmieszczone w folderach.

Powiedzmy, że masz skrót pliku, który jest podobny do tego. 515d7eab9c29349e0cde90381ee8f810
Możesz przechowywać go w następującej lokalizacji i możesz użyć, ile głębokości potrzebujesz, aby utrzymać niską liczbę plików w każdym folderze.
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg

Widziałem to podejście wielokrotnie. Nadal potrzebujesz bazy danych, aby zamapować te skróty plików na czytelną dla człowieka nazwę i inne metadane, które musisz przechowywać. Ale to podejście dobrze się skaluje, ponieważ możesz zacząć dystrybuować przestrzeń adresową skrótu między wiele komputerów i / lub puli pamięci itp.

3dinfluence
źródło
2
Git stosuje podobne podejście: git-scm.com/book/en/v2/Git-Internals-Git-Objects (na poparcie tej odpowiedzi)
aexl
11

Najlepiej jest przeprowadzić testy losowych czasów dostępu dla różnych struktur, ponieważ konfiguracja dysku twardego, buforowanie, dostępna pamięć itp. Mogą zmienić te wyniki.

Zakładając, że masz kontrolę nad nazwami plików, podzieliłbym je na partycje na poziomie 1000 na katalog. Im więcej poziomów katalogu dodasz, tym więcej spalisz i-węzłów, więc tutaj jest push-pull.

Na przykład,

/ root / [0-99] / [0-99] / filename

Uwaga: http://technet.microsoft.com/en-us/library/cc781134(WS.10).aspx zawiera więcej szczegółów na temat konfiguracji NTFS. W szczególności „Jeśli używasz dużej liczby plików w folderze NTFS (300 000 lub więcej), wyłącz generowanie krótkich nazw plików, aby uzyskać lepszą wydajność, a zwłaszcza jeśli pierwsze sześć znaków długich nazw plików jest podobnych”.

Powinieneś także rozważyć wyłączenie niepotrzebnych funkcji systemu plików (np. Czas ostatniego dostępu). http://www.pctools.com/guides/registry/detail/50/

Jason Yanowitz
źródło
3
+1 za wyłączenie generowania plików 8.3 i czasu ostatniego dostępu; były to pierwsze rzeczy, które przyszły mi do głowy, gdy przeczytałem „ogromną liczbę [plików]” i „NTFS” (Windows).
rob
link w dół ........................
Pacerier,
7

Cokolwiek robisz, nie przechowuj ich wszystkich w jednym katalogu.

W zależności od rozmieszczenia nazw tych obrazów możesz stworzyć strukturę katalogów, w której masz jedno litowe foldery najwyższego poziomu, w których miałbyś inny zestaw podfolderów dla drugiej litery obrazów itp.

Więc:

Folder img\a\b\c\d\e\f\g\zawierałby obrazy zaczynające się od „abcdefg” i tak dalej.

Możesz wprowadzić własną odpowiednią głębokość.

Wspaniałą rzeczą w tym rozwiązaniu jest to, że struktura katalogów działa jak hashtable / słownik. Na podstawie nazwy pliku obrazu poznasz jego katalog, a na podstawie katalogu poznasz podzbiór obrazów, które tam się znajdują.

Wim Hollebrandse
źródło
\ a \ b \ c \ d \ e \ f \ Robię teraz, myślałem, że jest rozsądny sposób na zrobienie tego.
s.mihai,
1
Jest to ogólnie przyjęte rozwiązanie dotyczące fizycznego przechowywania ich. Wyraźne generowanie adresów URL obrazu to coś, co można łatwo zrobić dynamicznie na podstawie nazwy pliku obrazu. Ponadto, aby je obsłużyć, możesz nawet wprowadzić subdomeny img-a, img-b na serwerze obrazów, aby przyspieszyć ładowanie.
2
I +1 za „nie przechowuj ich wszystkich w jednym katalogu”. Wspieram starszy system, który umieścił ponad 47000 plików na serwerze w jednym folderze, a samo otwarcie Eksploratora zajmuje około minuty.
Mark Ransom,
5
Wykonanie \ b \ c \ d \ e \ f \ g powoduje, że struktura katalogów jest bardzo głęboka i każdy katalog zawiera tylko kilka plików. Lepiej używać więcej niż jednej litery na poziom katalogu, np. Ab \ cd \ ef \ lub abc \ def \. Katalogi również zajmują miejsce na dysku, więc nie chcesz ich zbyt wiele.
Juha Syrjälä,
2
Musiałem obsługiwać aplikację, która zawierała ponad 4 miliony plików w jednym katalogu; zadziałało zaskakująco dobrze, ale NIGDY nie można było skłonić eksploratora do otwarcia folderu, ciągle sortowałby nowe dodatki. +1 za to, że NTFS jest w stanie poradzić sobie bez umierania.
SqlACID
5

Chciałbym je przechowywać w systemie plików, ale zależy to od tego, jak szybko wzrośnie liczba plików. Czy te pliki są hostowane w Internecie? Ilu użytkowników miałoby dostęp do tego pliku? Oto pytania, na które należy odpowiedzieć, zanim będę mógł udzielić lepszej rekomendacji. Chciałbym również spojrzeć na Haystack z Facebooka, mają one bardzo dobre rozwiązanie do przechowywania i serwowania zdjęć.

Również jeśli wybierzesz system plików, musisz podzielić te pliki na partycje. Patrzyłem na ten problem i zaproponowałem rozwiązanie, ale pod żadnym względem nie jest idealne. Dzielę według tabeli skrótów, a użytkownicy mogą przeczytać więcej na moim blogu .

Łukasz
źródło
obrazy nie są przeznaczone do częstego dostępu. więc nie ma z tym problemu. ich liczba będzie rosła dość szybko. zakładam, że będzie 1mil. znak za 1 miesiąc.
s.mihai,
interesuje mnie widok programisty, aby nie przesadzić z tym zbytnio
s.mihai
Więc jeśli nie potrzebujesz szybkiego dostępu Haystack prawdopodobnie nie jest dla ciebie. Używanie katalogów do partycji jest moim najprostszym rozwiązaniem.
Łukasz
5

Mamy system sklepów fotograficznych z 4 milionami zdjęć. Korzystamy z bazy danych tylko w przypadku metadanych, a wszystkie obrazy są przechowywane w systemie plików przy użyciu odwróconego systemu nazewnictwa, w którym nazwy folderów są generowane na podstawie ostatniej cyfry pliku, ostatniej-1 itd. np. 000001234.jpg jest przechowywany w strukturze katalogów, takich jak 4 \ 3 \ 2 \ 1 \ 000001234.jpg.

Ten schemat działa bardzo dobrze z indeksem tożsamości w bazie danych, ponieważ wypełnia równomiernie całą strukturę katalogów.


źródło
4

Szybki punkt, nie musisz przechowywać ścieżki do pliku DB. Możesz po prostu zapisać wartość liczbową, jeśli twoje pliki są nazwane w opisany sposób. Następnie za pomocą jednego z dobrze zdefiniowanych schematów przechowywania omówionych wcześniej, możesz uzyskać indeks jako liczbę i bardzo szybko znaleźć plik, przechodząc przez strukturę katalogów.

Mr. Boy
źródło
: -? dobry szybki punkt. po prostu nie mam algorytmu do generowania ścieżki.
s.mihai,
4

Czy twoje obrazy będą musiały mieć niepowtarzalną nazwę? Czy proces generujący te obrazy może wygenerować tę samą nazwę pliku więcej niż jeden raz? Trudno powiedzieć, nie wiedząc, które urządzenie tworzy nazwę pliku, ale powiedzieć, że urządzenie jest „resetowane”, a po ponownym uruchomieniu zaczyna nazywać obrazy tak, jak to było podczas ostatniego resetowania - jeśli jest to taki problem…

Mówisz też, że za miesiąc trafisz 1 milion zdjęć. A może po tym? Jak szybko te obrazy będą nadal wypełniać system plików? Czy osiągną one w pewnym momencie poziom i osiągną poziom około 1 miliona RAZEM zdjęć, czy będą rosły z miesiąca na miesiąc?

Pytam, bo możesz zacząć projektować system plików z miesiąca na miesiąc, a potem z obrazu. Może chciałbym zasugerować przechowywanie obrazów w takiej strukturze katalogów:

imgs\yyyy\mm\filename.ext

where: yyyy = 4 digit year
         mm = 2 digit month

example:  D:\imgs\2009\12\aaa0001.jpg
          D:\imgs\2009\12\aaa0002.jpg
          D:\imgs\2009\12\aaa0003.jpg
          D:\imgs\2009\12\aaa0004.jpg
                   |
          D:\imgs\2009\12\zzz9982.jpg
          D:\imgs\2010\01\aaa0001.jpg (this is why I ask about uniqueness)
          D:\imgs\2010\01\aab0001.jpg

Miesiąc, rok, a nawet dzień jest dobry dla obrazów typu bezpieczeństwa. Nie jestem pewien, czy to właśnie robisz, ale zrobiłem to za pomocą domowej kamery bezpieczeństwa, która robiła zdjęcie co 10 sekund ... W ten sposób Twoja aplikacja może przejść do określonego czasu lub nawet zakresu, w którym możesz pomyśleć, że obraz został wygenerowany . Lub zamiast roku, miesiąca - czy jest jakieś inne „znaczenie”, które można wyprowadzić z samego pliku obrazu? Jakieś inne deskryptory inne niż podany przykład daty?

Nie zapisałbym danych binarnych w bazie danych. Nigdy nie miałem dobrych wyników / szczęścia z tego rodzaju rzeczami. Nie mogę sobie wyobrazić, że działa dobrze z 1 milionem zdjęć. Chciałbym zapisać nazwę pliku i to wszystko. Jeśli wszystkie mają być JPG, nie przechowuj nawet rozszerzenia. Stworzyłbym tabelę kontrolną, która przechowywałaby wskaźnik na serwerze pliku, dysku, ścieżce itp. W ten sposób możesz przenieść te obrazy do innego pudełka i nadal je zlokalizować. Czy chcesz oznaczyć zdjęcia słowami kluczowymi? Jeśli tak, to warto zbudować odpowiednie tabele, które pozwalają na tego rodzaju tagowanie.

Ty / inni mogłeś zająć się tymi pomysłami, kiedy odpowiadałem .. Mam nadzieję, że to pomaga ..

Taptronic
źródło
1. wszystkie pliki zostaną nazwane jednoznacznie 2. system będzie się powiększał i początkowo wydostawał z 1 miliona zdjęć, a następnie rósł w tempie kilkudziesięciu tysięcy miesięcznie. 3. w pewnym momencie w przyszłości będzie jakieś oznaczanie plików, dlatego chcę przechowywać dane db w bazie danych.
s.mihai,
3

Jestem zaangażowany w projekt, który przechowuje 8,4 miliona zdjęć w ciągu roku w celu udokumentowania stanu różnych urządzeń. Dostęp do nowszych zdjęć jest uzyskiwany częściej, a starsze obrazy są rzadko wyszukiwane, chyba że zostanie wykryty warunek, który skłonił kogoś do wkopania się w archiwa.

Moje rozwiązanie, oparte na tym zastosowaniu, polegało na stopniowym kompresowaniu obrazów do skompresowanych plików. Obrazy są plikami JPG, każdy w przybliżeniu 20 kB i nie kompresuje dużo, więc schemat kompresji ZIP jest żaden. Odbywa się to wyłącznie w celu połączenia ich w jedną pozycję systemu plików, co znacznie pomaga NTFS pod względem szybkości, jeśli chodzi o przenoszenie ich z dysku na dysk lub przeglądanie listy plików.

Obrazy starsze niż jeden dzień są łączone w „codzienny” zip; zamki starsze niż miesiąc są łączone w odpowiedni „miesięczny” zamek błyskawiczny; i wreszcie wszystko w ciągu roku nie jest już potrzebne i w związku z tym jest usuwane.

Ten system działa dobrze, ponieważ użytkownicy mogą przeglądać pliki (za pośrednictwem systemu operacyjnego lub wielu aplikacji klienckich), a wszystko nazywa się na podstawie nazw urządzeń i znaczników czasu. Zasadniczo użytkownik zna te dwie informacje i może szybko zlokalizować dowolny z milionów zdjęć.

Rozumiem, że prawdopodobnie nie ma to związku z Twoimi szczegółami, ale pomyślałem, że się podzielę.

JYelton
źródło
2

Być może schemat nazewnictwa oparty na dacie utworzenia - albo zawierający wszystkie informacje w nazwie pliku, albo (lepiej do późniejszego przeglądania) dzielący go na katalogi. Mogę wymyślić następujące, w zależności od częstotliwości generowania obrazów:

  • Kilka zdjęć generowanych każdego dnia: Year/Month/Day/Hour_Minute_Second.png
  • Kilka miesięcznie: Year/Month/Day_Hour_Minute_Second.png

itp. Dostajesz mój punkt ... =)

Tomas Aschan
źródło
z czasem nie są generowane w sposób ciągły, więc niektóre foldery stają się grube, a inne pozostają ... szczupłe :))
s.mihai
Cóż, oczywiście nie musisz tworzyć każdego folderu, tylko dlatego, że postępujesz zgodnie z tym schematem. Możesz nawet mieć Year/Month/Day/Hour/Minute- zdecydować, ile poziomów folderów potrzebujesz w zależności od częstotliwości generowania obrazów, gdy szybkość jest najwyższa - a następnie po prostu nie twórz folderów, które byłyby puste.
Tomas Aschan,
2

Byłbym skłonny stworzyć strukturę folderów opartą na dacie, np. \ Rok \ miesiąc \ dzień, i użyć znaczników czasu dla nazw plików. W razie potrzeby znaczniki czasu mogą mieć dodatkowy komponent licznika, jeśli obrazy mają być tworzone tak szybko, że może być ich więcej niż jeden w ciągu milisekundy. Dzięki zastosowaniu najbardziej znaczącej do najmniej znaczącej sekwencji do sortowania nazw, wyszukiwanie i konserwacja są dziecinnie proste. np. hhmmssmm [seq] .jpg

John Gardeniers
źródło
2

Czy zastanawiasz się nad odzyskiwaniem po awarii?

Niektóre z proponowanych tutaj rozwiązań ostatecznie zniekształcają nazwę pliku (tak, że jeśli plik fizyczny zostanie przeniesiony, stracisz kontrolę nad tym, jaki to plik). Zalecam zachowanie unikalnej fizycznej nazwy pliku, aby w przypadku uszkodzenia głównej listy lokalizacji plików można było ją ponownie wygenerować za pomocą małej powłoki, er, powershell, skryptu;)

Z tego, co tutaj czytam, brzmi to tak, jakby wszystkie te pliki były przechowywane w jednym systemie plików. Rozważ przechowywanie ich w wielu systemach plików na wielu komputerach. Jeśli masz zasoby, określ system przechowywania każdego pliku na dwóch różnych komputerach na wypadek utraty zasilania, a wymiana zajmie 2 dni.

Zastanów się, jakie procedury musisz utworzyć, aby przeprowadzić migrację plików między komputerami lub systemami plików. Możliwość zrobienia tego z twoim systemem jest na żywo, a online może zaoszczędzić ci znacznego bólu głowy na drodze.

Możesz rozważyć użycie identyfikatora GUID jako nazwy pliku fizycznego zamiast numeru przyrostowego na wypadek, gdyby twój licznik przyrostowy (kolumna tożsamości bazy danych?) Został pomieszany.

W razie potrzeby rozważ użycie sieci CDN, takiej jak Amazon S3.

Donald Byrd
źródło
2

Chociaż nie wyświetlałem zdjęć na taką skalę, wcześniej napisałem małą galerię do obsługi ~ 25 000 zdjęć na maszynie 400 MHz w. 512 MB pamięci RAM lub więcej. Niektóre doświadczenia;

  • Unikaj relacyjnych baz danych za wszelką cenę; chociaż bazy danych bez wątpienia są inteligentne w przetwarzaniu danych, nie są przeznaczone do takiego użytku (mamy wyspecjalizowane, hierarchiczne bazy danych o kluczowej wartości dla tak zwanych systemów plików ). Chociaż mam tylko przeczucie, postawiłbym, że pamięć podręczna DB wychodzi przez okno, jeśli rzucisz w nią naprawdę duże obiekty BLOB. Podczas gdy mój dostępny sprzęt znajdował się na małym końcu, nie dotykanie DB w ogóle podczas wyszukiwania obrazu dawało rzędy wielkości lepszą prędkość.

  • Zbadaj, jak zachowuje się system plików; na ext3 (lub czy to było wtedy ext2 - nie pamiętam), limit możliwości skutecznego wyszukiwania podkatalogów i plików wynosił około 256 znaków; więc mając tylko tyle plików i folderów w danym folderze. Znów zauważalne przyspieszenie. Chociaż nie wiem o NTFS, rzeczy takie jak XFS (który, o ile pamiętam, korzysta z drzewek B), są niezwykle szybkie, po prostu dlatego, że potrafią bardzo szybko wyszukiwać.

  • Rozłóż dane równomiernie; kiedy eksperymentowałem z powyższymi, próbowałem równomiernie rozdzielić dane między wszystkie katalogi (zrobiłem MD5 adresu URL i użyłem go do katalogów; /1a/2b/1a2b...f.jpg). W ten sposób dotarcie do dowolnego limitu wydajności zajmuje więcej czasu (a pamięć podręczna systemu plików i tak jest nieważna przy tak dużych zestawach danych). (przeciwnie, możesz chcieć zobaczyć, gdzie limity są wcześnie; następnie chcesz wrzucić wszystko do pierwszego dostępnego katalogu.

Morten Siebuhr
źródło
2

Może się spóźnić do gry. Ale jednym rozwiązaniem (jeśli pasuje do twojego przypadku użycia) może być skrót nazwy pliku. Jest to sposób na stworzenie łatwo odtwarzalnej ścieżki pliku przy użyciu nazwy pliku, a także utworzenie dobrze rozproszonej struktury katalogów. Na przykład możesz użyć bajtów kodu skrótu nazwy pliku jako ścieżki:

String fileName = "cat.gif";
int hash = fileName.hashCode();
int mask = 255;
int firstDir = hash & mask;
int secondDir = (hash >> 8) & mask;

Spowoduje to, że ścieżka będzie:

/172/029/cat.gif

Następnie możesz znaleźć cat.gifw strukturze katalogów, odtwarzając algorytm.

Używanie HEX jako nazw katalogów byłoby tak proste, jak konwersja intwartości:

String path = new StringBuilder(File.separator)
        .append(String.format("%02x", firstDir))
        .append(File.separator)
        .append(String.format("%02x", secondDir)
        .toString();

Wynikające z:

/AC/1D/cat.gif

Kilka lat temu napisałem o tym artykuł, a ostatnio przeniosłem go na Medium. Ma kilka dodatkowych szczegółów i przykładowy kod: Mieszanie nazw plików: Tworzenie struktury zaszyfrowanej struktury katalogów . Mam nadzieję że to pomoże!

Michael Andrews
źródło
Przechowujemy 1,8 miliarda przedmiotów, używając czegoś podobnego. To dobrze działa. Użyj skrótu, który jest szybki i ma niski wskaźnik kolizji, i jesteś gotowy.
CVVS,
1

Jeśli WSZYSTKIE nie są natychmiast wymagane i można je generować w locie, a są to małe obrazy, dlaczego nie zaimplementować pamięci LRU lub pamięci podręcznej dysku nad generatorem obrazów?

Może to uratować Cię od przechowywania i zachować gorące obrazy do wyświetlenia z pamięci?

Jé Queue
źródło
1

Właśnie uruchomiłem test na ZFS, ponieważ uwielbiam ZFS i miałem partycję 500 GB, na której miałem kompresję. Napisałem skrypt, który wygenerował 50-100 tys. Plików i umieścił je w zagnieżdżonych katalogach 1/2/3/4/5/6/7/8 (głębokość 5-8 poziomów) i pozwól mi działać przez 1 tydzień. (to nie był świetny skrypt.) Wypełnił dysk i ostatecznie miał około 25 milionów plików. Dostęp do dowolnego pliku ze znaną ścieżką był natychmiastowy. Wyświetlenie dowolnego katalogu ze znaną ścieżką było natychmiastowe.

Jednak uzyskanie listy plików (przez find) zajęło 68 godzin.

Przeprowadziłem również test umieszczając wiele plików w jednym katalogu. Przed zatrzymaniem dostałem do około 3,7 miliona plików w jednym katalogu. Wyświetlanie katalogu w celu uzyskania liczby zajęło około 5 minut. Usunięcie wszystkich plików w tym katalogu zajęło 20 godzin. Ale wyszukiwanie i dostęp do dowolnego pliku było natychmiastowe.

Stu
źródło
1

Widzę inne wzmianki o bazie danych, ale nie widzę żadnej wzmianki o tym w twoim poście. W każdym razie, moim zdaniem w tym konkretnym punkcie jest: albo trzymać się bazy danych lub systemu plików. Jeśli musisz wymieszać oba, bądź ostrożny. Sprawa się komplikuje. Ale być może będziesz musiał. Przechowywanie miliona zdjęć w bazie danych nie wydaje się najlepszym pomysłem.

Poniższa specyfikacja może Cię zainteresować, większość aparatów cyfrowych stosuje ją do zarządzania pamięcią plików: https://en.wikipedia.org/wiki/Camera_Image_File_Format

Zasadniczo tworzony jest folder, na przykład 000OLYMPUSi zdjęcia są dodawane do tego folderu (na przykład DSC0000.RAW). Gdy licznik nazw plików dotrze DSC9999.RAWdo nowego folderu, tworzony jest nowy folder ( 001OLYMPUS) i obraz jest dodawany ponownie, resetując licznik, być może z innym prefiksem (np .:) P_0000.RAW.

Alternatywnie możesz również utworzyć foldery na podstawie części nazwy pliku (wspomnianej już kilka razy). Na przykład, jeśli twoje zdjęcie ma nazwę IMG_A83743.JPG, zapisz je w IMG_\A8\3\IMG_A83743.JPG. Implementacja jest bardziej skomplikowana, ale ułatwi znalezienie plików.

W zależności od systemu plików (będzie to wymagało pewnych badań) możesz po prostu zrzucić wszystkie obrazy w jednym folderze, ale z mojego doświadczenia wynika, że ​​zwykle powoduje to problemy z wydajnością.

Rolf
źródło
0

Możesz przyjrzeć się ZFS (system plików, menedżer woluminów firmy Sun) Pozdrawiam


źródło
0

Prostym sposobem na wygenerowanie ścieżki z dużej liczby jest łatwe przekonwertowanie jej na heks, a następnie podzielenie!

na przykład 1099496034834> 0xFFFF1212>FF/FF/12/12

public string GeneratePath(long val)
{  
    string hex = val.ToString("X");
    hex=hex.PadLeft(10, '0');
    string path="";
    for(int i=0; i<hex.Length; i+=2 )
    {
        path += hex.Substring(i,2);
        if(i+2<hex.Length)
            path+="/";
    }
    return path;
}

Przechowuj i ładuj:

public long Store(Stream doc)
{
   var newId = getNewId();
   var fullpath = GeneratePath(newId)
   // store into fullpath 
   return newId;
}

public Stream Load(long id)
{
   var fullpath = GeneratePath(newId)
   var stream = ... 
   return stream;
}

Pełne kody źródłowe: https://github.com/acrobit/AcroFS

Ghominejad
źródło
-1

Niestety systemy plików są bardzo złe (wydajność z wieloma plikami na katalog lub głębokie drzewa katalogów, czas sprawdzania przy ponownym uruchomieniu, niezawodność) w zarządzaniu dużą ilością małych plików, więc powyższe rozwiązanie obejmujące pliki ZIP jest najlepsze, jeśli chcesz użyć systemu plików.

Korzystanie z menedżera bazy danych jest zdecydowanie najlepszą opcją; na przykład prosty jak BDB lub GDBM; nawet relacyjna relacja DBMS, taka jak MySQL, byłaby lepsza. Tylko leniwi ludzie, którzy nie rozumieją systemów plików i baz danych (np. Ci, którzy zamykają transakcje) zwykle używają systemów plików jako baz danych (lub nieco rzadziej odwrotnie).


źródło
-2

Co powiesz na bazę danych z tabelą zawierającą identyfikator i BLOB do przechowywania obrazu? Następnie możesz dodawać nowe tabele, gdy chcesz powiązać więcej elementów danych ze zdjęciem.

Jeśli spodziewasz się skalować, dlaczego nie skalować teraz? Zaoszczędzisz czas zarówno teraz, jak i później IMO. Zaimplementuj warstwę bazy danych raz, co jest dość łatwe na początek. Lub zaimplementuj coś z folderami i nazwami plików i bla bla bla, a później przełącz się na coś innego, gdy zaczniesz wysadzać MAX_PATH.

jdmichal
źródło
5
Byłem tam, zrobiłem to, mam blizny, aby to udowodnić. Bazy danych, w których przechowywane są zdjęcia w dużych ilościach, są nieporadne i są niewiarygodne i wymagają nadmiernej konserwacji. Znacznie lepiej przechowywać je w systemie plików, chyba że masz konkretną potrzebę, na którą może odpowiedzieć tylko baza danych (naszym
zadaniem
1
Istnieje wiele narzędzi do obsługi plików i systemów plików, od niewielu do żadnego z plikami w bazie danych.
Mark Ransom,
2
O Boże Nie. Nie używaj bazy danych jako dużej pamięci BLOB.
Neil N,
Eek. Nie wiedziałem, że bazy danych (wciąż?) Mają tak wiele problemów z BLOBami.
W jaki sposób tak złe rozwiązanie, które ma tak wiele komentarzy, może nadal mieć +1? bez obrazy dla OP (widzę, że pochodzi z SO), ale przycisk downvote jest tutaj z jakiegoś powodu!
Mark Henderson