Hûnderten miljoenen lytse bestannen effisjint opslaan. Self-Hosted oplossing

Hûnderten miljoenen lytse bestannen effisjint opslaan. Self-Hosted oplossing

Beste mienskip, Dit artikel sil rjochtsje op it effisjint opslaan en opheljen fan hûnderten miljoenen lytse bestannen. Op dit stadium wurdt de definitive oplossing foarsteld foar POSIX-kompatibele bestânsystemen mei folsleine stipe foar slûzen, ynklusyf klusterslûzen, en skynber sels sûnder krukken.

Dat ik skreau myn eigen oanpaste tsjinner foar dit doel.
Yn 'e rin fan' e útfiering fan dizze taak slagge it ús om it haadprobleem op te lossen, en tagelyk besparrings yn skiifromte en RAM te berikken, dy't ús klusterbestânsysteem sûnder genede konsumearre. Eins is sa'n oantal bestannen skealik foar elk klustere bestânsysteem.

It idee is dit:

Yn ienfâldige wurden, lytse bestannen wurde opladen fia de tsjinner, se wurde direkt opslein yn it argyf, en ek lêzen fan it, en grutte triemmen wurde pleatst njonken inoar. Skema: 1 map = 1 argyf, yn totaal hawwe wy ferskate miljoen argiven mei lytse bestannen, en net ferskate hûndert miljoen bestannen. En dit alles wurdt folslein ymplementearre, sûnder skripts of it pleatsen fan bestannen yn tar / zip-argiven.

Ik sil besykje it koart te hâlden, ik ferûntskuldigje my foarôf as it berjocht lang is.

It begon allegear mei it feit dat ik gjin gaadlike tsjinner yn 'e wrâld koe fine dy't gegevens ûntfongen fia it HTTP-protokol direkt yn argiven bewarje koe, sûnder de neidielen dy't inherent binne oan konvinsjonele argiven en objektopslach. En de reden foar it sykjen wie it Origin-kluster fan 10-tsjinners dy't groeide ta in grutte skaal, wêryn 250,000,000 lytse bestannen al sammele wiene, en de groeitrend soe net stopje.

Foar dyjingen dy't net graach artikels lêze, is in bytsje dokumintaasje makliker:

hjir и hjir.

En docker tagelyk, no is d'r in opsje allinich mei nginx binnen foar it gefal:

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

Folgjende:

As d'r in protte bestannen binne, binne wichtige boarnen nedich, en it slimste is dat guon fan har fergriemd binne. Bygelyks, by it brûken fan in klustere triemsysteem (yn dit gefal, MooseFS), nimt it bestân, nettsjinsteande de werklike grutte, altyd op syn minst 64 KB. Dat is, foar bestannen fan 3, 10 of 30 KB yn grutte, binne 64 KB nedich op skiif. As der in kwart fan in miljard triemmen binne, ferlieze wy fan 2 oant 10 terabytes. It sil net mooglik wêze om nije bestannen foar ûnbepaalde tiid te meitsjen, om't MooseFS in beheining hat: net mear as 1 miljard mei ien replika fan elke triem.

As it oantal bestannen ferheget, is in protte RAM nedich foar metadata. Faak grutte metadata-dumps drage ek by oan de slijtage fan SSD-skiven.

wZD tsjinner. Wy sette dingen yn oarder op de skiven.

De tsjinner is skreaun yn Go. Earst moast ik it oantal bestannen ferminderje. Hoe it te dwaan? Troch argivearjen, mar yn dit gefal sûnder kompresje, om't myn bestannen gewoan komprimeare ôfbyldings binne. BoltDB kaam yn 'e rêding, dy't noch út syn tekoarten helle wurde moast, dit is werom te finen yn de dokumintaasje.

Yn totaal, ynstee fan in kwart fan in miljard triemmen, yn myn gefal wiene d'r mar 10 miljoen Bolt-argiven oer. As ik de kâns hie om de hjoeddeistige triemstruktuerstruktuer te feroarjen, soe it mooglik wêze om it te ferminderjen nei sawat 1 miljoen bestannen.

Alle lytse bestannen wurde ynpakt yn Bolt-argiven, dy't automatysk de nammen krije fan 'e mappen wêryn se lizze, en alle grutte bestannen bliuwe neist de argiven; it hat gjin punt om se yn te pakken, dit is oanpasber. Lytsen wurde argivearre, grutten bliuwe ûnferoare. De tsjinner wurket transparant mei beide.

Arsjitektuer en funksjes fan 'e wZD-tsjinner.

Hûnderten miljoenen lytse bestannen effisjint opslaan. Self-Hosted oplossing

De tsjinner wurket ûnder Linux, BSD, Solaris en OSX bestjoeringssystemen. Ik haw allinnich hifke foar AMD64-arsjitektuer ûnder Linux, mar it moat wurkje foar ARM64, PPC64, MIPS64.

Wichtigste skaaimerken:

  • Multithreading;
  • Multiserver, it bieden fan fouttolerânsje en load balancing;
  • Maksimale transparânsje foar de brûker as ûntwikkelder;
  • Stipe HTTP-metoaden: GET, HEAD, PUT en DELETE;
  • Kontrolearje fan lês- en skriuwgedrach fia kliïntkoppen;
  • Stipe foar fleksibele firtuele hosts;
  • Stypje CRC-gegevensyntegriteit by skriuwen / lêzen;
  • Semi-dynamyske buffers foar minimal ûnthâld konsumpsje en optimale netwurk prestaasjes tuning;
  • Fertrage gegevens kompaktearring;
  • Derneist wurdt in multi-threaded archiver wZA oanbean foar it migrearjen fan bestannen sûnder de tsjinst te stopjen.

