Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

VKontakte izveides vēsture ir atrodama Vikipēdijā, to stāstÄ«ja pats Pāvels. Å Ä·iet, ka visi viņu jau pazÄ«st. Par HighLoad++ Pavel vietnes iekŔējo elementu, arhitektÅ«ru un struktÅ«ru man teica 2010. gadā. KopÅ” tā laika ir noplÅ«duÅ”i daudzi serveri, tāpēc mēs atjaunināsim informāciju: izgriezÄ«sim to, izņemsim iekÅ”pusi, nosvērsim un apskatÄ«sim VK ierÄ«ci no tehniskā viedokļa.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Aleksejs Akulovičs (AterCattus) aizmugursistēmas izstrādātājs VKontakte komandā. Å Ä« ziņojuma atÅ”ifrējums ir kolektÄ«va atbilde uz bieži uzdotajiem jautājumiem par platformas darbÄ«bu, infrastruktÅ«ru, serveriem un mijiedarbÄ«bu starp tiem, bet ne par attÄ«stÄ«bu, proti, par dzelzi. AtseviŔķi par datu bāzēm un to, kas VK vietā ir, par žurnālu apkopoÅ”anu un visa projekta uzraudzÄ«bu kopumā. SÄ«kāka informācija zem griezuma.



Vairāk nekā četrus gadus esmu nodarbojies ar visdažādākajiem uzdevumiem, kas saistīti ar backend.

  • AugÅ”upielādēt, uzglabāt, apstrādāt, izplatÄ«t medijus: video, tieÅ”raides, audio, fotogrāfijas, dokumentus.
  • InfrastruktÅ«ra, platforma, izstrādātāju uzraudzÄ«ba, žurnāli, reÄ£ionālās keÅ”atmiņas, CDN, patentēts RPC protokols.
  • Integrācija ar ārējiem pakalpojumiem: push paziņojumi, ārējo saiÅ”u parsÄ“Å”ana, RSS plÅ«sma.
  • PalÄ«dzu kolēģiem ar dažādiem jautājumiem, uz kuriem atbildēm ir jāiedziļinās nezināmā kodā.

Šajā laikā es iesaistījos daudzos vietnes komponentos. Gribu padalīties ar Ŕo pieredzi.

Vispārējā arhitektūra

Viss, kā parasti, sākas ar serveri vai serveru grupu, kas pieņem pieprasījumus.

PriekŔējais serveris

PriekŔējais serveris pieņem pieprasÄ«jumus, izmantojot HTTPS, RTMP un WSS.

HTTPS - tie ir pieprasÄ«jumi vietnes galvenajai un mobilajai tÄ«mekļa versijai: vk.com un m.vk.com, kā arÄ« citiem oficiālajiem un neoficiālajiem mÅ«su API klientiem: mobilajiem klientiem, kurjeriem. Mums ir pieņemÅ”ana RTMP-Trafika tieÅ”raidēm ar atseviŔķiem priekŔējiem serveriem un WSS- StraumÄ“Å”anas API savienojumi.

HTTPS un WSS serveros ir vērts nginx. RTMP apraides gadÄ«jumā mēs nesen pārgājām uz savu risinājumu kive, taču tas ir ārpus ziņojuma darbÄ«bas jomas. Lai nodroÅ”inātu kļūdu toleranci, Å”ie serveri reklamē kopÄ«gas IP adreses un darbojas grupās, lai, ja kādā no serveriem rodas problēma, lietotāju pieprasÄ«jumi nepazustu. HTTPS un WSS gadÄ«jumā Å”ie paÅ”i serveri Å”ifrē trafiku, lai paÅ”i uzņemtos daļu CPU slodzes.

Mēs nerunāsim tālāk par WSS un RTMP, bet tikai par standarta HTTPS pieprasījumiem, kas parasti ir saistīti ar tīmekļa projektu.

aizmugure

Aiz priekÅ”puses parasti ir aizmugures serveri. Viņi apstrādā pieprasÄ«jumus, ko priekŔējais serveris saņem no klientiem.

Tā kPHP serveri, kurā darbojas HTTP dēmons, jo HTTPS jau ir atÅ”ifrēts. kPHP ir serveris, kas darbojas sagatavju modeļi: sāk galveno procesu, virkni bērnu apstrādā, nodod viņiem klausÄ«Å”anās ligzdas, un viņi apstrādā viņu pieprasÄ«jumus. Å ajā gadÄ«jumā procesi netiek restartēti starp katru lietotāja pieprasÄ«jumu, bet vienkārÅ”i atiestata to stāvokli uz sākotnējo nulles vērtÄ«bas stāvokli ā€” pieprasÄ«jums pēc pieprasÄ«juma, nevis restartÄ“Å”ana.

Slodzes sadalījums

Visas mÅ«su aizmugursistēmas nav liels iekārtu kopums, kas var apstrādāt jebkuru pieprasÄ«jumu. Mēs viņus sadalÄ«tas atseviŔķās grupās: vispārÄ«gs, mobilais, api, video, inscenējums... Problēma atseviŔķās maŔīnu grupās neietekmēs visas pārējās. Ja rodas problēmas ar video, lietotājs, kurÅ” klausās mÅ«ziku, pat nezinās par problēmām. Uz kuru aizmugursistēmu nosÅ«tÄ«t pieprasÄ«jumu, nosaka nginx priekÅ”pusē atbilstoÅ”i konfigurācijai.

Metrikas vākŔana un līdzsvaroŔana

Lai saprastu, cik automaŔīnu mums ir jābÅ«t katrā grupā, mēs nepaļaujieties uz QPS. Aizmugursistēmas ir dažādas, tām ir dažādi pieprasÄ«jumi, katram pieprasÄ«jumam ir atŔķirÄ«ga QPS aprēķināŔanas sarežģītÄ«ba. Tāpēc mēs mēs darbojamies ar jēdzienu slodze uz serveri kopumā - uz CPU un perf.

Mums ir tūkstoŔiem Ŕādu serveru. Katrs fiziskais serveris vada kPHP grupu, lai pārstrādātu visus kodolus (jo kPHP ir viens pavediens).

