Vraag Een miljoen afbeeldingen opslaan in het bestandssysteem


Ik heb een project dat een enorm aantal afbeeldingen zal genereren. Ongeveer 1.000.000 voor start. Het zijn geen grote afbeeldingen dus ik zal ze allemaal op één machine opslaan bij het begin.

Hoe raadt u aan om deze afbeeldingen efficiënt op te slaan? (NTFS-bestandssysteem momenteel)

Ik overweeg een naamgevingsschema ... om te beginnen hebben alle afbeeldingen een oplopende naam vanaf 1 op Ik hoop dat dit me zal helpen ze later te sorteren indien nodig, en ze in verschillende mappen te gooien.

wat zou een beter naamgevingsschema zijn:

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

of

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

enig idee hierover?


75
2017-12-17 16:52


oorsprong


Zijn ze gebonden aan specifieke gebruikers of gewoon generiek? Zijn ze gegroepeerd op welke manier dan ook?
alleen generiek. een stapel afbeeldingen gegenereerd door een aantal technische apparatuur. ik noem ze incrementeel van 1 op om een ​​idee te hebben van een tijdreflex. - s.mihai
hoe worden ze gebruikt / gebruikt? via een op maat gemaakte app of wat? - dove
Ben jij dit? i46.tinypic.com/1z55k7q.jpg
:)) ja ... 1 mil. pornobeelden :)) - s.mihai


antwoorden:


Ik raad aan om een ​​normaal bestandssysteem te gebruiken in plaats van databases. Het gebruik van een bestandssysteem is eenvoudiger dan een database, je kunt normale tools gebruiken om toegang te krijgen tot bestanden, bestandssystemen zijn ontworpen voor dit soort gebruik enz. NTFS zou prima moeten werken als een opslagsysteem.

Bewaar het daadwerkelijke pad niet naar de database. Het is beter om het volgnummer van de afbeelding op te slaan in de database en een functie te hebben die een pad kan genereren op basis van het volgnummer. bijv:

 File path = generatePathFromSequenceNumber(sequenceNumber);

Het is gemakkelijker om aan te pakken als u de structuur van mappen moet veranderen. Misschien moet je de afbeeldingen naar een andere locatie verplaatsen, heb je misschien te weinig ruimte en begin je sommige van de afbeeldingen op de schijf A en sommige op de schijf B enz. Op te slaan. Het is gemakkelijker om een ​​functie te veranderen dan om paden in de database te wijzigen .

Ik zou dit soort algoritme gebruiken voor het genereren van de directorystructuur:

  1. Maak eerst een volgnummer met voorloopnullen totdat je een string hebt van minimaal 12 cijfers. Dit is de naam voor uw bestand. Misschien wilt u een achtervoegsel toevoegen:
    • 12345 -> 000000012345.jpg
  2. Splits de string vervolgens in blokken van 2 of 3 tekens, waarbij elk blok een directoryniveau aangeeft. Een vast aantal mapniveaus hebben (bijvoorbeeld 3):
    • 000000012345 -> 000/000/012
  3. Bewaar het bestand in een ondergegenereerde directory:
    • Dus het volledige pad en bestand bestandsnaam voor bestand met sequence id 123 is 000/000/012/00000000012345.jpg
    • Voor bestand met sequentie-ID 12345678901234 het pad zou zijn 123/456/789/12345678901234.jpg

