Lagra effektivt hundratals miljoner små filer. Self-hosted lösning

Lagra effektivt hundratals miljoner små filer. Self-hosted lösning

Bästa community, Den här artikeln kommer att fokusera på att effektivt lagra och hämta hundratals miljoner små filer. I detta skede föreslås den slutliga lösningen för POSIX-kompatibla filsystem med fullt stöd för lås, inklusive klusterlås, och till synes även utan kryckor.

Så jag skrev min egen anpassade server för detta ändamål.
Under genomförandet av denna uppgift lyckades vi lösa huvudproblemet och samtidigt uppnå besparingar i diskutrymme och RAM, vilket vårt klusterfilsystem skoningslöst konsumerade. Egentligen är ett sådant antal filer skadligt för alla klustrade filsystem.

Tanken är denna:

Med enkla ord laddas små filer upp via servern, de sparas direkt i arkivet och läses även från det, och stora filer placeras sida vid sida. Schema: 1 mapp = 1 arkiv, totalt har vi flera miljoner arkiv med små filer, och inte flera hundra miljoner filer. Och allt detta implementeras fullt ut, utan några skript eller att lägga in filer i tar/zip-arkiv.

Jag ska försöka hålla det kort, jag ber om ursäkt på förhand om inlägget är långt.

Allt började med att jag inte kunde hitta en lämplig server i världen som kunde spara data som tagits emot via HTTP-protokollet direkt i arkiv, utan de nackdelar som finns med konventionella arkiv och objektlagring. Och anledningen till sökningen var Origin-klustret med 10 servrar som hade vuxit till stor skala, där 250,000,000 XNUMX XNUMX små filer redan hade samlats, och tillväxttrenden skulle inte sluta.

För dem som inte gillar att läsa artiklar är lite dokumentation lättare:

här и här.

Och docker samtidigt, nu finns det ett alternativ endast med nginx inuti i fall:

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ästa:

Om det finns många filer behövs betydande resurser, och det värsta är att en del av dem är bortkastade. Till exempel, när du använder ett klustrat filsystem (i det här fallet MooseFS), tar filen, oavsett dess faktiska storlek, alltid upp minst 64 KB. Det vill säga för filer på 3, 10 eller 30 KB krävs 64 KB på disken. Om det finns en kvarts miljard filer förlorar vi från 2 till 10 terabyte. Det kommer inte att vara möjligt att skapa nya filer på obestämd tid, eftersom MooseFS har en begränsning: inte mer än 1 miljard med en replik av varje fil.

När antalet filer ökar behövs mycket RAM-minne för metadata. Frekventa stora metadatadumpar bidrar också till slitaget på SSD-enheter.

wZD-server. Vi ställer i ordning på diskarna.

Servern är skriven i Go. Först och främst behövde jag minska antalet filer. Hur man gör det? På grund av arkivering, men i detta fall utan komprimering, eftersom mina filer bara är komprimerade bilder. BoltDB kom till undsättning, som fortfarande måste elimineras från sina brister, detta återspeglas i dokumentationen.

Totalt, istället för en kvarts miljard filer, fanns det i mitt fall bara 10 miljoner Bolt-arkiv kvar. Om jag hade möjlighet att ändra den nuvarande katalogfilstrukturen skulle det vara möjligt att minska den till cirka 1 miljon filer.

Alla små filer packas in i Bolt-arkiv, som automatiskt får namnen på katalogerna där de finns, och alla stora filer finns kvar bredvid arkiven, det är ingen idé att packa dem, detta är anpassningsbart. Små arkiveras, stora lämnas oförändrade. Servern fungerar transparent med båda.

Arkitektur och funktioner hos wZD-servern.

Lagra effektivt hundratals miljoner små filer. Self-hosted lösning

Servern fungerar under operativsystemen Linux, BSD, Solaris och OSX. Jag testade bara för AMD64-arkitektur under Linux, men det borde fungera för ARM64, PPC64, MIPS64.

Huvuddrag:

  • Multithreading;
  • Multiserver, ger feltolerans och lastbalansering;
  • Maximal transparens för användaren eller utvecklaren;
  • HTTP-metoder som stöds: GET, HEAD, PUT och DELETE;
  • Kontroll av läs- och skrivbeteende via klientrubriker;
  • Stöd för flexibla virtuella värdar;
  • Stöd CRC-dataintegritet när du skriver/läser;
  • Semidynamiska buffertar för minimal minnesförbrukning och optimal inställning av nätverksprestanda;
  • Uppskjuten datakomprimering;
  • Dessutom erbjuds en flertrådig arkivering wZA för att migrera filer utan att stoppa tjänsten.