Echte ûnderfining:

Ik haw in lange tiid de tsjinner en archiver op live gegevens ûntwikkele en testen, no wurket it mei súkses op in kluster dat 250,000,000 lytse bestannen (ôfbyldings) omfettet yn 15,000,000 mappen op aparte SATA-skiven. In kluster fan 10 servers is in Origin-tsjinner ynstalleare efter in CDN-netwurk. Om it te tsjinjen, wurde 2 Nginx-tsjinners + 2 wZD-tsjinners brûkt.

Foar dyjingen dy't beslute om dizze tsjinner te brûken, soe it ferstannich wêze om de mapstruktuer te planjen, as fan tapassing, foar gebrûk. Lit my meitsje in reservearring daliks dat de tsjinner is net bedoeld om te proppe alles yn in 1 Bolt argyf.

Prestaasje testen:

Hoe lytser de grutte fan it zip-bestân, de flugger GET- en PUT-operaasjes wurde derop útfierd. Litte wy de totale tiid foar skriuwen fan HTTP-kliïnten fergelykje mei reguliere bestannen en Bolt-argiven, lykas lêzen. Wurkje mei bestannen fan grutte 32 KB, 256 KB, 1024 KB, 4096 KB en 32768 KB wurdt fergelike.

By it wurkjen mei Bolt-argiven wurdt de gegevensyntegriteit fan elk bestân kontrolearre (CRC wurdt brûkt), foar it opnimmen en ek nei it opnimmen, bart on-the-fly lêzen en opnij berekkening, dit yntrodusearret fansels fertragingen, mar it wichtichste ding is gegevensfeiligens.

Ik útfierd prestaasjes testen op SSD driuwfearren, sûnt tests op SATA driuwfearren net sjen litte in dúdlik ferskil.

Grafiken basearre op testresultaten:

Hûnderten miljoenen lytse bestannen effisjint opslaan. Self-Hosted oplossing
Hûnderten miljoenen lytse bestannen effisjint opslaan. Self-Hosted oplossing

Sa't jo sjen kinne, foar lytse bestannen is it ferskil yn lês- en skriuwtiden tusken argivearre en net-argivearre bestannen lyts.

Wy krije in folslein oar byld by it testen fan it lêzen en skriuwen fan bestannen fan 32 MB yn grutte:

Hûnderten miljoenen lytse bestannen effisjint opslaan. Self-Hosted oplossing

It tiidferskil tusken it lêzen fan bestannen is binnen 5-25 ms. Mei opname binne dingen slimmer, it ferskil is sawat 150 ms. Mar yn dit gefal is d'r gjin ferlet om grutte bestannen op te laden; d'r is gewoan gjin punt om dat te dwaan; se kinne apart libje fan 'e argiven.

* Technysk kinne jo dizze tsjinner brûke foar taken dy't NoSQL nedich binne.

Basismetoaden foar wurkjen mei wZD-tsjinner:

It laden fan in gewoane triem:

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

It opladen fan in bestân nei it Bolt-argyf (as de tsjinnerparameter fmaxsize, dy't de maksimale triemgrutte bepaalt dy't yn it argyf opnommen wurde kin, net oerhelle wurdt; as it oerschreden wurdt, wurdt it bestân as gewoanlik neist it argyf opladen):

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

In bestân downloade (as d'r bestannen binne mei deselde nammen op 'e skiif en yn it argyf, dan wurdt by it ynladen standert prioriteit jûn oan it net-argivearre bestân):

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

In bestân downloade fan it Bolt-argyf (twongen):

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

Beskriuwingen fan oare metoaden binne yn 'e dokumintaasje.

wZD dokumintaasje
wZA dokumintaasje

De tsjinner stipet op it stuit allinnich it HTTP-protokol; it wurket noch net mei HTTPS. De POST-metoade wurdt ek net stipe (der is noch net besletten oft it nedich is of net).

Wa't yn 'e boarnekoade graaft, sil dêr butterscotch fine, net elkenien fynt it leuk, mar ik haw de haadkoade net bûn oan 'e funksjes fan it webramt, útsein de interrupt-handler, dus yn 'e takomst kin ik it fluch opnij skriuwe foar hast elke motor.

Dwaan:

  • Untwikkeling fan jo eigen replikator en distributeur + geo foar de mooglikheid fan gebrûk yn grutte systemen sûnder klusterbestânsystemen (Alles foar folwoeksenen)
  • Mooglikheid fan folslein omkearde herstel fan metadata as it folslein ferlern is (as it brûken fan in distributeur)
  • Native protokol foar de mooglikheid om persistente netwurkferbiningen en bestjoerders te brûken foar ferskate programmeartalen
  • Avansearre mooglikheden foar it brûken fan de NoSQL-komponint
  • Kompresjes fan ferskate soarten (gzip, zstd, snappy) foar bestannen as wearden yn Bolt-argiven en foar reguliere bestannen
  • Fersifering fan ferskate soarten foar bestannen as wearden yn Bolt-argiven en foar reguliere bestannen
  • Fertrage server-side fideokonverzje, ynklusyf op GPU

Ik haw alles, Ik hoopje dat dizze tsjinner sil wêze nuttich foar immen, BSD-3 lisinsje, dûbele auteursrjocht, sûnt as der wiene gjin bedriuw dêr't ik wurkje, de tsjinner soe net hawwe skreaun. Ik bin de ienige ûntwikkelder. Ik soe tankber wêze foar alle bugs en funksje-oanfragen dy't jo fine.

Boarne: www.habr.com

Add a comment