Enkele dingen om rekening te houden met directorystructuren en bestandsopslag:

  • Bovenstaand algoritme geeft je een systeem waarbij elke bladmap maximaal 1000 bestanden bevat (als je minder hebt dan 1 000 000 000 000 bestanden)
  • Er kunnen limieten zijn hoeveel bestanden en submappen een map kan bevatten, bijvoorbeeld ext3-bestandssysteem op Linux heeft een limiet van 31998 submappen per map.
  • Normale hulpmiddelen (WinZip, Windows Explorer, opdrachtregel, bash-shell, enz.) Werken mogelijk niet erg goed als u een groot aantal bestanden per map hebt (> 1000)
  • De directorystructuur zelf vereist wat schijfruimte, dus u wilt niet te veel mappen.
  • Met bovenstaande structuur kun je altijd het juiste pad vinden voor het afbeeldingsbestand door alleen maar naar de bestandsnaam te kijken, als je toevallig je mapstructuren hebt verpest.
  • Als u bestanden van verschillende machines moet openen, overweeg dan om de bestanden te delen via een netwerkbestandssysteem.
  • De bovenstaande mapstructuur zal niet werken als u veel bestanden verwijdert. Het laat "gaten" achter in de mappenstructuur. Maar aangezien u geen bestanden verwijdert, zou het goed moeten zijn.

70
2017-12-17 17:32



heel interessant! de bestandsnaam splitsen ... daar heb ik niet aan gedacht. ik neem aan dat dit de elegante manier is om het te doen: -? - s.mihai
Het gebruik van een hash (zoals MD5) als de naam van het bestand, evenals de distributie van de map, zou werken. Niet alleen zou de integriteit van de bestanden een bijkomend voordeel zijn voor het naamgevingsschema (eenvoudig te controleren), maar u hebt een redelijk gelijke verdeling in de directoryhiërarchie. Dus als je een bestand hebt met de naam "f6a5b1236dbba1647257cc4646308326.jpg", bewaar je het in "/ f / 6" (of zo diep als je nodig hebt). 2 niveaus diep geeft 256 mappen, of iets minder dan 4000 bestanden per map voor de eerste 1m-bestanden. Het zou ook heel gemakkelijk zijn om de herdistributie naar een dieper schema te automatiseren.
+1 Ik heb net gemerkt dat dit antwoord vergelijkbaar was met het antwoord dat ik net heb gepost. - 3dinfluence
Ik ben het absoluut eens over het gebruik van het bestandssysteem en het creëren van een kunstmatige identificatiecode om in mapnamen te "snappen". Maar u moet ook proberen een willekeurige verdeling van ID's te krijgen, dat wil zeggen geen volgnummer gebruiken. Dat zou je toestaan ​​om een ​​meer uitgebalanceerde boom van mappen te hebben. Bovendien kunt u met willekeurige distributie de boom gemakkelijker partitioneren over meerdere bestandssystemen. Ik zou ook een op ZFS gebaseerd SAN gebruiken met dedup ingeschakeld en een schaars volume voor elk bestandssysteem. U kunt NTFS nog steeds gebruiken door iSCSI te gebruiken om toegang te krijgen tot het SAN. - Michael Dillon
Als u in stap 2 van rechts naar links gaat, worden de bestanden gelijkmatig verdeeld. U hoeft zich ook geen zorgen te maken dat u niet voldoende nullen volhoudt omdat u een onbeperkt aantal bestanden kunt gebruiken - ropo


Ik ga mijn 2 cent waard in op een stuk van negatief advies: ga niet met een database.

Ik werk al jaren met beeldopslagdatabases: grote (1 meg-> 1 gig) bestanden, vaak gewijzigd, meerdere versies van het bestand, redelijk vaak gebruikt. De databaseproblemen die u tegenkomt bij het opslaan van grote bestanden zijn uiterst vervelend om mee om te gaan, schrijven en transactieproblemen zijn knoestig en u ondervindt vergrendelingsproblemen die grote treinen kunnen veroorzaken wrakken. Ik heb meer oefening in het schrijven van dbcc-scripts en het herstellen van tabellen van back-ups dan welke normale persoon dan ook zou moeten doen ooit hebben.

De meeste nieuwe systemen waarmee ik heb gewerkt, hebben de bestandsopslag naar het bestandssysteem geduwd en vertrouwden op databases voor niets meer dan indexeren. Bestandssystemen zijn ontworpen om dat soort misbruik aan te pakken, ze zijn veel gemakkelijker uit te breiden en je verliest zelden het hele bestandssysteem als een item beschadigd raakt.