Satura serveris

CS vai satura serveris ir krātuve. CS ir serveris, kas glabā failus, kā arÄ« apstrādā augÅ”upielādētos failus un visa veida fona sinhronos uzdevumus, ko tam pieŔķir galvenā tÄ«mekļa saskarne.

Mums ir desmitiem tÅ«kstoÅ”u fizisku serveru, kas glabā failus. Lietotājiem patÄ«k augÅ”upielādēt failus, un mums patÄ«k tos uzglabāt un koplietot. Daži no Å”iem serveriem ir slēgti ar Ä«paÅ”iem pu/pp serveriem.

pu/pp

Ja VK atvērāt tīkla cilni, jūs redzējāt pu/pp.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Kas ir pu/pp? Ja mēs aizveram vienu serveri pēc otra, ir divas iespējas faila augÅ”upielādei un lejupielādei serverÄ«, kas tika aizvērts: tieÅ”i caur http://cs100500.userapi.com/path vai caur starpserveri Sākot no http://pu.vk.com/c100500/path.

Pu ir fotoattēlu augÅ”upielādes vēsturiskais nosaukums, un pp ir fotoattēlu starpniekserveris. Tas ir, viens serveris ir paredzēts fotoattēlu augÅ”upielādei, bet otrs - augÅ”upielādei. Tagad tiek ielādētas ne tikai fotogrāfijas, bet arÄ« saglabāts nosaukums.

Å ie serveri pārtraukt HTTPS sesijaslai noņemtu procesora slodzi no krātuves. Turklāt, tā kā lietotāju faili tiek apstrādāti Å”ajos serveros, jo mazāk sensitÄ«va informācija tiek glabāta Å”ajās iekārtās, jo labāk. Piemēram, HTTPS Å”ifrÄ“Å”anas atslēgas.

Tā kā iekārtas ir slēgtas ar citām mÅ«su maŔīnām, mēs varam atļauties tām nepieŔķirt "baltos" ārējos IP, un dot "pelēku". Tādā veidā mēs ietaupÄ«jām IP pÅ«lu un garantējām, ka maŔīnas aizsargās no ārējās piekļuves - vienkārÅ”i nav IP, lai tajā iekļūtu.

NoturÄ«ba, izmantojot koplietotus IP. AttiecÄ«bā uz kļūdu toleranci shēma darbojas tāpat - vairākiem fiziskajiem serveriem ir kopÄ«gs fiziskais IP, un tiem priekŔā esoŔā aparatÅ«ra izvēlas, kur nosÅ«tÄ«t pieprasÄ«jumu. Par citām iespējām es runāŔu vēlāk.

PretrunÄ«gi vērtētais ir tas, ka Å”ajā gadÄ«jumā klients saglabā mazāk savienojumu. Ja vairākām maŔīnām ir viena un tā pati IP ā€” ar vienu un to paÅ”u resursdatoru: pu.vk.com vai pp.vk.com, klienta pārlÅ«kprogrammā ir ierobežots vienlaicÄ«gu pieprasÄ«jumu skaits vienam resursdatoram. Bet visuresoŔā HTTP/2 laikā uzskatu, ka tas vairs nav tik aktuāli.

Shēmas acÄ«mredzamais trÅ«kums ir tāds, ka tas ir jādara sÅ«knējiet visu satiksmi, kas nonāk krātuvē caur citu serveri. Tā kā mēs sÅ«knējam satiksmi caur maŔīnām, mēs vēl nevaram sÅ«knēt smago satiksmi, piemēram, video, izmantojot to paÅ”u shēmu. Mēs to pārraidām tieÅ”i - atseviŔķs tieÅ”s savienojums atseviŔķām krātuvēm Ä«paÅ”i video. Mēs pārsÅ«tām vieglāku saturu, izmantojot starpniekserveri.

Pirms neilga laika mēs saņēmām uzlabotu starpniekservera versiju. Tagad es jums pastāstÄ«Å”u, kā tie atŔķiras no parastajiem un kāpēc tas ir nepiecieÅ”ams.

Saule

2017. gada septembrÄ« Oracle, kas iepriekÅ” bija iegādājies Sun, atlaida milzÄ«gu skaitu Sun darbinieku. Var teikt, ka uz Å”o brÄ«di uzņēmums beidza pastāvēt. Izvēloties nosaukumu jaunajai sistēmai, mÅ«su administratori nolēma godināt Ŕī uzņēmuma piemiņu un nosauca jauno sistēmu Sun. Mēs savā starpā viņu vienkārÅ”i saucam par "saulÄ«tēm".

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

pp bija dažas problēmas. Viena IP katrai grupai - neefektÄ«va keÅ”atmiņa. Vairākiem fiziskiem serveriem ir kopÄ«ga IP adrese, un nav iespējams kontrolēt, uz kuru serveri tiks nosÅ«tÄ«ts pieprasÄ«jums. Tāpēc, ja vienam un tam paÅ”am failam nāk dažādi lietotāji, tad, ja Å”ajos serveros ir keÅ”atmiņa, fails nonāk katra servera keÅ”atmiņā. Å Ä« ir ļoti neefektÄ«va shēma, taču neko nevarēja darÄ«t.

SekojoÅ”i - mēs nevaram sadalÄ«t saturu, jo Å”ai grupai nevaram izvēlēties konkrētu serveri ā€“ tiem ir kopÄ«gs IP. ArÄ« dažu iekŔēju iemeslu dēļ mums ir reÄ£ionos nebija iespējams uzstādÄ«t Ŕādus serverus. Viņi stāvēja tikai Sanktpēterburgā.

Ar sauli mainÄ«jām atlases sistēmu. Tagad mums ir Anycast marÅ”rutÄ“Å”ana: dinamiskā marÅ”rutÄ“Å”ana, Anycast, paÅ”pārbaudes dēmons. Katram serverim ir savs individuālais IP, bet kopÄ«gs apakÅ”tÄ«kls. Viss ir konfigurēts tā, ka, ja viens serveris neizdodas, trafiks automātiski tiek izplatÄ«ts pa citiem tās paÅ”as grupas serveriem. Tagad ir iespējams izvēlēties konkrētu serveri, nav liekas keÅ”atmiņas, un uzticamÄ«ba netika ietekmēta.

