VKontakte-ren arkitekturari eta lanari buruzko FAQ

VKontakte-ren sorreraren historia Wikipedian dago; Pavelek berak kontatu zuen. Badirudi denek ezagutzen dutela jada. HighLoad++ Pavel-en gunearen barneko, arkitektura eta egiturari buruz esan zidan 2010ean. Harrezkero zerbitzari asko filtratu dira, beraz, informazioa eguneratuko dugu: disekzionatu, barruak atera, pisatu eta VK gailua ikuspuntu teknikotik begiratuko dugu.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Alexey Akulovich (AterCattus) VKontakte taldeko backend garatzailea. Txosten honen transkripzioa plataformaren funtzionamenduari, azpiegiturari, zerbitzariei eta haien arteko elkarrekintzari buruzko maiz egiten diren galderei erantzun kolektiboa da, baina ez garapenari buruzkoa, alegia. burdinari buruz. Bereiz, datu-baseei buruz eta VK-k duenaren ordez, erregistroak biltzeari buruz eta proiektu osoaren jarraipenari buruz. Xehetasunak ebaki azpian.



Lau urte baino gehiago daramatzat backendarekin lotutako era guztietako zereginekin.

  • Hedabideak igotzea, gordetzea, prozesatzea, banatzea: bideoa, zuzeneko streaminga, audioa, argazkiak, dokumentuak.
  • Azpiegitura, plataforma, garatzaileen jarraipena, erregistroak, eskualdeko cacheak, CDN, RPC protokolo jabeduna.
  • Kanpoko zerbitzuekin integrazioa: push jakinarazpenak, kanpoko esteken analisia, RSS jarioa.
  • Lankideei hainbat galdera egiten laguntzea, eta horien erantzunak kode ezezagunetan murgiltzea eskatzen du.

Denbora horretan, gunearen osagai askotan eskua izan nuen. Esperientzia hau partekatu nahi dut.

Arkitektura orokorra

Dena, ohi bezala, eskaerak onartzen dituen zerbitzari edo zerbitzari talde batekin hasten da.

Aurrealdeko zerbitzaria

Aurreko zerbitzariak HTTPS, RTMP eta WSS bidez onartzen ditu eskaerak.

HTTPS - Webgunearen bertsio nagusi eta mugikorretarako eskaerak dira: vk.com eta m.vk.com, eta gure APIaren beste bezero ofizial eta ez-ofizial batzuk: bezero mugikorrak, mezulariak. Harrera dugu RTMP-zuzeneko emankizunetarako trafikoa aurreko zerbitzari bereiziekin eta WSS- Streaming APIrako konexioak.

HTTPS eta WSS zerbitzarietan merezi du nginx. RTMP emisioetarako, duela gutxi gure irtenbidera aldatu gara kive, baina txostenaren esparrutik kanpo dago. Akatsen tolerantziarako, zerbitzari hauek IP helbide arruntak iragartzen dituzte eta taldeka jarduten dute, zerbitzarietako batean arazoren bat izanez gero, erabiltzaileen eskaerak gal ez daitezen. HTTPS eta WSS-rako, zerbitzari hauek beraiek trafikoa enkriptatzen dute PUZaren kargaren zati bat bere gain hartzeko.

Ez dugu WSS eta RTMPri buruz gehiago hitz egingo, HTTPS eskaera estandarrei buruz baizik, web-proiektu batekin erlazionatu ohi direnak.

backend

Aurrealdearen atzean backend zerbitzariak egon ohi dira. Aurrealdeko zerbitzariak bezeroengandik jasotzen dituen eskaerak prozesatzen dituzte.

It kPHP zerbitzariak, zeinetan HTTP deabrua exekutatzen ari den, HTTPS dagoeneko deszifratuta dagoelako. kPHP exekutatzen den zerbitzari bat da prefork modeloak: prozesu nagusi bat abiarazten du, prozesu seme-alaba mordo bat, entzuteko socketak pasatzen dizkie eta haien eskaerak prozesatzen dituzte. Kasu honetan, prozesuak ez dira berrabiarazten erabiltzailearen eskaera bakoitzaren artean, baizik eta beren egoera jatorrizko zero balio-egoera berrezartzen dute - eskaeraz eskaera, berrabiarazi beharrean.

Karga banaketa

Gure backend guztiak ez dira edozein eskaera prozesatu dezaketen makina multzo handi bat. Gu haiek talde bereizietan banatuta: orokorra, mugikorra, api, bideoa, eszenaratzea... Makina talde bereizi baten arazoak ez die beste guztiei eragingo. Bideoarekin arazoak izanez gero, musika entzuten duen erabiltzaileak ez du arazoen berri ere izango. Eskaera zein backendra bidali behar den nginx-ek erabakitzen du aurrean konfigurazioaren arabera.

Bilketa metrikoa eta berregokatzea

Talde bakoitzean zenbat auto izan behar ditugun ulertzeko, guk ez fidatu QPSn. Backendak desberdinak dira, eskaera desberdinak dituzte, eskaera bakoitzak QPS kalkulatzeko konplexutasun desberdina du. Horregatik dugu karga kontzeptuarekin funtzionatzen dugu zerbitzarian bere osotasunean - CPUan eta perf.

Horrelako milaka zerbitzari ditugu. Zerbitzari fisiko bakoitzak kPHP talde bat exekutatzen du nukleo guztiak birziklatzeko (kPHP hari bakarrekoa delako).

