Spar plads til et globalt teknologivirksomhed på flere millioner pund med en dronningens pris for innovation

Jeg starter et nyt websted, der (forhåbentlig) vil have mange brugergenererede billeder. Jeg prøver at finde ud af den bedste måde at gemme og servere disse billeder på.

Det CMS, jeg bruger (umbraco), har et mediebibliotek, der placerer en mappe på serveren for hvert billede. Inde i der kan du have forskellige størrelser af det samme billede. Denne mappe har et ID, og ​​databasen har yderligere oplysninger til det billede sammen med ID'et for mappen.

Dette fungerer godt til små websteder, men hvad hvis billederne får op til 10.000, 100.000 eller 1.000.000? Det ser ud til, at opslaget i biblioteket vil tage lang tid at finde den korrekte mappe. Jeg er på Windows 2008, hvis det gør en forskel.

Jeg er ikke så bekymret for belastning. Jeg kan indlæse balance på min server ret let og replikere billederne på tværs af serverne. Webstedets natur har heller ikke mange brugere på det, men det kan have mange billeder.

Tak.

-Nate

REDIGERE Efter nogle overvejelser tror jeg, at jeg vil oprette en mappe til hver bruger under en rodbilledmappe og derefter have brugerens billeder under det. Jeg ville være temmelig stok, hvis jeg endda havde 5.000 brugere, så det burde ikke være så dårligt med et lineært opslag. Hvis det bliver langsomt, opdeler jeg det i mapper som /media/a/adam/image123.png.

Hvis det nogensinde bliver rigtig stort, udvider jeg ovenstående metode til at bygge et større træ. Det ville dog tage en masse indhold.

  • Leder du efter SEO-fordele, som f.eks. Muligheden for, at folk kan google dine billeder? I så fald vil du gerne navngive billederne ved hjælp af nøgleord. Ellers skal du bruge det, der er nemmest.
  • O_o 10.000, 100.000 eller 1.000.000 billeder? Hvorfor kommer kun én ting i tankerne.
  • Det er faktisk et sted til at registrere træning gennem nogle software. Hver træning gemmes som et billede i et par forskellige størrelser. Hvis du endda får 5.000 mennesker til at træne et par gange om ugen, skaleres det ret hurtigt op.

Generer en hash-værdi for hvert billede, baseret på indholdet af billedet (som SHA-1 eller SHA-2), og adskil katalogstrukturen baseret på startværdien af ​​hashen (dvs. 64 mapper, der dækker en række hashværdier:

/ billeder / 00-03 / billeder / 04-07 / billeder / 08-0B ... (osv.)

ELLER en anden sammenbrud

/ billeder / 0000 / billeder / 0001 / billeder / 0002 ... / billeder / 000A ... (osv.)

En del filer hedder 0003ABC2EFA23.png. Det findes i biblioteket: / images / 0003

Katalogets nummer repræsenterer de første cifre i hash-værdien. Du kan konfigurere det til at bruge et bredere ELLER mindre udvalg af hash-værdier. Dette giver dig mulighed for at opdele filerne i separate mapper og hurtigt finde den fil, du ønsker, baseret på denne hash.

BEMÆRK: Sørg for at overveje kollisionsopløsning af hashen (fordi det kan og sandsynligvis vil ske). Noget som 0003ABC2EFA23-01.png til den første kollision, 0003ABC2EFA23-02.png til den anden.

  • Tak for svaret. Jeg håbede, at jeg ikke behøvede at gøre dette, men jeg tror, ​​det kan være det eneste, jeg kan gøre. Er dette ret standard til styring af filer til store websteder? Det ser ud til, at der allerede skal være et .NET-bibliotek til denne ting ... Jeg ser mig omkring.
  • Jeg gør det i dag for et stort antal vedhæftede filer (ikke kun billedfiler). Andre kan også have ideer, men dette er hvad vi gør for at adskille filsystemet i håndterbare dele.

Sådanne stordriftsproblemer har effektive løsninger på skyplatforme som Azure eller AWS. Selvom vi taler om et lokalt filsystem, kan de samme begreber anvendes her. Tre ting at overveje i din løsning:

1) Fjern enhver sammenhæng mellem ressourcens attributter og dens fysiske placering. Undgå f.eks. At bruge filnavne, titler, beregnede hashværdier osv. Til at bestemme, hvor billedet skal opholde sig.