Svara atbalsts. Tagad varam atļauties uzstādÄ«t dažādas jaudas maŔīnas pēc vajadzÄ«bas, kā arÄ« Ä«slaicÄ«gu problēmu gadÄ«jumā mainÄ«t darba ā€œsaulÄ«Å”uā€ svarus, lai samazinātu to slodzi, lai tās ā€œatpÅ«stosā€ un atsāktu strādāt.

DalÄ«Å”ana pēc satura ID. SmieklÄ«ga lieta par sadalÄ«Å”anu: mēs parasti sadalām saturu, lai dažādi lietotāji dotos uz vienu un to paÅ”u failu caur vienu un to paÅ”u "sauli", lai viņiem bÅ«tu kopÄ«ga keÅ”atmiņa.

Mēs nesen uzsākām lietojumprogrammu ā€œÄ€boliņŔā€. Å Ä« ir tieÅ”saistes viktorÄ«na tieÅ”raidē, kurā vadÄ«tājs uzdod jautājumus un lietotāji atbild reāllaikā, izvēloties iespējas. Lietojumprogrammai ir tērzÄ“Å”ana, kurā lietotāji var tērzēt. Var vienlaikus izveidot savienojumu ar apraidi vairāk nekā 100 tÅ«kstoÅ”i cilvēku. Viņi visi raksta ziņojumus, kas tiek nosÅ«tÄ«ti visiem dalÄ«bniekiem, un kopā ar ziņojumu nāk iemiesojums. Ja pēc viena iemiesojuma vienā ā€œsaulÄ«tēā€ nāk 100 tÅ«kstoÅ”i cilvēku, tad tas dažkārt var aizripot aiz mākoņa.

Lai izturētu viena un tā paÅ”a faila pieprasÄ«jumu pārrāvumus, noteikta veida saturam mēs ieslēdzam stulbu shēmu, kas izplata failus pa visām pieejamajām ā€œsaulÄ«tēmā€ reÄ£ionā.

Saule no iekŔpuses

Reversais starpniekserveris nginx, keÅ”atmiņa vai nu RAM, vai ātrajos Optane/NVMe diskos. Piemērs: http://sun4-2.userapi.com/c100500/path ā€” saite uz ā€œsauliā€, kas atrodas ceturtajā reÄ£ionā, otrajā serveru grupā. Tas aizver ceļa failu, kas fiziski atrodas serverÄ« 100500.

KeÅ”atmiņa

Mēs savai arhitektÅ«ras shēmai pievienojam vēl vienu mezglu - keÅ”atmiņas vidi.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Zemāk ir izkārtojuma diagramma reÄ£ionālās keÅ”atmiņas, tādu ir apmēram 20. Tās ir vietas, kur atrodas keÅ”atmiņas un ā€œsaulesā€, kas var keÅ”atmiņā saglabāt trafiku caur sevi.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Tā ir multivides satura saglabāŔana keÅ”atmiņā; Å”eit netiek glabāti nekādi lietotāja dati ā€” tikai mÅ«zika, video, fotoattēli.

Lai noteiktu lietotāja reÄ£ionu, mēs mēs apkopojam reÄ£ionos izziņotos BGP tÄ«kla prefiksus. AtkāpÅ”anās gadÄ«jumā mums ir arÄ« jāparsē geoip datubāze, ja mēs nevaram atrast IP pēc prefiksiem. Mēs nosakām reÄ£ionu pēc lietotāja IP. Kodā varam aplÅ«kot vienu vai vairākus lietotāja reÄ£ionus ā€“ tos punktus, kuriem viņŔ Ä£eogrāfiski atrodas vistuvāk.

Kā tas strādā?

Mēs uzskaitām failu popularitāti pēc reÄ£iona. Ir vairākas reÄ£ionālās keÅ”atmiņas, kurā atrodas lietotājs, un faila identifikators ā€” mēs ņemam Å”o pāri un paaugstinām vērtējumu ar katru lejupielādi.

Tajā paŔā laikā dēmoni - pakalpojumi reÄ£ionos - laiku pa laikam ierodas API un saka: ā€œEs esmu tāda un tāda keÅ”atmiņa, iedodiet man sarakstu ar populārākajiem failiem manā reÄ£ionā, kas vēl nav manā rÄ«cÄ«bā. ā€ API nodroÅ”ina virkni failu, kas sakārtoti pēc vērtējuma, dēmons tos lejupielādē, aizved uz reÄ£ioniem un piegādā failus no turienes. Å Ä« ir bÅ«tiskā atŔķirÄ«ba starp pu/pp un Sun no keÅ”atmiņām: viņi nekavējoties nodod failu caur sevi, pat ja Ŕī faila nav keÅ”atmiņā, un keÅ”atmiņa vispirms lejupielādē failu sev un pēc tam sāk to atdot.

Å ajā gadÄ«jumā mēs saņemam saturam tuvāk lietotājiem un tÄ«kla slodzes izkliedÄ“Å”ana. Piemēram, tikai no Maskavas keÅ”atmiņas mēs pÄ«Ä·a stundās izplatām vairāk nekā 1 Tbit/s.

Bet ir problēmas - keÅ”atmiņas serveri nav gumijas. ÄŖpaÅ”i populāram saturam dažkārt nepietiek tÄ«kla atseviŔķam serverim. MÅ«su keÅ”atmiņas serveri ir 40-50 Gbit/s, bet ir saturs, kas pilnÄ«bā aizsprosto Ŕādu kanālu. Mēs virzāmies uz vairāk nekā vienas populāru failu kopiju glabāŔanas ievieÅ”anu reÄ£ionā. Ceru, ka lÄ«dz gada beigām to Ä«stenosim.