Eduki zerbitzaria

CS edo Content Server biltegiratze bat da. CS fitxategiak gordetzen dituen zerbitzaria da eta kargatutako fitxategiak eta web frontend nagusiak esleitzen dizkion atzeko planoko era guztietako zeregin sinkronoak ere prozesatzen ditu.

Fitxategiak gordetzen dituzten dozenaka mila zerbitzari fisiko ditugu. Erabiltzaileei gustatzen zaie fitxategiak kargatzea, eta guk gordetzea eta partekatzea gustatzen zaigu. Zerbitzari horietako batzuk pu/pp zerbitzari bereziek ixten dituzte.

pu/pp

VK-n sareko fitxa ireki baduzu, pu/pp ikusi duzu.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Zer da pu/pp? Zerbitzari bat bestearen atzetik ixten badugu, bi aukera daude itxitako zerbitzarian fitxategi bat igo eta deskargatzeko: zuzenean bidez http://cs100500.userapi.com/path edo tarteko zerbitzariaren bidez - http://pu.vk.com/c100500/path.

Pu da argazkiak kargatzeko izen historikoa, eta pp argazki proxya. Hau da, zerbitzari bat argazkiak igotzeko da, eta beste bat igotzeko. Orain argazkiak kargatzen ez ezik, izena gorde egin da.

Zerbitzari hauek amaitu HTTPS saioakprozesadorearen karga biltegitik kentzeko. Gainera, erabiltzaile-fitxategiak zerbitzari horietan prozesatzen direnez, zenbat eta informazio hain sentikorra izan makina horietan, orduan eta hobeto. Adibidez, HTTPS enkriptatzeko gakoak.

Makinak gure beste makinek itxita daudenez, kanpoko IP "zuriak" ez ematea ordaindu dezakegu, eta eman "grisa". Horrela IP multzoan gorde dugu eta makinak kanpoko sarbideetatik babesten ditugula bermatu dugu; besterik gabe, ez dago IP-rik bertan sartzeko.

Partekatutako IPen erresilientzia. Akatsen tolerantziari dagokionez, eskemak berdin funtzionatzen du: hainbat zerbitzari fisikoek IP fisiko komun bat dute, eta aurrean duten hardwareak aukeratzen du eskaera non bidali. Beste aukera batzuei buruz hitz egingo dut gero.

Puntu polemikoa da kasu honetan bezeroak konexio gutxiago mantentzen ditu. Hainbat makinarentzat IP bera badago - ostalari berdinarekin: pu.vk.com edo pp.vk.com, bezero-arakatzaileak ostalari bati aldibereko eskaera-kopuruari muga bat dauka. Baina nonahiko HTTP/2 garaian, uste dut hori ez dela hain garrantzitsua.

Eskemaren desabantaila nabaria behar duela da trafiko guztia ponpatu, biltegira doa, beste zerbitzari baten bidez. Trafikoa makinen bidez ponpatzen dugunez, oraindik ezin dugu trafiko astuna puzten, adibidez, bideoa, eskema bera erabiliz. Zuzenean transmititzen dugu - bideorako bereziki biltegiratze bereizietarako zuzeneko konexioa. Eduki arinagoak proxy baten bidez transmititzen ditugu.

Duela ez asko proxyaren bertsio hobetua lortu genuen. Orain esango dizut nola desberdintzen diren ohikoetatik eta zergatik den beharrezkoa.

Sun

2017ko irailean, Oraclek, aurretik Sun erosi zuena, Sun langile kopuru handi bat kaleratu zuen. Momentu honetan enpresak existitzeari utzi diola esan dezakegu. Sistema berrirako izena aukeratzerakoan, gure administratzaileek enpresa honen memoriari omenaldia egitea erabaki zuten eta sistema berriari Sun izena jarri zioten. Gure artean "eguzkiak" deitzen diogu besterik gabe.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

PPk arazo batzuk izan zituen. IP bat talde bakoitzeko - cache eraginkorra. Hainbat zerbitzari fisikok IP helbide komun bat partekatzen dute, eta ez dago eskaera zein zerbitzaritara joango den kontrolatzeko modurik. Hori dela eta, erabiltzaile desberdinak fitxategi berera etortzen badira, zerbitzari horietan cache bat badago, fitxategia zerbitzari bakoitzaren cachean amaitzen da. Oso eskema eraginkorra da, baina ezin da ezer egin.

Ondorioz - ezin dugu edukia zatikatu, ezin dugulako talde honetarako zerbitzari zehatz bat hautatu - IP komun bat dute. Baita barneko arrazoi batzuengatik ere ezin izan zen halako zerbitzariak eskualdeetan instalatu. San Petersburgon bakarrik egon ziren.

Eguzkiekin, hautaketa sistema aldatu genuen. Orain dugu anycast bideratzea: bideratze dinamikoa, anycast, auto-egiaztapen daemon. Zerbitzari bakoitzak bere IP indibiduala du, baina azpisare komun bat. Dena konfiguratuta dago zerbitzari batek huts egiten badu, trafikoa talde bereko beste zerbitzarietan automatikoki zabaltzen da. Orain zerbitzari zehatz bat hautatzea posible da, caching erredundanterik ez, eta fidagarritasuna ez zen kaltetu.