29
2017-12-17 17:12



Ja. opmerking gemaakt! - s.mihai
Heb je gekeken naar het FILESTREAM gegevenstype van SQL 2008? Het is een kruising tussen database- en bestandssysteemopslag. - NotMe
+1 op vasthouden aan bestandsserver in plaats van een database terwijl je bezig bent met snelle en zeldzame IO-bewerkingen.
Wat als u slechts een paar honderd documenten of foto's per database opslaat - een nadeel van het gebruik van de database voor opslag? - Beep beep
+1 ... een bestandssysteem is sowieso een soort "database" (ntfs zeker), dus waarom zou je het te ingewikkeld maken. - akira


Ik denk dat de meeste sites die hiermee te maken hebben, een soort hash gebruiken om ervoor te zorgen dat de bestanden gelijkmatig worden verdeeld in de mappen.

Dus zeg dat je een hash hebt van een bestand dat zoiets als dit is 515d7eab9c29349e0cde90381ee8f810
U kunt dit op de volgende locatie laten opslaan en u kunt gebruiken hoe vaak u diep moet gaan om het aantal bestanden in elke map laag te houden.
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg

Ik heb deze benadering vele malen gezien. Je hebt nog steeds een database nodig om deze bestandshulsen aan een door mensen leesbare naam toe te wijzen en welke andere metadata je ook moet opslaan. Maar deze aanpak schalen vrij goed b / c u kunt beginnen met het distribueren van de hash-adresruimte tussen meerdere computers en of opslagpools, enz.


12
2017-12-17 20:17



Git gebruikt een vergelijkbare benadering: git-scm.com/book/en/v2/Git-Internals-Git-Objects (om dit antwoord te ondersteunen) - aexl


Idealiter zou u een aantal tests moeten uitvoeren op willekeurige toegangstijden voor verschillende structuren, aangezien uw specifieke harddrive-instellingen, caching, beschikbaar geheugen, enz. Deze resultaten kunnen veranderen.

Ervan uitgaande dat u controle hebt over de bestandsnamen, zou ik ze partitioneren op het niveau van 1000s per map. Hoe meer directoryniveaus je toevoegt, des te meer inodes je verft, dus hier is een push-pull.

bv

/ Root / [0-99] / [0-99] / filename

Notitie, http://technet.microsoft.com/en-us/library/cc781134(WS.10).aspx heeft meer details over de NTFS-instellingen. In het bijzonder: "Als u grote aantallen bestanden in een NTFS-map (300.000 of meer) gebruikt, schakelt u het genereren van korte bestandsnamen uit voor betere prestaties en vooral als de eerste zes tekens van de lange bestandsnamen vergelijkbaar zijn."

Je moet ook kijken naar het uitschakelen van bestandssysteemfuncties die je niet nodig hebt (bijvoorbeeld de laatste toegangstijd). http://www.pctools.com/guides/registry/detail/50/


11
2017-12-17 17:01



+1 voor het uitschakelen van 8.3 bestandsnaam genereren en laatste toegangstijd; dat waren het eerste dat me te binnen schoot toen ik 'enorm veel [bestanden]' en 'NTFS' (Windows) las. - rob
link naar beneden ........................ - Pacerier


Wat je ook doet, sla ze niet allemaal op in één map.

Afhankelijk van de distributie van de namen van deze afbeeldingen, kunt u een directorystructuur maken waarin u mappen van één letter op het hoogste niveau hebt waarin u een andere set submappen voor de tweede letter met afbeeldingen, enzovoort, zou hebben.

Zo:

Map img\a\b\c\d\e\f\g\ zou de afbeeldingen bevatten die beginnen met 'abcdefg' enzovoort.

U zou uw eigen geschikte diepte kunnen invoeren.