Mēs apskatījām vispārējo arhitektūru.

  • PriekŔējie serveri, kas pieņem pieprasÄ«jumus.
  • Aizmugursistēmas, kas apstrādā pieprasÄ«jumus.
  • Krātuves, kuras aizver divu veidu starpniekserveri.
  • ReÄ£ionālās keÅ”atmiņas.

Kas trÅ«kst Å”ajā diagrammā? Protams, datu bāzes, kurās mēs glabājam datus.

Datu bāzes vai dzinēji

Mēs tos saucam nevis par datubāzēm, bet gan par dzinējiem - Dzinējiem, jo ā€‹ā€‹mums praktiski nav datubāzu vispārpieņemtā izpratnē.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Tas ir nepiecieÅ”ams pasākums. Tas notika tāpēc, ka 2008.ā€“2009. gadā, kad VK popularitāte strauji pieauga, projekts pilnÄ«bā darbojās uz MySQL un Memcache, un radās problēmas. MySQL patika avarēt un bojāt failus, pēc tam tas vairs neatkopās, un Memcache veiktspēja pakāpeniski pasliktinājās, un tā bija jārestartē.

Izrādās, ka arvien populārākajam projektam bija pastāvÄ«ga krātuve, kas sabojā datus, un keÅ”atmiņa, kas palēninās. Šādos apstākļos ir grÅ«ti izstrādāt augoÅ”u projektu. Tika nolemts mēģināt pārrakstÄ«t kritiskās lietas, uz kurām projekts bija vērsts uz mÅ«su paÅ”u velosipēdiem.

Risinājums bija veiksmÄ«gs. Bija iespēja to izdarÄ«t, kā arÄ« ārkārtēja nepiecieÅ”amÄ«ba, jo citi mērogoÅ”anas veidi tajā laikā nepastāvēja. Nebija daudz datu bāzu, NoSQL vēl neeksistēja, bija tikai MySQL, Memcache, PostrgreSQL - un viss.

Universāla darbÄ«ba. Izstrādi vadÄ«ja mÅ«su C izstrādātāju komanda, un viss tika darÄ«ts konsekventi. NeatkarÄ«gi no dzinēja tiem visiem bija aptuveni vienāds faila formāts, kas tika ierakstÄ«ts diskā, vienādi palaiÅ”anas parametri, vienādi apstrādāti signāli un aptuveni vienādi izturējās malu situāciju un problēmu gadÄ«jumā. Pieaugot dzinējiem, administratoriem ir ērti darboties ar sistēmu - nav zoodārza, kas bÅ«tu jāuztur, un viņiem ir no jauna jāmācās darboties ar katru jaunu treÅ”o personu datu bāzi, kas ļāva ātri un ērti palielināt to numurs.

Dzinēju veidi

Komanda uzrakstÄ«ja diezgan daudz dzinēju. Å eit ir tikai daži no tiem: draugs, padomi, attēls, ipdb, burti, saraksti, žurnāli, atmiņa, meowdb, ziņas, nostradamus, fotoattēls, atskaņoÅ”anas saraksti, pmemcached, smilÅ”kaste, meklÄ“Å”ana, krātuve, atzÄ«mes PatÄ«k, uzdevumi,ā€¦

Katram uzdevumam, kam nepiecieÅ”ama noteikta datu struktÅ«ra vai kas apstrādā netipiskus pieprasÄ«jumus, C komanda raksta jaunu dzinēju. Kāpēc ne.

Mums ir atseviŔķs dzinējs memcached, kas ir lÄ«dzÄ«gs parastajam, bet ar gardumu gÅ«zmu un kas nemazina ātrumu. Nav ClickHouse, bet tas arÄ« darbojas. Pieejams atseviŔķi pmemcached -Å o neatlaidÄ«gi iespiests atmiņā, kas var arÄ« glabāt datus diskā, turklāt nekā iekļaujas RAM, lai restartējot nezaudētu datus. AtseviŔķu uzdevumu veikÅ”anai ir dažādi dzinēji: rindas, saraksti, komplekti - viss, kas nepiecieÅ”ams mÅ«su projektam.

Kopas

No koda viedokļa nav vajadzÄ«bas uzskatÄ«t dzinējus vai datu bāzes kā procesus, entÄ«tijas vai gadÄ«jumus. Kods darbojas Ä«paÅ”i ar klasteriem, ar dzinēju grupām - viens tips katrā klasterÄ«. Pieņemsim, ka ir keÅ”atmiņā saglabāts klasteris ā€” tā ir tikai maŔīnu grupa.

Kodam vispār nav jāzina serveru fiziskā atraÅ”anās vieta, izmērs vai skaits. ViņŔ dodas uz kopu, izmantojot noteiktu identifikatoru.

Lai tas darbotos, jums jāpievieno vēl viena entītija, kas atrodas starp kodu un dzinējiem - pilnvara.

RPC starpniekserveris

Starpniekserveris savienojoÅ”ais autobuss, kurā darbojas gandrÄ«z visa vietne. Tajā paŔā laikā mums ir nav pakalpojuma atklāŔanas ā€” tā vietā Å”im starpniekserveram ir konfigurācija, kas zina visu klasteru un visu Ŕī klastera fragmentu atraÅ”anās vietu. LÅ«k, ko dara administratori.

Programmētājiem ir pilnÄ«gi vienalga, cik, kur un ko tas maksā - viņi vienkārÅ”i dodas uz kopu. Tas mums ļauj daudz. Saņemot pieprasÄ«jumu, starpniekserveris pāradresē pieprasÄ«jumu, zinot, kur - tas pats to nosaka.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Šajā gadījumā starpniekserveris ir aizsardzības punkts pret pakalpojuma kļūmi. Ja kāds dzinējs palēninās vai avarē, starpniekserveris to saprot un attiecīgi reaģē uz klienta pusi. Tas ļauj noņemt taimautu - kods negaida dzinēja reakciju, bet saprot, ka tas nedarbojas un ir jārīkojas kaut kā savādāk. Kods ir jāsagatavo tam, ka datu bāzes ne vienmēr strādā.

Konkrētas ievieÅ”anas