Pisuaren euskarria. Orain beharren arabera potentzia desberdineko makinak instalatu ditzakegu, eta, gainera, behin-behineko arazoak izanez gero, lan egiten duten "eguzkien" pisuak alda ditzakegu haien gaineko karga murrizteko, "atseden hartu" eta berriro lanean hasteko.

Eduki IDaren arabera partekatzea. Bitxikeria bat zatikatzeari buruz: edukia zatikatzen dugu normalean, erabiltzaile desberdinak fitxategi berera joan daitezen β€œeguzki” beraren bitartez, cache komun bat izan dezaten.

Duela gutxi β€œClover” aplikazioa jarri dugu martxan. Zuzeneko emisioko lineako galdetegia da, non ostalariak galderak egiten dituen eta erabiltzaileek denbora errealean erantzuten duten aukerak aukeratuz. Aplikazioak txat bat dauka, non erabiltzaileak txateatzeko. Aldi berean konektatu daiteke emisiora 100 mila pertsona baino gehiago. Guztiek parte-hartzaile guztiei bidaltzen zaizkien mezuak idazten dituzte, eta avatar bat dator mezuarekin batera. "Eguzki" batean 100 mila pertsona avatar bat bila etortzen badira, batzuetan hodei baten atzean ibil daiteke.

Fitxategi beraren eskaeren eztanda jasateko, eduki mota jakin baterako da eskema ergel bat aktibatzen duguna, fitxategiak eskualdeko "eguzki" erabilgarri guztietan zabaltzen dituena.

Eguzkia barrutik

Alderantzizko proxy nginx-en, cachea RAM-n edo Optane/NVMe disko bizkorretan. Adibidea: http://sun4-2.userapi.com/c100500/path β€” "eguzkia" esteka, laugarren eskualdean, bigarren zerbitzari taldean dagoena. Bide-fitxategia ixten du, fisikoki 100500 zerbitzarian dagoena.

cover

Gure eskema arkitektonikoari nodo bat gehitzen diogu: cache-ingurunea.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Jarraian diseinuaren diagrama dago eskualdeko katxeak, 20 inguru daude. Cacheak eta "eguzkiak" kokatzen diren tokiak dira, trafikoa beraiek gorde dezaketenak.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Multimedia edukiaren cachean gordetzea da; hemen ez da erabiltzailearen daturik gordetzen - musika, bideoa, argazkiak besterik ez.

Erabiltzailearen eskualdea zehazteko, guk eskualdeetan iragarritako BGP sare-aurrizkiak biltzen ditugu. Fallback-aren kasuan, geoip datu-basea ere analizatu behar dugu IP-a aurrizkien bidez aurkitu ezin badugu. Eskualdea erabiltzailearen IParen arabera zehazten dugu. Kodean, erabiltzailearen eskualde bat edo gehiago ikus ditzakegu, geografikoki hurbilen dagoen puntuak.

Nola funtzionatzen du?

Fitxategien ospea eskualdeka zenbatzen dugu. Erabiltzailea kokatzen den eskualdeko cache-kopuru bat eta fitxategi-identifikatzaile bat daude - bikote hau hartzen dugu eta deskarga bakoitzean balorazioa handitzen dugu.

Aldi berean, deabruak -eskualdeetako zerbitzuak- noizean behin etortzen dira APIra eta esaten dute: "Halako eta halako cachea naiz, eman iezadazu nire eskualdeko fitxategi ezagunenen zerrenda oraindik nire esku ez daudenak. ” APIak balorazioen arabera ordenatutako fitxategi mordoa eskaintzen ditu, deabruak deskargatzen ditu, eskualdeetara eramaten ditu eta hortik fitxategiak entregatzen ditu. Hau da pu/pp eta Sun-en arteko oinarrizko aldea cacheetatik: fitxategia beren bitartez ematen dute berehala, nahiz eta fitxategi hau cachean ez egon, eta cacheak lehenik fitxategia berera deskargatzen du, eta gero itzultzen hasten da.

Kasu honetan lortzen dugu erabiltzaileengandik hurbilago dauden edukiak eta sareko karga zabaltzea. Adibidez, Moskuko cachetik bakarrik 1 Tbit/s baino gehiago banatzen dugu puntako orduetan.

Baina arazoak daude - cache zerbitzariak ez dira gomazkoak. Oso ezaguna den edukirako, batzuetan ez dago sare nahikorik zerbitzari bereizi baterako. Gure cache zerbitzariak 40-50 Gbit/s-koak dira, baina badago halako kanal bat guztiz estutzen duen edukia. Eskualdeko fitxategi ezagunen kopia bat baino gehiago biltegiratzea ezartzera goaz. Espero dut urte amaierarako ezarriko dugula.

Arkitektura orokorrari erreparatu diogu.

  • Eskaerak onartzen dituzten aurreko zerbitzariak.
  • Eskaerak prozesatzen dituzten backendak.
  • Bi proxy motak ixten dituzten biltegiak.
  • Eskualdeko cacheak.

Zer falta zaio diagrama honetan? Jakina, datuak gordetzen ditugun datu-baseak.

Datu-baseak edo motorrak

