Gem effektivt hundredvis af millioner af små filer. Selvhostet løsning

Gem effektivt hundredvis af millioner af små filer. Selvhostet løsning

Kære fællesskab, Denne artikel vil fokusere på effektiv lagring og hentning af hundreder af millioner af små filer. På dette stadium foreslås den endelige løsning til POSIX-kompatible filsystemer med fuld understøttelse af låse, inklusive klyngelåse, og tilsyneladende endda uden krykker.

Så jeg skrev min egen tilpassede server til dette formål.
I løbet af implementeringen af ​​denne opgave lykkedes det os at løse hovedproblemet og samtidig opnå besparelser i diskplads og RAM, som vores klyngefilsystem nådesløst forbrugte. Faktisk er et sådant antal filer skadeligt for ethvert klynget filsystem.

Ideen er denne:

Med enkle ord uploades små filer gennem serveren, de gemmes direkte i arkivet og læses også fra det, og store filer placeres side om side. Skema: 1 mappe = 1 arkiv, i alt har vi flere millioner arkiver med små filer, og ikke flere hundrede millioner filer. Og alt dette er implementeret fuldt ud, uden scripts eller indsættelse af filer i tar/zip-arkiver.

Jeg vil prøve at holde det kort, jeg beklager på forhånd, hvis indlægget er langt.

Det hele startede med, at jeg ikke kunne finde en passende server i verden, der kunne gemme data modtaget via HTTP-protokollen direkte i arkiver, uden de ulemper, der ligger i konventionelle arkiver og objektlagring. Og årsagen til søgningen var Origin-klyngen på 10 servere, der var vokset til stor skala, hvori der allerede var ophobet 250,000,000 små filer, og væksttendensen ville ikke stoppe.

For dem, der ikke kan lide at læse artikler, er lidt dokumentation lettere:

her и her.

Og docker på samme tid, nu er der kun en mulighed med nginx inde for en sikkerheds skyld:

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

Næste:

Hvis der er mange filer, er der brug for betydelige ressourcer, og det værste er, at nogle af dem er spildt. For eksempel, når du bruger et klynget filsystem (i dette tilfælde MooseFS), fylder filen, uanset dens faktiske størrelse, altid mindst 64 KB. Det vil sige, at for filer på 3, 10 eller 30 KB i størrelse kræves 64 KB på disk. Hvis der er en kvart milliard filer, mister vi fra 2 til 10 terabyte. Det vil ikke være muligt at oprette nye filer på ubestemt tid, da MooseFS har en begrænsning: ikke mere end 1 milliard med en replika af hver fil.

Efterhånden som antallet af filer stiger, kræves der meget RAM til metadata. Hyppige store metadata-dumps bidrager også til slid på SSD-drev.

wZD server. Vi sætter tingene i orden på diskene.

Serveren er skrevet i Go. Først og fremmest var jeg nødt til at reducere antallet af filer. Hvordan gør man det? På grund af arkivering, men i dette tilfælde uden komprimering, da mine filer kun er komprimerede billeder. BoltDB kom til undsætning, som stadig skulle elimineres fra sine mangler, det afspejles i dokumentationen.

I alt, i stedet for en kvart milliard filer, var der i mit tilfælde kun 10 millioner Bolt-arkiver tilbage. Hvis jeg havde mulighed for at ændre den nuværende mappefilstruktur, ville det være muligt at reducere den til cirka 1 million filer.

Alle små filer pakkes i Bolt-arkiver, som automatisk modtager navnene på de mapper, de er placeret i, og alle store filer forbliver ved siden af ​​arkiverne; det nytter ikke at pakke dem, dette kan tilpasses. Små arkiveres, store forbliver uændrede. Serveren arbejder gennemsigtigt med begge.

Arkitektur og funktioner i wZD-serveren.

Gem effektivt hundredvis af millioner af små filer. Selvhostet løsning

Serveren fungerer under operativsystemerne Linux, BSD, Solaris og OSX. Jeg testede kun for AMD64-arkitektur under Linux, men det burde virke for ARM64, PPC64, MIPS64.

Hovedtræk:

  • Multithreading;
  • Multiserver, der giver fejltolerance og belastningsbalancering;
  • Maksimal gennemsigtighed for brugeren eller udvikleren;
  • Understøttede HTTP-metoder: GET, HEAD, PUT og DELETE;
  • Kontrol af læse- og skriveadfærd via klientoverskrifter;
  • Understøttelse af fleksible virtuelle værter;
  • Understøtter CRC-dataintegritet ved skrivning/læsning;
  • Semidynamiske buffere til minimalt hukommelsesforbrug og optimal netværksydelsesjustering;
  • Udskudt datakomprimering;
  • Derudover tilbydes en multi-threaded arkiver wZA til migrering af filer uden at stoppe tjenesten.