Dažreiz mēs joprojām ļoti vēlamies, lai kā dzinējs bÅ«tu kāds nestandarta risinājums. Tajā paŔā laikā tika nolemts neizmantot mÅ«su gatavo rpc-proxy, kas tika izveidots Ä«paÅ”i mÅ«su dzinējiem, bet gan uzdevumam izveidot atseviŔķu starpniekserveri.

MySQL, kas mums joprojām ir Å”eit un tur, mēs izmantojam db-proxy, un ClickHouse - Kaķēnu māja.

Kopumā tas darbojas Ŕādi. Ir noteikts serveris, tajā darbojas kPHP, Go, Python - vispār jebkurÅ” kods, kas var izmantot mÅ«su RPC protokolu. Kods darbojas lokāli uz RPC starpniekservera ā€” katrs serveris, kurā atrodas kods, palaiž savu lokālo starpniekserveri. Pēc pieprasÄ«juma pilnvarnieks saprot, kur doties.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Ja viens dzinējs vēlas pāriet uz citu, pat ja tas ir kaimiņŔ, tas iet caur starpniekserveri, jo kaimiņŔ var bÅ«t citā datu centrā. Dzinējam nevajadzētu paļauties uz to, ka zina nekam citam, izņemot sevi ā€“ tas ir mÅ«su standarta risinājums. Bet protams ir izņēmumi :)

TL shēmas piemērs, saskaņā ar kuru darbojas visi dzinēji.

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;

Å is ir binārais protokols, kura tuvākais analogs ir protobuf. Shēmā ir noteikti izvēles lauki, sarežģīti veidi - iebÅ«vēto skalāru paplaÅ”inājumi un vaicājumi. Viss darbojas saskaņā ar Å”o protokolu.

RPC, izmantojot TL, izmantojot TCP/UDPā€¦ UDP?

Mums ir RPC protokols dzinēju pieprasījumu izpildei, kas darbojas papildus TL shēmai. Tas viss darbojas, izmantojot TCP/UDP savienojumu. TCP ir saprotams, bet kāpēc mums bieži ir vajadzīgs UDP?

UDP palÄ«dz izvairieties no liela skaita savienojumu starp serveriem problēmas. Ja katram serverim ir RPC starpniekserveris un kopumā tas var pāriet uz jebkuru dzinēju, tad vienam serverim ir desmitiem tÅ«kstoÅ”u TCP savienojumu. Slodze ir, bet nekam neder. UDP gadÄ«jumā Ŕī problēma nepastāv.

Nav lieka TCP rokasspiediena. Tā ir tipiska problēma: kad tiek palaists jauns dzinējs vai jauns serveris, vienlaikus tiek izveidoti daudzi TCP savienojumi. Nelieliem, viegliem pieprasījumiem, piemēram, UDP kravnesība, visa saziņa starp kodu un dzinēju tiek veikta divas UDP paketes: viens lido vienā virzienā, otrs otrā. Viens brauciens turp un atpakaļ - un kods saņēma atbildi no dzinēja bez rokasspiediena.

Jā, tas viss vienkārÅ”i darbojas ar ļoti nelielu pakeÅ”u zuduma procentu. Protokolam ir atbalsts atkārtotām pārraidēm un taimautiem, bet, ja mēs zaudēsim daudz, mēs iegÅ«sim gandrÄ«z TCP, kas nav izdevÄ«gi. Mēs nebraucam ar UDP pāri okeāniem.

Mums ir tÅ«kstoÅ”iem Ŕādu serveru, un shēma ir tāda pati: katrā fiziskajā serverÄ« ir instalēta dzinēju pakotne. Tie lielākoties ir ar vienu pavedienu, lai tie darbotos pēc iespējas ātrāk bez bloÄ·Ä“Å”anas, un tie ir sadalÄ«ti kā viena vÄ«tnes risinājumi. Tajā paŔā laikā mums nav nekā uzticamāka par Å”iem dzinējiem, un liela uzmanÄ«ba tiek pievērsta pastāvÄ«gai datu glabāŔanai.

Pastāvīga datu glabāŔana

Dzinēji raksta binlogus. Binlog ir fails, kura beigās tiek pievienots notikums par stāvokļa vai datu izmaiņām. Dažādos risinājumos to sauc atŔķirÄ«gi: binārs žurnāls, Wal, AOF, bet princips ir tāds pats.

Lai, restartējot, dzinējs daudzus gadus neizlasÄ«tu visu binlog, dzinēji raksta momentuzņēmumi ā€” paÅ”reizējais stāvoklis. Ja nepiecieÅ”ams, viņi vispirms izlasa no tā un pēc tam pabeidz lasÄ«t no binlog. Visi binārlogi tiek rakstÄ«ti vienā binārajā formātā ā€“ pēc TL shēmas, lai administratori varētu tos administrēt vienādi ar saviem rÄ«kiem. Nav tādas vajadzÄ«bas pēc momentuzņēmumiem. Ir vispārÄ«ga galvene, kas norāda, kura momentuzņēmums ir int, dzinēja maÄ£ija un kurÅ” korpuss nevienam nav svarÄ«gs. Tā ir problēma ar dzinēju, kas ierakstÄ«ja momentuzņēmumu.

Es ātri aprakstÄ«Å”u darbÄ«bas principu. Ir serveris, uz kura darbojas dzinējs. ViņŔ atver jaunu tukÅ”u binlogu rakstÄ«Å”anai un ieraksta notikumu, lai to mainÄ«tu.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Kādā brÄ«dÄ« viņŔ vai nu nolemj pats uzņemt momentuzņēmumu, vai arÄ« saņem signālu. Serveris izveido jaunu failu, ieraksta tajā visu tā stāvokli, faila beigām pievieno paÅ”reizējo binlog lielumu - nobÄ«di - un turpina rakstÄ«t tālāk. Jauns binlog netiek izveidots.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Kādā brīdī, kad dzinējs tiks restartēts, diskā būs gan binlog, gan momentuzņēmums. Dzinējs nolasa visu momentuzņēmumu un noteiktā brīdī paaugstina tā stāvokli.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Nolasa pozīciju, kas bija momentuzņēmuma izveides laikā, un binlog lielumu.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Nolasa binlog beigas, lai iegÅ«tu paÅ”reizējo stāvokli, un turpina rakstÄ«t turpmākos notikumus. Å Ä« ir vienkārÅ”a shēma; visi mÅ«su dzinēji darbojas saskaņā ar to.