Ez ditugu datu-baseak, motoreak baizik - Motorrak deitzen diegu, ia ez baitugu datu-baserik orokorrean onartutako zentzuan.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Hau beharrezko neurria da. Hau gertatu zen 2008-2009an, VK-k ospearen hazkunde izugarria izan zuenean, proiektuak MySQL eta Memcache-n guztiz funtzionatu zuelako eta arazoak egon zirelako. MySQL-k fitxategiak huts egitea eta hondatzea gustatzen zitzaion, ondoren ez zen berreskuratuko, eta Memcache-k pixkanaka-pixkanaka errendimendua hondatzen joan zen eta berrabiarazi behar izan zuen.

Gero eta ezagunagoa den proiektuak biltegiratze iraunkorra zuela, datuak hondatzen zituena, eta cachea, moteltzen zena. Halako baldintzetan, zaila da hazten ari den proiektu bat garatzea. Proiektuak bideratzen zituen gauza kritikoak gure bizikleten gainean berridazten saiatzea erabaki zen.

Irtenbidea arrakastatsua izan zen. Horretarako aukera zegoen, baita muturreko beharra ere, garai hartan ez baitzegoen eskalatzeko beste modurik. Ez zegoen datu-base asko, NoSQL ez zen oraindik existitzen, MySQL, Memcache, PostrgreSQL bakarrik zeuden - eta kitto.

Funtzionamendu unibertsala. Garapena gure C garatzaileen taldeak zuzendu zuen eta dena modu koherentean egin zen. Motorra edozein dela ere, denek gutxi gorabehera fitxategi-formatu bera zuten diskoan idatzita, abiarazteko parametro berdinak, seinaleak modu berean prozesatzen zituzten eta gutxi gorabehera berdin jokatzen zuten ertz-egoeretan eta arazoen kasuan. Motorren hazkuntzarekin, administratzaileentzat komenigarria da sistema ustiatzea - ​​ez dago zoorik mantendu behar denik eta hirugarrenen datu-base berri bakoitza nola funtzionatzen ikasi behar dute, eta horrek azkar eta eroso handitu ahal izan zuen. haien zenbakia.

Motor motak

Taldeak motor dezente idatzi zituen. Hona hemen horietako batzuk: laguna, aholkuak, irudia, ipdb, gutunak, zerrendak, erregistroak, memcached, meowdb, albisteak, nostradamus, argazkia, erreprodukzio-zerrendak, pmemcached, sandbox, bilaketa, biltegiratzea, atseginak, zereginak, ...

Datu-egitura zehatz bat behar duen edo eskaera atipikoak prozesatzen dituen zeregin bakoitzeko, C taldeak motor berri bat idazten du. Zergatik ez.

Motor bereizia dugu memcached, ohiko baten antzekoa dena, baina goxotasun mordoa duena, eta moteltzen ez duena. ClickHouse ez, baina funtzionatzen du. Bereiz eskuragarri pmemcached - Is memcached iraunkorra, datuak diskoan gorde ditzakeena, gainera, RAMan sartzen dena baino, berrabiaraztean datuak ez galtzeko. Banakako zereginetarako hainbat motor daude: ilarak, zerrendak, multzoak - gure proiektuak eskatzen duen guztia.

Klusterrak

Kodearen ikuspegitik, ez dago motorrak edo datu-baseak prozesu, entitate edo instantzia gisa pentsatu beharrik. Kodeak klusterrekin lan egiten du bereziki, motor taldeekin - kluster bakoitzeko mota bat. Demagun memcached cluster bat dagoela - makina talde bat besterik ez da.

Kodeak ez du kokapen fisikoa, tamaina edo zerbitzarien kopurua ezagutu beharrik. Klusterera joaten da identifikatzaile jakin bat erabiliz.

Honek funtziona dezan, kodearen eta motoreen artean dagoen entitate bat gehiago gehitu behar duzu - proxy.

RPC proxy

Proxy lotzen duen autobusa, ia gune osoa exekutatzen baita. Aldi berean dugu zerbitzuen aurkikuntzarik ez β€” horren ordez, proxy honen konfigurazio bat dago, zeinak kluster guztien eta kluster honen zati guztien kokapena ezagutzen duena. Hau da administratzaileek egiten dutena.

Programatzaileei ez zaie batere axola zenbat, non eta zer kostatzen den - klusterera joaten dira. Horrek asko ahalbidetzen digu. Eskaera bat jasotzean, proxyak eskaera birbideratzen du, nondik jakinda - berak zehazten du hori.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Kasu honetan, proxy zerbitzuaren hutsegiteen aurkako babes puntu bat da. Motorren bat moteltzen bada edo huts egiten badu, proxyak hori ulertzen du eta horren arabera erantzuten dio bezeroaren aldetik. Honek denbora-muga kentzeko aukera ematen du - kodeak ez du motorrak erantzun arte itxaroten, baina ulertzen du ez duela funtzionatzen eta nolabait modu ezberdinean jokatu behar duela. Kodea prestatu behar da datu-baseek beti funtzionatzen ez dutelako.

Inplementazio espezifikoak

Batzuetan oraindik benetan nahi dugu motor gisa irtenbide ez-estandarra izan. Aldi berean, gure motorretarako berariaz sortutako gure prest egindako rpc-proxy ez erabiltzea erabaki zen, zeregin horretarako proxy bereizia egitea baizik.

MySQLrako, oraindik han eta hemen daukaguna, db-proxy erabiltzen dugu, eta ClickHouserako - Kittenetxea.