Virkelig oplevelse:

Jeg har udviklet og testet serveren og arkiveren på live data i ret lang tid, nu fungerer den med succes på en klynge, der inkluderer 250,000,000 små filer (billeder) placeret i 15,000,000 mapper på separate SATA-drev. En klynge på 10 servere er en Origin-server, der er installeret bag et CDN-netværk. For at servicere den bruges 2 Nginx-servere + 2 wZD-servere.

For dem, der beslutter sig for at bruge denne server, ville det være klogt at planlægge mappestrukturen, hvis det er relevant, før brug. Lad mig tage forbehold med det samme, at serveren ikke er beregnet til at proppe alt ind i et 1 Bolt-arkiv.

Præstationstest:

Jo mindre størrelsen af ​​den zippede fil er, jo hurtigere udføres GET- og PUT-operationer på den. Lad os sammenligne den samlede tid for HTTP-klientskrivning med almindelige filer og Bolt-arkiver samt læsning. Arbejde med filer i størrelserne 32 KB, 256 KB, 1024 KB, 4096 KB og 32768 KB sammenlignes.

Når man arbejder med Bolt-arkiver, tjekkes dataintegriteten af ​​hver fil (CRC bruges), før optagelse og også efter optagelse sker der on-the-fly aflæsning og genberegning, dette medfører naturligvis forsinkelser, men det vigtigste er datasikkerhed.

Jeg udførte ydelsestest på SSD-drev, da test på SATA-drev ikke viser en klar forskel.

Grafer baseret på testresultater:

Gem effektivt hundredvis af millioner af små filer. Selvhostet løsning
Gem effektivt hundredvis af millioner af små filer. Selvhostet løsning

Som du kan se, er forskellen i læse- og skrivetider mellem arkiverede og ikke-arkiverede filer lille for små filer.

Vi får et helt andet billede, når vi tester læse- og skrivefiler på 32 MB:

Gem effektivt hundredvis af millioner af små filer. Selvhostet løsning

Tidsforskellen mellem læsning af filer er inden for 5-25 ms. Med optagelse er tingene værre, forskellen er omkring 150 ms. Men i dette tilfælde er der ingen grund til at uploade store filer; det nytter simpelthen ikke at gøre det; de kan leve adskilt fra arkiverne.

*Teknisk kan du bruge denne server til opgaver, der kræver NoSQL.

Grundlæggende metoder til at arbejde med wZD-server:

Indlæsning af en almindelig fil:

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

Upload af en fil til Bolt-arkivet (hvis serverparameteren fmaxsize, som bestemmer den maksimale filstørrelse, der kan inkluderes i arkivet, ikke overskrides; hvis den overskrides, uploades filen som normalt ved siden af ​​arkivet):

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

Download af en fil (hvis der er filer med de samme navne på disken og i arkivet, så prioriteres den ikke-arkiverede fil som standard ved downloading):

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

Download af en fil fra Bolt-arkivet (tvungen):

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

Beskrivelser af andre metoder findes i dokumentationen.

wZD dokumentation
wZA dokumentation

Serveren understøtter i øjeblikket kun HTTP-protokollen; den virker endnu ikke med HTTPS. POST-metoden understøttes heller ikke (det er endnu ikke besluttet, om det er nødvendigt eller ej).

Den, der graver i kildekoden, vil finde butterscotch der, ikke alle kan lide det, men jeg har ikke knyttet hovedkoden til funktionerne i web-frameworket, bortset fra interrupt-handleren, så i fremtiden kan jeg hurtigt omskrive den til næsten enhver motor.

ToDo:

  • Udvikling af egen replikator og distributør + geo til mulighed for brug i store systemer uden klyngefilsystemer (Alt for voksne)
  • Mulighed for fuldstændig omvendt gendannelse af metadata, hvis de går tabt fuldstændigt (hvis du bruger en distributør)
  • Native protokol for muligheden for at bruge vedvarende netværksforbindelser og drivere til forskellige programmeringssprog
  • Avancerede muligheder for at bruge NoSQL-komponenten
  • Kompressioner af forskellige typer (gzip, zstd, snappy) for filer eller værdier inde i Bolt-arkiver og for almindelige filer
  • Kryptering af forskellige typer for filer eller værdier inde i Bolt-arkiver og for almindelige filer
  • Forsinket serverside videokonvertering, inklusive på GPU

Jeg har alt, jeg håber, at denne server vil være nyttig for nogen, BSD-3-licens, dobbelt copyright, da hvis der ikke var nogen virksomhed, hvor jeg arbejder, ville serveren ikke være blevet skrevet. Jeg er den eneste udvikler. Jeg ville være taknemmelig for eventuelle fejl og funktionsanmodninger, du finder.

Kilde: www.habr.com

Tilføj en kommentar