Datu replikācija

Tā rezultātā datu replikācija mÅ«su pamatojoties uz apgalvojumu ā€” binlogā rakstām nevis kādas lapas izmaiņas, bet proti izmaiņu pieprasÄ«jumi. Ä»oti lÄ«dzÄ«gs tam, kas tiek piegādāts tÄ«klā, tikai nedaudz pārveidots.

To paÅ”u shēmu izmanto ne tikai replikācijai, bet arÄ« lai izveidotu dublējumus. Mums ir dzinējs ā€“ rakstÄ«Å”anas meistars, kas raksta uz binlog. Jebkurā citā vietā, kur administratori to ir iestatÄ«juÅ”i, Å”is binlog tiek kopēts, un viss ā€” mums ir rezerves kopija.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Ja nepiecieÅ”ams lasÄ«Å”anas replikaLai samazinātu CPU lasÄ«Å”anas slodzi, vienkārÅ”i tiek palaists lasÄ«Å”anas dzinējs, kas nolasa binlog beigas un izpilda Ŕīs komandas lokāli.

AtpalicÄ«ba Å”eit ir ļoti maza, un ir iespējams noskaidrot, cik daudz replika atpaliek no meistara.

Datu sadalīŔana RPC starpniekserverī

Kā darbojas sadalÄ«Å”ana? Kā starpniekserveris saprot, uz kuru klastera fragmentu nosÅ«tÄ«t? Kodā nav teikts: "SÅ«tiet par 15 lauskas!" - nē, to dara pilnvarnieks.

VienkārŔākā shēma ir firstint ā€” pieprasÄ«juma pirmais numurs.

get(photo100_500) => 100 % N.

Å is ir vienkārÅ”a memcached teksta protokola piemērs, taču, protams, vaicājumi var bÅ«t sarežģīti un strukturēti. Piemērā tiek ņemts pirmais skaitlis vaicājumā un atlikuÅ”ais skaitlis, dalÄ«ts ar klastera lielumu.

Tas ir noderÄ«gi, ja vēlamies iegÅ«t vienas entÄ«tijas datu atraÅ”anās vietu. Pieņemsim, ka 100 ir lietotāja vai grupas ID, un mēs vēlamies, lai sarežģītiem vaicājumiem visi vienas entÄ«tijas dati bÅ«tu vienā fragmentā.

Ja mums ir vienalga, kā pieprasÄ«jumi tiek izplatÄ«ti klasterÄ«, ir vēl viena iespēja ā€” sajaucot visu shardu.

hash(photo100_500) => 3539886280 % N

Mēs arī iegūstam hash, dalījuma atlikumu un shard numuru.

Abas Ŕīs iespējas darbojas tikai tad, ja esam gatavi tam, ka, palielinot klastera lielumu, mēs to sadalÄ«sim vai palielināsim vairākas reizes. Piemēram, mums bija 16 lauskas, mums nepietiek, mēs vēlamies vairāk - mēs varam droÅ”i iegÅ«t 32 bez dÄ«kstāves. Ja gribam palielināt, nevis reizināt, bÅ«s dÄ«kstāves, jo nevarēsim visu precÄ«zi sadalÄ«t bez zaudējumiem. Å Ä«s iespējas ir noderÄ«gas, bet ne vienmēr.

Ja mums ir jāpievieno vai jānoņem patvaļīgs skaits serveru, mēs to izmantojam Konsekventa jaukÅ”ana uz gredzena a la Ketama. Bet tajā paŔā laikā mēs pilnÄ«bā zaudējam datu atraÅ”anās vietu; mums ir jāapvieno pieprasÄ«jums ar klasteru, lai katrs elements atgrieztu savu mazo atbildi, un pēc tam jāapvieno atbildes ar starpniekserveri.

Ir Ä«paÅ”i specifiski pieprasÄ«jumi. Tas izskatās Ŕādi: RPC starpniekserveris saņem pieprasÄ«jumu, nosaka, uz kuru klasteru doties, un nosaka fragmentu. Pēc tam ir vai nu rakstÄ«Å”anas meistari, vai arÄ«, ja klasterim ir reprodukcijas atbalsts, tas pēc pieprasÄ«juma nosÅ«ta uz repliku. To visu dara starpniekserveris.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Baļķi

Mēs rakstām žurnālus vairākos veidos. Visredzamākais un vienkārŔākais ir rakstÄ«t žurnālus memcache.

ring-buffer: prefix.idx = line

Ir atslēgas prefikss - žurnāla nosaukums, lÄ«nija, un ir Ŕī žurnāla izmērs - rindu skaits. Mēs ņemam nejauÅ”u skaitli no 0 lÄ«dz rindu skaitam mÄ«nus 1. Memcache atslēga ir prefikss, kas savienots ar Å”o nejauÅ”o skaitli. Mēs saglabājam žurnāla lÄ«niju un paÅ”reizējo laiku lÄ«dz vērtÄ«bai.

Kad nepiecieÅ”ams nolasÄ«t žurnālus, veicam Multi Get visas atslēgas, sakārtotas pēc laika, un tādējādi iegÅ«stiet ražoÅ”anas žurnālu reāllaikā. Shēma tiek izmantota, ja ir nepiecieÅ”ams kaut ko atkļūdot ražoÅ”anā reāllaikā, neko nesalaužot, neapstājoties un neļaujot satiksmi uz citām maŔīnām, taču Å”is žurnāls neturpinās ilgi.

DroÅ”ai baļķu uzglabāŔanai mums ir dzinējs baļķu dzinējs. TieÅ”i tāpēc tas tika izveidots un tiek plaÅ”i izmantots daudzos klasteros. Lielākajā man zināmajā klasterÄ« ir 600 TB iesaiņotu baļķu.