Orokorrean horrela funtzionatzen du. Zerbitzari jakin bat dago, kPHP, Go, Python exekutatzen ditu; oro har, gure RPC protokoloa erabil dezakeen edozein kode. Kodea lokalean exekutatzen da RPC proxy batean - kodea dagoen zerbitzari bakoitzak bere proxy lokala exekutatzen du. Eskatuz gero, proxyak ulertzen du nora joan.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Motor batek beste batera joan nahi badu, bizilaguna bada ere, proxy batetik pasatzen da, bizilaguna beste datu-zentro batean egon daitekeelako. Motorrak ez luke bere buruaz gain beste ezeren kokapena jakitean fidatu behar - hau da gure irtenbide estandarra. Baina, noski, salbuespenak daude :)

Motor guztiek funtzionatzen duten TL eskemaren adibidea.

memcache.not_found                                = memcache.Value;
memcache.strvalue	value:string flags:int = memcache.Value;
memcache.addOrIncr key:string flags:int delay:int value:long = memcache.Value;

tasks.task
    fields_mask:#
    flags:int
    tag:%(Vector int)
    data:string
    id:fields_mask.0?long
    retries:fields_mask.1?int
    scheduled_time:fields_mask.2?int
    deadline:fields_mask.3?int
    = tasks.Task;
 
tasks.addTask type_name:string queue_id:%(Vector int) task:%tasks.Task = Long;

Hau protokolo bitar bat da, zeinaren analogiko hurbilena protobuf. Eskemak aukerako eremuak, mota konplexuak - barneraturiko eskalarren luzapenak eta kontsultak aurreikusten ditu. Dena protokolo honen arabera funtzionatzen du.

RPC TL baino gehiago TCP/UDP baino gehiago... UDP?

TL eskemaren gainean exekutatzen den motorraren eskaerak exekutatzeko RPC protokoloa dugu. Horrek guztiak TCP/UDP konexio baten bidez funtzionatzen du. TCP ulergarria da, baina zergatik behar dugu maiz UDP?

UDPk laguntzen du saihestu zerbitzarien arteko konexio kopuru handi baten arazoa. Zerbitzari bakoitzak RPC proxy bat badu eta, oro har, edozein motorra joan daitekeen, zerbitzari bakoitzeko dozenaka mila TCP konexio daude. Karga bat dago, baina ez du ezertarako balio. UDPren kasuan arazo hau ez da existitzen.

TCP esku-eskubide erredundanterik ez. Hau ohiko arazoa da: motor berri bat edo zerbitzari berri bat abiarazten denean, TCP konexio asko ezartzen dira aldi berean. Eskaera arin txikietarako, adibidez, UDP karga erabilgarria, kodearen eta motorren arteko komunikazio guztia da bi UDP pakete: bata norabide batean doa, bigarrena bestean. Joan-etorri bat - eta kodeak motorraren erantzuna jaso zuen eskua eman gabe.

Bai, dena funtzionatzen du pakete-galeren ehuneko oso txikiarekin. Protokoloak birtransmisiorako eta denbora-mugarako euskarria du, baina asko galtzen badugu, ia TCP lortuko dugu, eta hori ez da errentagarria. Ez dugu UDP gidatzen ozeanoetan zehar.

Horrelako milaka zerbitzari ditugu, eta eskema bera da: zerbitzari fisiko bakoitzean motor-pack bat instalatzen da. Gehienetan hari bakarrekoak dira blokeatu gabe ahalik eta azkarren exekutatzeko, eta hari bakarreko soluzio gisa zatitzen dira. Aldi berean, ez dugu motor hauek baino fidagarriagoa den ezer, eta arreta handia jartzen zaio datuen biltegiratze iraunkorrari.

Datuen biltegiratze iraunkorra

Motorek binlog-ak idazten dituzte. Binlog-a egoera edo datuak aldatzeko gertaera bat gehitzen den fitxategi bat da. Soluzio desberdinetan modu ezberdinean deitzen da: log bitarra, Wal, AOF, baina printzipioa berdina da.

Berrabiarazten denean motorrak urte askotan binlog osoa berriro irakurtzea saihesteko, motorrek idazten dute argazkiak - uneko egoera. Beharrezkoa bada, bertatik irakurtzen dute lehenik, eta gero binlog-etik irakurtzen amaitzen dute. Binlog guztiak formatu bitar berean idazten dira - TL eskemaren arabera, administratzaileek berdin administra ditzaten beren tresnak erabiliz. Ez dago argazkien beharrik. Badago goiburu orokor bat zeinen argazkia den int, motorraren magia eta zein gorputz ez den inorentzat garrantzitsua adierazten duena. Hau argazkia grabatu duen motorraren arazo bat da.

Azkar deskribatuko dut funtzionamendu-printzipioa. Motorra martxan dagoen zerbitzari bat dago. Binlog huts berri bat irekitzen du idazteko eta gertaera bat idazten du hura aldatzeko.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Noizbait, edo berak argazki bat ateratzea erabakitzen du, edo seinale bat jasotzen du. Zerbitzariak fitxategi berri bat sortzen du, bere egoera osoa idazten du bertan, uneko binlog-aren tamaina - desplazamendua - eransten du fitxategiaren amaieran eta idazten jarraitzen du. Ez da binlog berririk sortu.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Noizbait, motorra berrabiarazten denean, binlog bat eta argazki bat egongo dira diskoan. Motorrak argazki osoa irakurtzen du eta une jakin batean bere egoera igotzen du.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Argazkia sortu zen unean zegoen posizioa eta binlog-aren tamaina irakurtzen ditu.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Binlog-aren amaiera irakurtzen du uneko egoera lortzeko eta gertaera gehiago idazten jarraitzen du. Hau eskema sinple bat da; gure motor guztiek horren arabera funtzionatzen dute.