2) Brug en shardingsalgoritme, der passer til den ønskede skala og de tilgængelige ressourcer til at bestemme den fysiske placering af fotos. For eksempel, hvis du har tre bind af samme størrelse, kan din shardingsalgoritme muligvis være designet til at distribuere fotos i undermapper på diskenhederne, så pladsforbruget på disse diskenheder er afbalanceret. Du kan også distribuere fotos på en sådan måde, at læsning kan være mere effektiv ved hjælp af flere diskspindler. Det er bedst at holde tingene enkle ... numeriske sekvenser af mappenavne fungerer bedst. Her er noget udelukkende til illustrative formål og ikke beregnet til at være en anbefaling:

00000000/000 til 999 / 000.jpg til 999.jpg

00000001/000 til 999 / 000.jpg til 999.jpg

3) Brug databasetabellen til at gemme metadataene og en markør til den eller de fysiske filer.

Ved hjælp af denne tilgang vil du være i stand til at skalere dette til et stort antal billeder med god ydeevne.

  • Tak! Gør Azure og AWS den sharding for dig? Eller får du bare flere diske til at gemme filerne på, og du skal stadig udføre biblioteksstrukturen?
  • 1 Da du bruger .NET, er Azure det mere logiske valg, så jeg vil fokusere på det. På Azure har du tabeller og klatter. En tabel er en nøgle- / objektbutik, og en Blob er en binær butik. Du behøver ikke tænke på det splittende aspekt, da detaljerne i den fysiske infrastruktur er abstraheret fra dig. Du vil føje et foto til en klat og derefter tilføje en række til en tabel med den unikke identifikator, du har givet klodsen. Her er et eksempel på en Azure-fotoapp, der hjælper dig med at få et overblik: codeproject.com/Articles/106806/…

At have hvert billede i sin egen mappe virkelig er overkill, og du har ret, det begynder at forårsage ydeevne problemer, når du får masser af billeder derinde. Det faktiske punkt, hvor du når dette, afhænger af operativsystemet. Men det kan bremse tingene markant.

Da du sporer billedet i en database, kan du bruge entydigt række-id for billednavnet. Så for billedet i række 1 skal du gemme navnet som '1.jpg'. Hvis du har brug for at spore forskellige versioner eller revisioner, kan du navngive dem som '1-resized.jpg', '1-original.jpg' osv. I db kan du gemme det originale filnavn og / eller filtypenavn, der er Brugt.

Hvis du forventer en masse billeder, skal du opdele dem i flere mapper baseret på id'et ved hjælp af noget udtryk. For eksempel, truncate( id / 1000), som placerer de første 1000 billeder i katalog 0 ('0 / 1.jpg', '0/1-resized.jpg'), den næste 1000 i '1' osv. Når du skal referere til billede # 15025 , du ved, at billedet er '15 /15025.jpg '. (hvis du vil være glat, skal du placere katalognavnet med nuller, så de kan sorteres)

Hvis du ender med en million billeder, vil de blive opdelt i 1000 mapper med 1000 billeder hver, hvilket stadig kan navigeres via kommandolinjen, hvis du har brug for manuelt at styre ting.

Du nævnte, at oplysninger blev gemt i databasen ... hvorfor ikke søge i databasen og derefter gå direkte til mappen?

  • Så måske forstår jeg det ikke korrekt, men lad os sige, at vi serverer noget som dette: website.com/images/12341231.png Er det en lineær søgning gennem mappen for den fil? Det er det, jeg er bange for.
  • Jeg tror, ​​at hans problem er strategien for, hvordan man opdeler filsystemet i håndterbare blokke og ikke listen over faktiske filer. Han ønsker ikke at have alle filerne i en mappe på grund af katalogadgangsoverhead (hvilket er en reel bekymring, jeg har arbejdet med mapper med et stort antal filer før, og det forårsager nogle alvorlige ydeevneproblemer).
  • Hvis jeg forstod korrekt, var de ikke alle i den samme mappe ... hvert billede havde sin egen mappe med forskellige størrelser og anden information.
  • Du får stadig det samme store lineære blik op, hvis det hele er på et niveau, ikke?

arbejdet for dig: Charles Robertson | Ønsker du at kontakte os?

nyttige oplysninger