Dzinējs ļoti vecs, ir klasteri, kuriem jau ir 6-7 gadi. Ar to ir problēmas, kuras mēs cenÅ”amies atrisināt, piemēram, mēs sākām aktÄ«vi izmantot ClickHouse žurnālu glabāŔanai.

Žurnālu vākŔana pakalpojumā ClickHouse

Šī diagramma parāda, kā mēs ieejam mūsu dzinējos.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Ir kods, kas lokāli, izmantojot RPC, tiek nosÅ«tÄ«ts uz RPC starpniekserveri, un tas saprot, kur doties uz dzinēju. Ja mēs vēlamies rakstÄ«t žurnālus ClickHouse, mums Å”ajā shēmā ir jāmaina divas daļas:

  • aizstāt kādu dzinēju ar ClickHouse;
  • aizstāt RPC starpniekserveri, kas nevar piekļūt ClickHouse, ar kādu risinājumu, kas var, un izmantojot RPC.

Dzinējs ir vienkārÅ”s ā€“ mēs to aizstājam ar serveri vai serveru kopu ar ClickHouse.

Un, lai dotos uz ClickHouse, mēs to darÄ«jām Kaķēnu māja. Ja mēs pārejam tieÅ”i no KittenHouse uz ClickHouse, tas netiks galā. Pat bez pieprasÄ«jumiem tas veidojas no ļoti daudzu iekārtu HTTP savienojumiem. Lai shēma darbotos, serverÄ« ar ClickHouse tiek paaugstināts vietējais apgrieztais starpniekserveris, kas ir uzrakstÄ«ts tā, lai tas varētu izturēt nepiecieÅ”amos savienojumu apjomus. Tas var arÄ« samērā uzticami buferēt datus sevÄ«.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Dažreiz mēs nevēlamies ieviest RPC shēmu nestandarta risinājumos, piemēram, nginx. Tāpēc KittenHouse ir iespēja saņemt žurnālus, izmantojot UDP.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Ja žurnālu sÅ«tÄ«tājs un saņēmējs strādā vienā maŔīnā, UDP paketes pazaudÄ“Å”anas iespējamÄ«ba vietējā resursdatorā ir diezgan zema. Kā kompromisu starp nepiecieÅ”amÄ«bu ieviest RPC treŔās puses risinājumā un uzticamÄ«bu mēs vienkārÅ”i izmantojam UDP sÅ«tÄ«Å”anu. Mēs atgriezÄ«simies pie Ŕīs shēmas vēlāk.

Uzraudzība

Mums ir divu veidu žurnāli: tie, ko administratori savākuÅ”i savos serveros, un tie, kurus izstrādātāji rakstÄ«juÅ”i no koda. Tie atbilst divu veidu rādÄ«tājiem: sistēma un produkts.

Sistēmas rādītāji

Tas darbojas visos mÅ«su serveros TÄ«kla dati, kas apkopo statistiku un nosÅ«ta to uz GrafÄ«ta ogleklis. Tāpēc ClickHouse tiek izmantota kā uzglabāŔanas sistēma, nevis, piemēram, Whisper. Ja nepiecieÅ”ams, varat lasÄ«t tieÅ”i no ClickHouse vai izmantot grafana metrikai, grafikiem un pārskatiem. Kā izstrādātājiem mums ir pietiekami daudz piekļuves Netdata un Grafana.

Produktu rādītāji

ĒrtÄ«bas labad mēs esam uzrakstÄ«juÅ”i daudzas lietas. Piemēram, ir parasto funkciju kopums, kas ļauj statistikā ierakstÄ«t Counts, UniqueCounts vērtÄ«bas, kuras tiek nosÅ«tÄ«tas kaut kur tālāk.

statlogsCountEvent   ( ā€˜stat_nameā€™,            $key1, $key2, ā€¦)
statlogsUniqueCount ( ā€˜stat_nameā€™, $uid,    $key1, $key2, ā€¦)
statlogsValuetEvent  ( ā€˜stat_nameā€™, $value, $key1, $key2, ā€¦)

$stats = statlogsStatData($params)

Pēc tam mēs varam izmantot kārtoÅ”anas un grupÄ“Å”anas filtrus un darÄ«t visu, ko vēlamies no statistikas ā€“ veidot grafikus, konfigurēt Watchdogs.

Mēs rakstām ļoti daudzi rādÄ«tāji notikumu skaits ir no 600 miljardiem lÄ«dz 1 triljonam dienā. Tomēr mēs vēlamies tos saglabāt vismaz pāris gaduslai izprastu metrikas tendences. To visu salikt kopā ir liela problēma, kuru mēs vēl neesam atrisinājuÅ”i. Es jums pastāstÄ«Å”u, kā tas ir strādājis pēdējos gadus.

Mums ir funkcijas, kas raksta Å”os rādÄ«tājus uz vietējo atmiņu keÅ”atmiņulai samazinātu ierakstu skaitu. Reizi Ä«sā laika periodā palaists lokāli statistikas dēmons apkopo visus ierakstus. Pēc tam dēmons apvieno metriku divos serveru slāņos baļķu savācēji, kas apkopo statistiku no vairākām mÅ«su maŔīnām, lai slānis aiz tiem nenomirst.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Ja nepiecieŔams, varam rakstīt tieŔi baļķiem-kolekcionāriem.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Bet rakstÄ«Å”ana no koda tieÅ”i uz kolekcionāriem, apejot stas-daemom, ir slikti mērogojams risinājums, jo tas palielina kolektora slodzi. Risinājums ir piemērots tikai tad, ja kāda iemesla dēļ mēs nevaram pacelt memcache stats-daemon uz maŔīnas, vai arÄ« tā avarēja un mēs devāmies tieÅ”i.

Pēc tam žurnālu savācēji apvieno statistiku meowDB - Ŕī ir mÅ«su datu bāze, kurā var saglabāt arÄ« metriku.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Pēc tam mēs varam veikt bināras ā€œgandrÄ«z SQLā€ atlases no koda.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Eksperiments