Datuen erreplikazioa

Ondorioz, gure datuen erreplikazioa adierazpenetan oinarrituta β€” binlog-ean ez dugu orrialde aldaketarik idazten, baina hain zuzen ere aldaketa eskaerak. Sarean datorrenaren oso antzekoa, apur bat aldatuta.

Errepliketarako ez ezik, eskema bera erabiltzen da babeskopiak sortzeko. Motor bat dugu: binlog-era idazten duen idazketa-maisu bat. Administratzaileek konfiguratzen duten beste edozein tokitan, binlog hau kopiatzen da, eta kitto - babeskopia bat dugu.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Behar izanez gero erreplika irakurtzenPUZaren irakurketa-karga murrizteko, irakurketa-motorra abiarazten da, binlog-aren amaiera irakurtzen duena eta komando hauek lokalean exekutatzen dituena.

Hemen desfasea oso txikia da, eta erreplika maisuaren atzetik zenbat geratzen den jakin daiteke.

Datuak zatikatzea RPC proxyan

Nola funtzionatzen du zatiketak? Nola ulertzen du proxyak zein kluster-partidara bidali? Kodeak ez du esaten: "Bidali 15 zati!" - Ez, hau proxyak egiten du.

Eskema sinpleena firstint da β€” Eskaeraren lehenengo zenbakia.

get(photo100_500) => 100 % N.

Hau memcached testu-protokolo sinple baten adibidea da, baina, noski, kontsultak konplexuak eta egituratuak izan daitezke. Adibideak kontsultako lehen zenbakia hartzen du eta gainerakoa kluster tamainaz zatitzen denean.

Hau erabilgarria da entitate bakar baten datu-lokalitatea izan nahi dugunean. Demagun 100 erabiltzaile edo talde ID bat dela, eta kontsulta konplexuetarako entitate baten datu guztiak zati batean egotea nahi dugu.

Eskaerak klusterrean nola hedatzen diren axola ez bazaigu, badago beste aukera bat - zati osoa hashing.

hash(photo100_500) => 3539886280 % N

Hash-a, zatiketaren gainerakoa eta zati-zenbakia ere lortzen ditugu.

Bi aukera hauek bakarrik funtzionatzen dute klusterraren tamaina handitzen dugunean, zatitu edo hainbat aldiz handituko dugulako prestatuta baldin bagaude. Esate baterako, 16 zati genituen, ez dugu nahikoa, gehiago nahi dugu - 32 segurtasunez lor ditzakegu geldialdirik gabe. Multiploak ez handitu nahi baditugu, geldialdi-denbora egongo da, ezingo baitugu dena zehaztasunez banatu galerarik gabe. Aukera hauek erabilgarriak dira, baina ez beti.

Zerbitzari kopuru arbitrario bat gehitu edo kendu behar badugu, erabiltzen dugu Hashing koherentea eraztunean a la Ketama. Baina, aldi berean, datuen tokikotasuna guztiz galtzen dugu; eskaera klusterera batu behar dugu, pieza bakoitzak bere erantzun txikia itzul dezan, eta gero erantzunak proxyarekin bateratu.

Eskaera super espezifikoak daude. Honela dirudi: RPC proxy-ak eskaera jasotzen du, zein klusterra joan behar den zehazten du eta zatia zehazten du. Ondoren, idazteko maisuak daude, edo, klusterrak erreplikaren euskarria badu, erreplika batera bidaltzen du eskaeraren arabera. Proxyak hau guztia egiten du.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Erregistroak

Erregistroak hainbat modutan idazten ditugu. Agerikoena eta sinpleena da idatzi erregistroak memcache-ra.

ring-buffer: prefix.idx = line

Funtsezko aurrizki bat dago: erregistroaren izena, lerro bat eta erregistro honen tamaina dago, lerro kopurua. Ausazko zenbaki bat hartzen dugu 0tik ken 1 lerro kopurura. Memcache-ko gakoa ausazko zenbaki honekin kateatuta dagoen aurrizki bat da. Erregistro-lerroa eta uneko ordua balioan gordetzen ditugu.

Erregistroak irakurtzea beharrezkoa denean, egiten dugu Multi Get gako guztiak, denboraren arabera ordenatuta, eta horrela denbora errealean produkzio-erregistroa lortu. Ekoizpeneko zerbait denbora errealean arazketa egin behar duzunean erabiltzen da eskema, ezer hautsi gabe, beste makinetara trafikoa gelditu gabe edo baimendu gabe, baina erregistro honek ez du asko irauten.

Erregistroak fidagarri biltegiratzeko motor bat dugu log-motorra. Horregatik, hain zuzen ere, sortu zen eta asko erabiltzen da kluster kopuru handi batean. Ezagutzen dudan klusterrik handienak 600 TB-ko erregistroak gordetzen ditu.