Verklig erfarenhet:

Jag har utvecklat och testat servern och arkiveraren på livedata ganska länge, nu fungerar den framgångsrikt på ett kluster som inkluderar 250,000,000 15,000,000 10 små filer (bilder) som finns i 2 2 XNUMX kataloger på separata SATA-enheter. Ett kluster med XNUMX servrar är en Origin-server installerad bakom ett CDN-nätverk. För att serva den används XNUMX Nginx-servrar + XNUMX wZD-servrar.

För de som bestämmer sig för att använda den här servern skulle det vara klokt att planera ut katalogstrukturen, om tillämpligt, före användning. Låt mig göra en reservation direkt att servern inte är avsedd att stoppa in allt i ett 1 Bolt-arkiv.

Prestandatester:

Ju mindre storleken på den zippade filen är, desto snabbare utförs GET- och PUT-operationer på den. Låt oss jämföra den totala tiden för HTTP-klientskrivning med vanliga filer och Bolt-arkiv, samt läsning. Arbete med filer i storlekarna 32 KB, 256 KB, 1024 KB, 4096 KB och 32768 KB jämförs.

När man arbetar med Bolt-arkiv kontrolleras dataintegriteten för varje fil (CRC används), före inspelning och även efter inspelning sker avläsning och omräkning i farten, detta medför naturligtvis förseningar, men huvudsaken är datasäkerhet.

Jag genomförde prestandatester på SSD-enheter, eftersom tester på SATA-enheter inte visar någon tydlig skillnad.

Grafer baserade på testresultat:

Lagra effektivt hundratals miljoner små filer. Self-hosted lösning
Lagra effektivt hundratals miljoner små filer. Self-hosted lösning

Som du kan se, för små filer är skillnaden i läs- och skrivtider mellan arkiverade och icke-arkiverade filer liten.

Vi får en helt annan bild när vi testar läsning och skrivning av filer på 32 MB:

Lagra effektivt hundratals miljoner små filer. Self-hosted lösning

Tidsskillnaden mellan att läsa filer är inom 5-25 ms. Med inspelning är det värre, skillnaden är cirka 150 ms. Men i det här fallet finns det inget behov av att ladda upp stora filer, det är helt enkelt ingen idé att göra det, de kan leva separat från arkiven.

*Tekniskt sett kan du använda den här servern för uppgifter som kräver NoSQL.

Grundläggande metoder för att arbeta med wZD-server:

Laddar en vanlig fil:

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

Att ladda upp en fil till Bolt-arkivet (om serverparametern fmaxsize, som bestämmer den maximala filstorleken som kan inkluderas i arkivet, inte överskrids; om den överskrids kommer filen att laddas upp som vanligt bredvid arkivet):

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

Nedladdning av en fil (om det finns filer med samma namn på disken och i arkivet, då prioriteras den oarkiverade filen vid nedladdning som standard):

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

Ladda ner en fil från Bolt-arkivet (tvingat):

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

Beskrivningar av andra metoder finns i dokumentationen.

wZD dokumentation
wZA dokumentation

Servern stöder för närvarande bara HTTP-protokollet, det fungerar inte med HTTPS ännu. POST-metoden stöds inte heller (det är ännu inte bestämt om det behövs eller inte).

Den som gräver i källkoden kommer att hitta butterscotch där, inte alla gillar det, men jag knöt inte huvudkoden till funktionerna i webbramverket, förutom avbrottshanteraren, så i framtiden kan jag snabbt skriva om den för nästan alla motor.

ToDo:

  • Utveckling av egen replikator och distributör + geo för möjlighet till användning i stora system utan klusterfilsystem (Allt för vuxna)
  • Möjlighet till fullständig omvänd återställning av metadata om den är helt förlorad (om du använder en distributör)
  • Native protokoll för möjligheten att använda beständiga nätverksanslutningar och drivrutiner för olika programmeringsspråk
  • Avancerade möjligheter att använda NoSQL-komponenten
  • Kompressioner av olika typer (gzip, zstd, snappy) för filer eller värden i Bolt-arkiv och för vanliga filer
  • Kryptering av olika typer för filer eller värden i Bolt-arkiv och för vanliga filer
  • Fördröjd videokonvertering på serversidan, inklusive på GPU

Jag har allt, jag hoppas att den här servern kommer att vara användbar för någon, BSD-3-licens, dubbel upphovsrätt, eftersom om det inte fanns något företag där jag arbetar, skulle servern inte ha skrivits. Jag är den enda utvecklaren. Jag skulle vara tacksam för alla buggar och funktionsförfrågningar du hittar.

Källa: will.com

Lägg en kommentar