2018. gada vasarā mums bija iekŔējs hakatons, un radās ideja mēģināt aizstāt diagrammas sarkano daļu ar kaut ko tādu, kas varētu glabāt rādÄ«tājus pakalpojumā ClickHouse. Mums ir žurnāli vietnē ClickHouse ā€“ kāpēc gan neizmēģināt?

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Mums bija shēma, kas ierakstīja žurnālus caur KittenHouse.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Mēs izlēmām pievienojiet diagrammai vēl vienu ā€œ*Mājaā€., kas saņems tieÅ”i metriku tādā formātā, kādā mÅ«su kods tos ieraksta, izmantojot UDP. Tad Ŕī *Māja tos pārvērÅ” ieliktņos, piemēram, baļķos, kurus KittenHouse saprot. ViņŔ var lieliski piegādāt Å”os žurnālus ClickHouse, kam vajadzētu bÅ«t iespējai tos nolasÄ«t.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Shēma ar memcache, stats-daemon un logs-collectors datu bāzi tiek aizstāta ar Å”o.

Bieži uzdotie jautājumi par VKontakte arhitektūru un darbu

Shēma ar memcache, stats-daemon un logs-collectors datu bāzi tiek aizstāta ar Å”o.

  • Å eit ir nosÅ«tÄ«Å”ana no koda, kas ir rakstÄ«ts lokāli StatsHouse.
  • StatsHouse ieraksta UDP metriku, kas jau ir pārveidota par SQL ieliktņiem, KittenHouse partijās.
  • KittenHouse tos nosÅ«ta ClickHouse.
  • Ja mēs vēlamies tos lasÄ«t, mēs tos lasām, apejot StatsHouse - tieÅ”i no ClickHouse, izmantojot parasto SQL.

Vai tas joprojām ir eksperiments, bet mums patīk, kā tas izrādās. Ja mēs novērsīsim problēmas ar shēmu, tad, iespējams, pāriesim uz to pilnībā. Personīgi es tā ceru.

Shēma netaupa dzelzi. NepiecieÅ”ams mazāk serveru, nav nepiecieÅ”ami lokālie statistikas dēmoni un žurnālu savācēji, bet ClickHouse nepiecieÅ”ams lielāks serveris nekā paÅ”reizējā shēmā. NepiecieÅ”ams mazāk serveru, taču tiem jābÅ«t dārgākiem un jaudÄ«gākiem.

Izvietot

Vispirms apskatÄ«sim PHP izvietoÅ”anu. Mēs attÄ«stāmies iekŔā iet: izmantot GitLab Šø TeamCity izvietoÅ”anai. Izstrādes filiāles tiek apvienotas galvenajā filiālē, no galvenā testÄ“Å”anai tās tiek apvienotas inscenÄ“Å”anā, bet no inscenÄ“Å”anas - ražoÅ”anā.

Pirms izvietoÅ”anas tiek ņemta paÅ”reizējā ražoÅ”anas filiāle un iepriekŔējā, un tajos tiek ņemti vērā diff faili - izmaiņas: izveidotas, dzēstas, mainÄ«tas. Å Ä«s izmaiņas tiek ierakstÄ«tas Ä«paÅ”as kopÄ“Å”anas ātruma programmas binlogā, kas var ātri atkārtot izmaiņas visā mÅ«su serveru parkā. Å eit tiek izmantota nevis tieÅ”a kopÄ“Å”ana, bet gan tenku replikācija, kad viens serveris nosÅ«ta izmaiņas saviem tuvākajiem kaimiņiem, tās saviem kaimiņiem un tā tālāk. Tas ļauj atjaunināt kodu desmitos un sekunžu vienÄ«bās visā flotē. Kad izmaiņas sasniedz vietējo kopiju, tās lieto Å”os ielāpus tai vietējā failu sistēma. AtcelÅ”ana tiek veikta arÄ« saskaņā ar to paÅ”u shēmu.

Mēs arÄ« daudz izvietojam kPHP, un tam ir arÄ« sava attÄ«stÄ«ba iet saskaņā ar iepriekÅ” minēto diagrammu. KopÅ” Ŕī HTTP servera binārs, tad mēs nevaram radÄ«t diff - laidiena binārais sver simtiem MB. Tāpēc Å”eit ir vēl viena iespēja - versija ir rakstÄ«ta binlog copyfast. Ar katru bÅ«vniecÄ«bu tas palielinās, un atcelÅ”anas laikā tas arÄ« palielinās. Versija replicēts serveros. Vietējie copyfasti redz, ka binlog ir ienākusi jauna versija, un ar to paÅ”u tenku replikāciju viņi paņem sev jaunāko binārā versija, nenogurdinot mÅ«su galveno serveri, bet rÅ«pÄ«gi sadalot slodzi tÄ«klā. Kas seko gracioza atsākÅ”ana jaunajai versijai.

Mūsu dzinējiem, kas arī būtībā ir bināri, shēma ir ļoti līdzīga:

  • git master filiāle;
  • binārs iekŔā deb;
  • versija ir ierakstÄ«ta binlog copyfast;
  • replicēts serveros;
  • serveris izvelk jaunu .dep;
  • dpkg -i;
  • gracioza atsākÅ”ana uz jauno versiju.

AtŔķirÄ«ba ir tāda, ka mÅ«su binārais fails ir iesaiņots arhÄ«vos deb, un tos izsÅ«knējot dpkg -i tiek ievietoti sistēmā. Kāpēc kPHP tiek izvietots kā binārs, bet dzinēji tiek izvietoti kā dpkg? Tas notika tā. Tas darbojas - nepieskarieties tam.

Noderīgas saites:

Aleksejs Akulovičs ir viens no tiem, kas Programmas komitejas sastāvā palÄ«dz PHP Krievija 17. maijā kļūs par pēdējā laika lielāko notikumu PHP izstrādātājiem. Paskat, kāds mums forÅ”s dators, kas skaļruņi (divi no tiem izstrādā PHP kodolu!) - Ŕķiet kaut kas tāds, ko nevar palaist garām, ja raksti PHP.

Avots: www.habr.com

Pievieno komentāru