Motorra oso zaharra da, dagoeneko 6-7 urte dituzten klusterrak daude. Konpontzen saiatzen ari garen arazoak daude, adibidez, ClickHouse aktiboki erabiltzen hasi ginen erregistroak gordetzeko.

ClickHouse-n erregistroak biltzea

Diagrama honek gure motorretan nola sartzen garen erakusten du.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Badago lokalean RPC bidez RPC-proxyra doan kodea, eta motorra nora joan behar den ulertzen du. ClickHousen erregistroak idatzi nahi baditugu, bi zati aldatu behar ditugu eskema honetan:

  • ordeztu motor batzuk ClickHouse-rekin;
  • ordezkatu RPC proxya, ClickHousera sartu ezin dena, ahal duen irtenbide batekin eta RPC bidez.

Motor sinplea da: zerbitzari batekin edo zerbitzari multzo batekin ordezkatzen dugu ClickHouse-rekin.

Eta ClickHousera joateko, egin genuen KittenHouse. KittenHousetik ClickHousera zuzenean joaten bagara, ez du aurre egingo. Nahiz eta eskaerarik egin gabe, makina kopuru handi baten HTTP konexioetatik gehitzen da. Eskemak funtziona dezan, ClickHouse duen zerbitzari batean tokiko alderantzizko proxy planteatzen da, beharrezkoak diren konexio-bolumenak jasan ditzakeen moduan idatzita dagoena. Era berean, bere baitan datuak nahiko fidagarri gorde ditzake.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Batzuetan ez dugu RPC eskema estandarrik gabeko soluzioetan ezarri nahi, adibidez, nginx-en. Hori dela eta, KittenHouse-k erregistroak UDP bidez jasotzeko gaitasuna du.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Erregistroen igorleak eta hartzaileak makina berean lan egiten badute, tokiko ostalariaren barruan UDP pakete bat galtzeko probabilitatea nahiko txikia da. RPC hirugarrenen soluzio batean ezartzeko beharraren eta fidagarritasunaren arteko konpromiso gisa, UDP bidalketa besterik ez dugu erabiltzen. Aurrerago eskema honetara itzuliko gara.

jarraipenaren

Bi erregistro mota ditugu: administratzaileek beren zerbitzarietan bildutakoak eta garatzaileek kodetik idatzitakoak. Bi neurketa motari dagozkio: sistema eta produktua.

Sistemaren neurketak

Gure zerbitzari guztietan funtzionatzen du netdata, estatistikak bildu eta bertara bidaltzen dituena Grafito Karbonoa. Hori dela eta, ClickHouse biltegiratze sistema gisa erabiltzen da, eta ez Whisper, adibidez. Beharrezkoa izanez gero, ClickHouse-tik zuzenean irakur dezakezu edo erabili Grafana metriketarako, grafikoetarako eta txostenetarako. Garatzaile gisa, nahikoa sarbide dugu Netdata eta Grafana.

Produktuen neurketak

Erosotasunerako, gauza asko idatzi ditugu. Esate baterako, Zenbak, UniqueCounts balioak estatistiketan idazteko aukera ematen duten funtzio arrunten multzo bat dago, nonbait urrunago bidaltzen direnak.

statlogsCountEvent   ( β€˜stat_name’,            $key1, $key2, …)
statlogsUniqueCount ( β€˜stat_name’, $uid,    $key1, $key2, …)
statlogsValuetEvent  ( β€˜stat_name’, $value, $key1, $key2, …)

$stats = statlogsStatData($params)

Ondoren, ordenatzeko eta taldekatzeko iragazkiak erabil ditzakegu eta estatistiketatik nahi dugun guztia egin: grafikoak eraiki, Watchdogs konfiguratu.

Oso idazten dugu metrika asko gertakarien kopurua eguneko 600 milioitik bilioi 1era bitartekoa da. Hala ere, mantendu nahi ditugu urte pare bat behintzatmetrikoen joerak ulertzeko. Guztia batzea oraindik konpondu ez dugun arazo handi bat da. Azken urteotan nola funtzionatzen duen kontatuko dizuet.

Neurri hauek idazten dituzten funtzioak ditugu tokiko memcacherasarrera kopurua murrizteko. Denbora tarte laburrean behin lokalean abian jarrita estatistikak-daemon erregistro guztiak biltzen ditu. Ondoren, deabruak neurketak bi zerbitzari geruzatan batzen ditu enbor-biltzaileak, gure makina mordo baten estatistikak biltzen dituena, haien atzean dagoen geruza hil ez dadin.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Beharrezkoa izanez gero, zuzenean idatz diezaiokegu erregistro-biltzaileei.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Baina kodetik bildumagileetara zuzenean idaztea, stas-daemom saihestuz, eskalagarria den irtenbide eskasa da, bildumagilearen karga areagotzen duelako. Irtenbidea egokia da arrazoiren batengatik ezin badugu memcache stats-daemon makinan igo, edo huts egin eta zuzenean joan ginen.

Ondoren, erregistro-biltzaileek estatistikak bateratzen dituzte meowDB - hau da gure datu-basea, metrikak ere gorde ditzake.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Ondoren, "near-SQL" hautapen bitarrak egin ditzakegu kodeatik.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Esperimentua