Het mooie van deze oplossing is dat de directorystructuur effectief werkt als een hashtable / woordenboek. Gegeven de naam van een afbeeldingsbestand, zult u de map kennen en een map krijgen, u zult een subset van afbeeldingen kennen die daarheen gaan.


7
2017-12-17 16:58



\ a \ b \ c \ d \ e \ f \ ik ben nu aan het doen, ik dacht dat er een wijze manier is om dit te doen. - s.mihai
Dat is een algemeen geaccepteerde oplossing voor het fysiek opslaan ervan. Het duidelijk genereren van de afbeeldings-URL's is iets dat gemakkelijk dynamisch kan worden gedaan op basis van de afbeeldingsbestandsnaam. En om ze te serveren, zou je zelfs img-a, img-b subdomeinen op de imageserver kunnen introduceren als je dat wilt, om de laadtijden te versnellen.
En +1 voor "sla ze niet allemaal op in één map". Ik ondersteun een legacy-systeem dat meer dan 47000 bestanden op een server in een enkele map heeft geplaatst en het duurt ongeveer een minuut voordat Explorer de map opent. - Mark Ransom
Door een \ b \ c \ d \ e \ f \ g te maken, wordt de mapstructuur erg diep en bevat elke map slechts enkele bestanden. Het is beter om meer dan één letter per directoryniveau, b.v. ab \ cd \ ef \ of abc \ def \. Mappen nemen ook ruimte in beslag vanaf schijf, dus u wilt er niet te veel van. - Juha Syrjälä
Ik moest een applicatie ondersteunen die 4 + miljoen bestanden allemaal in een map had; het werkte verrassend goed, maar je kon NOOIT explorer krijgen om de map te openen, het zou voortdurend de nieuwe toevoegingen sorteren. +1 zodat NTFS het aankan zonder dood te gaan. - SqlACID


Ik zou deze op het bestandssysteem opslaan, maar het hangt af van hoe snel het aantal bestanden zal groeien. Worden deze bestanden gehost op het web? Hoeveel gebruikers hebben toegang tot dit bestand? Dit zijn de vragen die moeten worden beantwoord voordat ik u een betere aanbeveling zou kunnen geven. Ik zou ook naar Haystack van Facebook kijken, ze hebben een zeer goede oplossing voor het opslaan en serveren van afbeeldingen.

Ook als u kiest voor een bestandssysteem, moet u deze bestanden partitioneren met mappen. Ik heb dit probleem bekeken en een oplossing voorgesteld, maar het is op geen enkele manier een perfecte oplossing. Ik partitioneer per hashtabel en gebruikers kun je meer lezen op mijn blog.


5
2017-12-17 16:59



de afbeeldingen zijn niet bedoeld voor frequente toegang. dus er is geen probleem mee. hun aantal zal vrij snel groeien. ik neem aan dat daar de 1mil zal zijn. merk in 1 maand. - s.mihai
ik ben geïnteresseerd in de weergave van de programmeur, zodat ik dit niet te veel overdenk - s.mihai
Dus als je geen snelle toegang nodig hebt, is Haystack waarschijnlijk niet voor jou. Het gebruik van mappen voor partities is volgens mij de eenvoudigste oplossing. - Lukasz


We hebben een fotoopslagsysteem met 4 miljoen afbeeldingen. We gebruiken de database alleen voor metagegevens en alle afbeeldingen worden opgeslagen in het bestandssysteem met behulp van een omgekeerd naamgevingssysteem, waarbij mapnamen worden gegenereerd op basis van het laatste cijfer van het bestand, laatste 1, enzovoort. bijv .: 000001234.jpg wordt opgeslagen in mapstructuur zoals 4 \ 3 \ 2 \ 1 \ 000001234.jpg.

Dit schema werkt heel goed met de identiteitsindex in de database, omdat het de volledige directorystructuur vult.


5
2017-12-30 22:10