2018ko udan, barne hackathon bat izan genuen, eta ideia sortu zen diagramaren zati gorria ClickHousen neurketak gorde ditzakeen zerbaitekin ordezkatzen saiatzea. ClickHouse-n erregistroak ditugu - zergatik ez probatu?

VKontakte-ren arkitekturari eta lanari buruzko FAQ

KittenHouse bidez erregistroak idazten zituen eskema bat genuen.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Erabaki genuen gehitu beste "*Etxe" diagramari, neurriak zehatz-mehatz jasoko ditu formatuan gure kodeak UDP bidez idazten dituen heinean. Orduan *Etxe honek txertatze bihurtzen ditu, enbor bezala, KittenHousek ulertzen duena. Erregistro hauek ezin hobeto entregatu ditzake ClickHouse-ra, zeinak irakurtzeko gai izan beharko luke.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Memcache, stats-daemon eta logs-collectors datu-basearen eskema honekin ordezkatzen da.

VKontakte-ren arkitekturari eta lanari buruzko FAQ

Memcache, stats-daemon eta logs-collectors datu-basearen eskema honekin ordezkatzen da.

  • Hemen kodearen bidalketa bat dago, StatsHouse-n lokalean idatzita dagoena.
  • StatsHouse-k UDP neurketak idazten ditu, dagoeneko SQL txertaketa bihurtuta, KittenHouse-n loteka.
  • KittenHousek ClickHouse-ra bidaltzen ditu.
  • Irakurri nahi baditugu, StatsHouse saihestuz irakurriko ditugu - ClickHousetik zuzenean SQL arrunta erabiliz.

Ba al da oraindik esperimentua, baina gustatzen zaigu nola geratzen den. Eskemaren arazoak konpontzen baditugu, agian guztiz aldatuko gara. Pertsonalki, hala espero dut.

Eskema ez du burdina aurrezten. Zerbitzari gutxiago behar dira, tokiko estatistika-daemonak eta erregistro-biltzaileak ez dira behar, baina ClickHouse-k zerbitzari handiagoa behar du egungo eskeman daudenak baino. Zerbitzari gutxiago behar dira, baina garestiagoak eta indartsuagoak izan behar dute.

Zabaldu

Lehenik eta behin, ikus dezagun PHP inplementazioa. urtean garatzen ari gara git: erabili GitLab ΠΈ TeamCity zabaltzeko. Garapen-adarrak maisu-adarrean batzen dira, maisutik probak egiteko eszenaratzean eta eszenatzetik ekoizpenera.

Inplementatu aurretik, uneko produkzio-adarra eta aurrekoa hartzen dira, eta dif-fitxategiak kontuan hartzen dira horietan - aldaketak: sortu, ezabatu, aldatu. Aldaketa hau copyfast motor berezi baten binlog-ean erregistratzen da, eta horrek aldaketak azkar errepika ditzake gure zerbitzari-flota osoan. Hemen erabiltzen dena ez da zuzenean kopiatzea, baina esamesak erreplikatzea, zerbitzari batek bere bizilagun hurbilenei aldaketak bidaltzen dizkienean, bizilagunei, eta abar. Horri esker, kodea hamarnaka eta segundoko unitateetan egunera dezakezu flota osoan. Aldaketa erreplika lokalera iristen denean, adabaki hauek aplikatzen dizkio bereari fitxategi-sistema lokala. Rollback ere eskema beraren arabera egiten da.

KPHP ere asko zabaltzen dugu eta bere garapena ere badu git goiko diagramaren arabera. Honetatik aurrera HTTP zerbitzariaren bitarra, orduan ezin dugu diferentziarik sortu - oharra bitarrak ehunka MB pisatzen ditu. Hori dela eta, beste aukera bat dago hemen: bertsioa idatzita dago binlog copyfast. Eraikitze bakoitzean handitzen da, eta itzultzean ere handitzen da. Bertsioa zerbitzarietan errepikatu. Tokiko copyfast-ek ikusten dute bertsio berri bat sartu dela binlog-ean, eta esamesaren erreplika beraren bidez bitarren azken bertsioa hartzen dute beretzat, gure zerbitzari nagusia nekatu gabe, baina karga kontu handiz zabalduz sarean zehar. Hurrengoa dotorea berrabiaraztea bertsio berrirako.

Gure motorretan, funtsean bitarrak ere badira, eskema oso antzekoa da:

  • git master adarra;
  • bitar batean .deb;
  • bertsioa binlog copyfast-en idatzita dago;
  • zerbitzarietan errepikatu;
  • zerbitzariak .dep berri bat ateratzen du;
  • dpkg -i;
  • bertsio berrira berrabiarazi dotorea.

Aldea da gure bitarra artxiboetan bilduta dagoela .deb, eta ponpatzeko orduan dpkg -i sisteman jartzen dira. Zergatik zabaltzen da kPHP bitar gisa eta motorrak dpkg gisa? Horrela gertatu zen. Funtzionatzen du - ez ukitu.

Esteka erabilgarriak:

Alexey Akulovich Programa Batzordearen parte gisa laguntzen duen horietako bat da PHP Errusia maiatzaren 17an PHP garatzaileentzako azken boladako ekitaldirik handiena bihurtuko da. Begira ze PC polita daukagun, zer hiztunak (horietako bi PHP core garatzen ari dira!) - PHP idazten baduzu galdu ezin duzun zerbait dirudi.

Iturria: www.habr.com

Gehitu iruzkin berria