Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Historia ya uundaji wa VKontakte iko kwenye Wikipedia; iliambiwa na Pavel mwenyewe. Inaonekana kwamba kila mtu tayari anamjua. Kuhusu mambo ya ndani, usanifu na muundo wa tovuti kwenye HighLoad++ Pavel aliniambia mnamo 2010. Seva nyingi zimevuja tangu wakati huo, kwa hivyo tutasasisha habari: tutaigawanya, tutoe ndani, tuipime, na tutazame kifaa cha VK kutoka kwa mtazamo wa kiufundi.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Alexey Akulovich (AterCattus) msanidi programu katika timu ya VKontakte. Nakala ya ripoti hii ni jibu la pamoja kwa maswali yanayoulizwa mara kwa mara kuhusu utendakazi wa jukwaa, miundombinu, seva na mwingiliano kati yao, lakini sio juu ya maendeleo, ambayo ni. kuhusu chuma. Kando, kuhusu hifadhidata na kile ambacho VK ina badala yake, kuhusu kukusanya kumbukumbu na kufuatilia mradi mzima kwa ujumla. Maelezo chini ya kukata.



Kwa zaidi ya miaka minne nimekuwa nikishughulika na kila aina ya kazi zinazohusiana na backend.

  • Kupakia, kuhifadhi, kuchakata, kusambaza vyombo vya habari: video, utiririshaji wa moja kwa moja, sauti, picha, hati.
  • Miundombinu, jukwaa, ufuatiliaji wa wasanidi programu, kumbukumbu, kache za kikanda, CDN, itifaki ya RPC ya wamiliki.
  • Muunganisho na huduma za nje: arifa za kushinikiza, uchanganuzi wa kiungo cha nje, mipasho ya RSS.
  • Kusaidia wenzako na maswali anuwai, majibu ambayo yanahitaji kupiga mbizi kwenye nambari isiyojulikana.

Wakati huu, nilikuwa na mkono katika vipengele vingi vya tovuti. Ninataka kushiriki uzoefu huu.

Usanifu wa jumla

Kila kitu, kama kawaida, huanza na seva au kikundi cha seva zinazokubali maombi.

Seva ya mbele

Seva ya mbele inakubali maombi kupitia HTTPS, RTMP na WSS.

HTTPS - haya ni maombi ya matoleo kuu na ya simu ya wavuti ya tovuti: vk.com na m.vk.com, na wateja wengine rasmi na wasio rasmi wa API yetu: wateja wa simu, wajumbe. Tuna mapokezi RTMP-trafiki kwa matangazo ya moja kwa moja na seva tofauti za mbele na WSS- miunganisho ya API ya Utiririshaji.

Kwa HTTPS na WSS kwenye seva inafaa nginx. Kwa matangazo ya RTMP, hivi majuzi tulibadilisha kwa suluhisho letu kive, lakini ni zaidi ya upeo wa ripoti. Kwa uvumilivu wa makosa, seva hizi hutangaza anwani za kawaida za IP na kutenda kwa vikundi ili ikiwa kuna tatizo kwenye moja ya seva, maombi ya mtumiaji hayapotee. Kwa HTTPS na WSS, seva hizi hizi husimba trafiki kwa njia fiche ili kuchukua sehemu ya mzigo wa CPU yenyewe.

Hatutazungumza zaidi kuhusu WSS na RTMP, lakini tu kuhusu maombi ya kawaida ya HTTPS, ambayo kwa kawaida huhusishwa na mradi wa wavuti.

Backend

Nyuma ya mbele kuna kawaida seva za nyuma. Wanashughulikia maombi ambayo seva ya mbele inapokea kutoka kwa wateja.

Ni seva za kPHP, ambayo daemoni ya HTTP inafanya kazi, kwa sababu HTTPS tayari imesimbwa. kPHP ni seva inayoendelea mifano ya prefork: huanza mchakato mkuu, rundo la michakato ya mtoto, hupitisha soketi za kusikiliza kwao na wanashughulikia maombi yao. Katika kesi hii, michakato haijaanzishwa tena kati ya kila ombi kutoka kwa mtumiaji, lakini tu kuweka upya hali yao kwa hali ya asili ya thamani ya sifuri - ombi baada ya ombi, badala ya kuanzisha upya.

Usambazaji wa mzigo

Nyuma zetu zote sio dimbwi kubwa la mashine ambazo zinaweza kushughulikia ombi lolote. Sisi wao kugawanywa katika vikundi tofauti: ujumla, simu, api, video, staging... Tatizo kwenye kundi tofauti la mashine halitaathiri wengine wote. Katika kesi ya matatizo na video, mtumiaji ambaye anasikiliza muziki hata hata kujua kuhusu matatizo. Ambayo nyuma ya kutuma ombi inaamuliwa na nginx mbele kulingana na usanidi.

Mkusanyiko wa vipimo na kusawazisha upya

Ili kuelewa ni magari ngapi tunahitaji kuwa nayo katika kila kikundi, sisi usitegemee QPS. Njia za nyuma ni tofauti, zina maombi tofauti, kila ombi lina ugumu tofauti wa kuhesabu QPS. Ndiyo maana sisi tunafanya kazi na dhana ya mzigo kwenye seva kwa ujumla - kwenye CPU na perf.

Tuna maelfu ya seva kama hizo. Kila seva halisi huendesha kikundi cha kPHP ili kuchakata viini vyote (kwa sababu kPHP ina uzi mmoja).

Seva ya Maudhui

CS au Seva ya Maudhui ni hifadhi. CS ni seva ambayo huhifadhi faili na pia kuchakata faili zilizopakiwa na kila aina ya kazi za ulandanishi za usuli ambazo sehemu kuu ya mbele ya wavuti huikabidhi.

Tuna makumi ya maelfu ya seva halisi zinazohifadhi faili. Watumiaji wanapenda kupakia faili, na tunapenda kuzihifadhi na kuzishiriki. Baadhi ya seva hizi zimefungwa na seva maalum za pu/pp.

pu/uk

Ikiwa umefungua kichupo cha mtandao katika VK, uliona pu/pp.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Pu/pp ni nini? Ikiwa tutafunga seva moja baada ya nyingine, basi kuna chaguzi mbili za kupakia na kupakua faili kwenye seva iliyofungwa: moja kwa moja kupitia http://cs100500.userapi.com/path au kupitia seva ya kati - http://pu.vk.com/c100500/path.

Pu ni jina la kihistoria la upakiaji wa picha, na pp ni proksi ya picha. Hiyo ni, seva moja ni ya kupakia picha, na nyingine ni ya kupakia. Sasa sio picha tu zinazopakiwa, lakini jina limehifadhiwa.

Seva hizi kusitisha vipindi vya HTTPSkuondoa mzigo wa processor kutoka kwa hifadhi. Pia, kwa kuwa faili za mtumiaji zinachakatwa kwenye seva hizi, taarifa zisizo nyeti zaidi zilizohifadhiwa kwenye mashine hizi, ni bora zaidi. Kwa mfano, funguo za usimbaji fiche za HTTPS.

Kwa kuwa mashine zimefungwa na mashine zetu zingine, tunaweza kumudu kutozipa IPs za nje "nyeupe", na kutoa "kijivu". Kwa njia hii tulihifadhi kwenye dimbwi la IP na tumehakikishiwa kulinda mashine kutoka kwa ufikiaji wa nje - hakuna IP ya kuingia ndani yake.

Uthabiti juu ya IP zilizoshirikiwa. Kwa upande wa uvumilivu wa makosa, mpango huo hufanya kazi sawa - seva kadhaa za kimwili zina IP ya kawaida ya kimwili, na vifaa vilivyo mbele yao huchagua wapi kutuma ombi. Nitazungumza juu ya chaguzi zingine baadaye.

Suala la utata ni kwamba katika kesi hii mteja huweka miunganisho machache. Ikiwa kuna IP sawa kwa mashine kadhaa - na mwenyeji sawa: pu.vk.com au pp.vk.com, kivinjari cha mteja kina kikomo kwa idadi ya maombi ya wakati mmoja kwa mwenyeji mmoja. Lakini katika wakati wa HTTP/2 inayopatikana kila mahali, ninaamini kuwa hii haifai tena.

Ubaya ulio wazi wa mpango ni kwamba lazima pampu trafiki yote, ambayo huenda kwenye hifadhi, kupitia seva nyingine. Kwa kuwa tunasukuma trafiki kupitia mashine, bado hatuwezi kusukuma trafiki nzito, kwa mfano, video, kwa kutumia mpango sawa. Tunasambaza moja kwa moja - muunganisho tofauti wa moja kwa moja kwa hifadhi tofauti haswa kwa video. Tunasambaza maudhui mepesi kupitia proksi.

Si muda mrefu uliopita tulipata toleo lililoboreshwa la seva mbadala. Sasa nitakuambia jinsi wanavyotofautiana na wale wa kawaida na kwa nini hii ni muhimu.

Sun

Mnamo Septemba 2017, Oracle, ambayo hapo awali ilinunua Sun, ilifuta idadi kubwa ya wafanyikazi wa Sun. Tunaweza kusema kwamba kwa wakati huu kampuni ilikoma kuwepo. Wakati wa kuchagua jina la mfumo mpya, wasimamizi wetu waliamua kulipa kumbukumbu ya kampuni hii na wakauita mfumo mpya Sun. Kati yetu sisi tu tunamwita "jua".

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

pp alikuwa na shida kadhaa. IP moja kwa kila kikundi - cache isiyofaa. Seva kadhaa za kimwili hushiriki anwani ya kawaida ya IP, na hakuna njia ya kudhibiti ni seva ipi ambayo ombi litaenda. Kwa hiyo, ikiwa watumiaji tofauti wanakuja kwa faili moja, basi ikiwa kuna cache kwenye seva hizi, faili inaisha kwenye cache ya kila seva. Huu ni mpango usiofaa sana, lakini hakuna kitu kinachoweza kufanywa.

Kwa hiyo - hatuwezi kushiriki maudhui, kwa sababu hatuwezi kuchagua seva maalum kwa kikundi hiki - wana IP ya kawaida. Pia kwa baadhi ya sababu za ndani tunazo haikuwezekana kusakinisha seva kama hizo katika mikoa. Walisimama tu huko St.

Pamoja na jua, tulibadilisha mfumo wa uteuzi. Sasa tuna uelekezaji wowote: uelekezaji unaobadilika, utumaji wowote, jiangalie daemoni. Kila seva ina IP yake binafsi, lakini subnet ya kawaida. Kila kitu kimeundwa kwa njia ambayo ikiwa seva moja itashindwa, trafiki huenea kwenye seva zingine za kundi moja moja kwa moja. Sasa inawezekana kuchagua seva maalum, hakuna caching isiyohitajika, na uaminifu haukuathiriwa.

Msaada wa uzito. Sasa tunaweza kumudu kufunga mashine za nguvu tofauti kama inahitajika, na pia, ikiwa kuna shida za muda, badilisha uzani wa "jua" zinazofanya kazi ili kupunguza mzigo juu yao, ili "kupumzika" na kuanza kufanya kazi tena.

Kushiriki kwa kitambulisho cha maudhui. Jambo la kuchekesha kuhusu kugawanyika: kwa kawaida sisi huchanja maudhui ili watumiaji tofauti waende kwenye faili moja kupitia "jua" sawa ili wawe na kache ya kawaida.

Hivi majuzi tulizindua programu ya "Clover". Hili ni swali la mtandaoni katika matangazo ya moja kwa moja, ambapo mwenyeji anauliza maswali na watumiaji kujibu kwa wakati halisi, kuchagua chaguo. Programu ina gumzo ambapo watumiaji wanaweza kupiga gumzo. Inaweza kuunganisha kwa utangazaji kwa wakati mmoja zaidi ya watu elfu 100. Wote huandika ujumbe unaotumwa kwa washiriki wote, na avatar inakuja pamoja na ujumbe. Ikiwa watu elfu 100 wanakuja kwa avatar moja katika "jua" moja, basi wakati mwingine inaweza kuzunguka nyuma ya wingu.

Ili kustahimili maombi mengi ya faili sawa, ni kwa aina fulani ya maudhui ambapo tunawasha mpango wa kijinga ambao unasambaza faili kwenye "jua" zote zinazopatikana katika eneo.

Jua kutoka ndani

Badilisha seva mbadala kwenye nginx, kashe kwenye RAM au kwenye diski za Optane/NVMe za haraka. Mfano: http://sun4-2.userapi.com/c100500/path - kiungo kwa "jua", ambayo iko katika eneo la nne, kundi la pili la seva. Inafunga faili ya njia, ambayo iko kwenye seva 100500.

Cache

Tunaongeza node moja zaidi kwenye mpango wetu wa usanifu - mazingira ya caching.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Chini ni mchoro wa mpangilio akiba za kikanda, kuna takriban 20 kati yao. Hizi ndio mahali ambapo cache na "jua" ziko, ambazo zinaweza kuficha trafiki kupitia wao wenyewe.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Hii ni akiba ya maudhui ya multimedia; hakuna data ya mtumiaji iliyohifadhiwa hapa - muziki tu, video, picha.

Kuamua eneo la mtumiaji, sisi tunakusanya viambishi awali vya mtandao wa BGP vilivyotangazwa mikoani. Katika hali ya kurudi nyuma, pia tunapaswa kuchanganua hifadhidata ya geoip ikiwa hatukuweza kupata IP kwa viambishi awali. Tunaamua eneo kwa IP ya mtumiaji. Katika kanuni, tunaweza kuangalia kanda moja au zaidi ya mtumiaji - pointi hizo ambazo yeye ni karibu zaidi kijiografia.

Jinsi gani kazi?

Tunahesabu umaarufu wa faili kwa mkoa. Kuna idadi ya kache ya kikanda ambapo mtumiaji iko, na kitambulisho cha faili - tunachukua jozi hii na kuongeza ukadiriaji kwa kila upakuaji.

Wakati huo huo, pepo - huduma katika mikoa - mara kwa mara huja kwa API na kusema: "Mimi ni kashe kama hiyo, nipe orodha ya faili maarufu zaidi katika mkoa wangu ambazo bado hazijanihusu. ” API hutoa rundo la faili zilizopangwa kwa ukadiriaji, daemon inazipakua, kuzipeleka kwa mikoa na kuwasilisha faili kutoka hapo. Hii ndio tofauti ya kimsingi kati ya pu/pp na Sun kutoka kwa kache: wanapeana faili kupitia wenyewe mara moja, hata ikiwa faili hii haiko kwenye kashe, na kashe hupakua faili yenyewe, na kisha kuanza kuirudisha.

Katika kesi hii tunapata yaliyomo karibu na watumiaji na kueneza mzigo wa mtandao. Kwa mfano, tu kutoka kwenye cache ya Moscow tunasambaza zaidi ya 1 Tbit / s wakati wa masaa ya kilele.

Lakini kuna shida - seva za kache sio mpira. Kwa yaliyomo maarufu, wakati mwingine hakuna mtandao wa kutosha kwa seva tofauti. Seva zetu za kache ni 40-50 Gbit/s, lakini kuna maudhui ambayo huziba kabisa chaneli kama hiyo. Tunaelekea kutekeleza uhifadhi wa zaidi ya nakala moja ya faili maarufu katika eneo hili. Natumai tutaitekeleza ifikapo mwisho wa mwaka.

Tuliangalia usanifu wa jumla.

  • Seva za mbele zinazokubali maombi.
  • Hurudisha nyuma maombi hayo ya mchakato.
  • Hifadhi ambazo zimefungwa na aina mbili za proksi.
  • Akiba za kikanda.

Ni nini kinakosekana kwenye mchoro huu? Bila shaka, hifadhidata ambazo tunahifadhi data.

Hifadhidata au injini

Tunaziita sio hifadhidata, lakini injini - Injini, kwa sababu hatuna hifadhidata kwa maana inayokubalika kwa ujumla.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Hiki ni kipimo cha lazima. Hii ilitokea kwa sababu mnamo 2008-2009, wakati VK ilikuwa na ukuaji mkubwa wa umaarufu, mradi ulifanya kazi kabisa kwenye MySQL na Memcache na kulikuwa na shida. MySQL ilipenda kuharibu na kuharibu faili, baada ya hapo haitapona, na Memcache ilishuka hatua kwa hatua katika utendaji na ilibidi iwashwe upya.

Inabadilika kuwa mradi unaozidi kuwa maarufu ulikuwa na hifadhi ya kudumu, ambayo inaharibu data, na cache, ambayo hupunguza kasi. Katika hali kama hizi, ni ngumu kukuza mradi unaokua. Iliamuliwa kujaribu kuandika upya mambo muhimu ambayo mradi ulilenga kwenye baiskeli zetu wenyewe.

Suluhisho lilifanikiwa. Kulikuwa na fursa ya kufanya hivyo, pamoja na umuhimu mkubwa, kwa sababu njia nyingine za kuongeza hazikuwepo wakati huo. Hakukuwa na rundo la hifadhidata, NoSQL haikuwepo bado, kulikuwa na MySQL tu, Memcache, PostrgreSQL - na ndivyo hivyo.

Uendeshaji wa Universal. Maendeleo yaliongozwa na timu yetu ya wasanidi C na kila kitu kilifanyika kwa njia thabiti. Bila kujali injini, wote walikuwa na takriban fomati sawa ya faili iliyoandikwa kwa diski, vigezo sawa vya uzinduzi, ishara zilizochakatwa kwa njia ile ile, na walitenda takriban sawa katika kesi ya hali na shida. Pamoja na ukuaji wa injini, ni rahisi kwa wasimamizi kuendesha mfumo - hakuna zoo ambayo inahitaji kudumishwa, na wanapaswa kujifunza tena jinsi ya kuendesha kila hifadhidata mpya ya mtu wa tatu, ambayo ilifanya iwezekane haraka na. kwa urahisi kuongeza idadi yao.

Aina za injini

Timu iliandika injini chache. Hizi ni baadhi tu yake: rafiki, vidokezo, picha, ipdb, herufi, orodha, kumbukumbu, memcached, meowdb, habari, nostradamus, picha, orodha za kucheza, pmemcached, sandbox, tafuta, hifadhi, zinazopendwa, kazi, ...

Kwa kila kazi inayohitaji muundo maalum wa data au kuchakata maombi yasiyo ya kawaida, timu C huandika injini mpya. Kwa nini isiwe hivyo.

Tuna injini tofauti imechapwa, ambayo ni sawa na ya kawaida, lakini kwa kundi la vyema, na ambayo haipunguzi. Sio ClickHouse, lakini pia inafanya kazi. Inapatikana tofauti pmemcached - Je, kuendelea memcached, ambayo inaweza pia kuhifadhi data kwenye diski, zaidi ya hayo, kuliko inafaa kwenye RAM, ili usipoteze data wakati wa kuanzisha upya. Kuna injini mbalimbali za kazi za kibinafsi: foleni, orodha, seti - kila kitu ambacho mradi wetu unahitaji.

Vikundi

Kwa mtazamo wa kificho, hakuna haja ya kufikiria injini au hifadhidata kama michakato, huluki au matukio. Nambari hiyo inafanya kazi haswa na vikundi, na vikundi vya injini - aina moja kwa kila nguzo. Wacha tuseme kuna nguzo ya memcached - ni kikundi cha mashine tu.

Msimbo hauhitaji kujua eneo halisi, saizi au idadi ya seva hata kidogo. Anaenda kwenye nguzo kwa kutumia kitambulisho fulani.

Ili hii ifanye kazi, unahitaji kuongeza chombo kimoja zaidi ambacho kiko kati ya nambari na injini - wakala.

Wakala wa RPC

Wakala basi ya kuunganisha, ambayo karibu tovuti nzima inaendesha. Wakati huo huo tuna hakuna ugunduzi wa huduma - badala yake, kuna usanidi wa proksi hii, ambayo inajua eneo la nguzo zote na shards zote za nguzo hii. Hivi ndivyo wasimamizi hufanya.

Watayarishaji wa programu hawajali ni kiasi gani, wapi na ni gharama gani - wanaenda tu kwenye nguzo. Hii inaruhusu sisi mengi. Wakati wa kupokea ombi, wakala huelekeza ombi, akijua wapi - huamua hii yenyewe.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Katika kesi hii, wakala ni hatua ya ulinzi dhidi ya kushindwa kwa huduma. Ikiwa injini fulani itapungua au kuanguka, basi wakala anaelewa hili na anajibu ipasavyo kwa upande wa mteja. Hii inakuwezesha kuondoa muda - msimbo hausubiri injini kujibu, lakini inaelewa kuwa haifanyi kazi na inahitaji kuishi kwa namna fulani tofauti. Nambari lazima iwe tayari kwa ukweli kwamba hifadhidata haifanyi kazi kila wakati.

Utekelezaji mahususi

Wakati mwingine bado tunataka kuwa na aina fulani ya suluhu isiyo ya kawaida kama injini. Wakati huo huo, iliamuliwa kutotumia wakala wetu tayari wa rpc, iliyoundwa mahsusi kwa injini zetu, lakini kutengeneza wakala tofauti kwa kazi hiyo.

Kwa MySQL, ambayo bado tunayo hapa na pale, tunatumia db-proxy, na kwa ClickHouse - Nyumba ya Kitten.

Inafanya kazi kwa ujumla kama hii. Kuna seva fulani, inaendesha kPHP, Go, Python - kwa ujumla, msimbo wowote ambao unaweza kutumia itifaki yetu ya RPC. Msimbo hutumika ndani ya seva mbadala ya RPC - kila seva ambapo msimbo unapatikana huendesha proksi yake ya ndani. Baada ya ombi, wakala anaelewa pa kwenda.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Ikiwa injini moja inataka kwenda kwa mwingine, hata ikiwa ni jirani, inapitia wakala, kwa sababu jirani inaweza kuwa katika kituo kingine cha data. Injini haipaswi kutegemea kujua eneo la kitu chochote isipokuwa yenyewe - hii ndio suluhisho letu la kawaida. Lakini bila shaka kuna tofauti :)

Mfano wa mpango wa TL kulingana na ambayo injini zote hufanya kazi.

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;

Hii ni itifaki ya binary, analog ya karibu ambayo ni protobuf. Ratiba inaelezea sehemu za hiari, aina changamano - viendelezi vya scalars zilizojengwa ndani, na maswali. Kila kitu hufanya kazi kulingana na itifaki hii.

RPC juu ya TL juu ya TCP/UDP… UDP?

Tunayo itifaki ya RPC ya kutekeleza maombi ya injini inayofanya kazi juu ya mpango wa TL. Hii yote inafanya kazi kupitia muunganisho wa TCP/UDP. TCP inaeleweka, lakini kwa nini tunahitaji UDP mara nyingi?

UDP inasaidia epuka shida ya idadi kubwa ya miunganisho kati ya seva. Ikiwa kila seva ina proksi ya RPC na, kwa ujumla, inaweza kwenda kwa injini yoyote, basi kuna makumi ya maelfu ya miunganisho ya TCP kwa kila seva. Kuna mzigo, lakini hauna maana. Kwa upande wa UDP tatizo hili halipo.

Hakuna kusalimiana kwa mikono kwa TCP isiyohitajika. Hili ni tatizo la kawaida: wakati injini mpya au seva mpya inapozinduliwa, viunganisho vingi vya TCP vinaanzishwa mara moja. Kwa maombi madogo nyepesi, kwa mfano, malipo ya UDP, mawasiliano yote kati ya kanuni na injini ni pakiti mbili za UDP: mmoja huruka upande mmoja, wa pili kwa upande mwingine. Safari moja ya pande zote - na msimbo ulipokea jibu kutoka kwa injini bila kushikana mkono.

Ndiyo, yote yanafanya kazi tu na asilimia ndogo sana ya upotezaji wa pakiti. Itifaki ina usaidizi wa kutuma tena na kuisha kwa muda, lakini ikiwa tutapoteza mengi, tutapata karibu TCP, ambayo haina faida. Hatuendeshi UDP katika bahari.

Tuna maelfu ya seva kama hizo, na mpango huo ni sawa: pakiti ya injini imewekwa kwenye kila seva ya mwili. Mara nyingi huwa na uzi mmoja ili kukimbia haraka iwezekanavyo bila kuzuiwa, na hugawanywa kama suluhu zenye uzi mmoja. Wakati huo huo, hatuna kitu cha kuaminika zaidi kuliko injini hizi, na tahadhari nyingi hulipwa kwa uhifadhi wa data unaoendelea.

Uhifadhi wa data unaoendelea

Injini huandika logi. Binlog ni faili ambayo mwisho wake tukio la mabadiliko ya hali au data huongezwa. Katika suluhisho tofauti inaitwa tofauti: logi ya binary, WAL, AOF, lakini kanuni ni ile ile.

Ili kuzuia injini kusoma tena binlog nzima kwa miaka mingi wakati wa kuanza tena, injini zinaandika snapshots - hali ya sasa. Ikiwa ni lazima, wanasoma kutoka kwake kwanza, na kisha kumaliza kusoma kutoka kwa binlog. Bilogi zote zimeandikwa katika umbizo la binary - kulingana na mpango wa TL, ili wasimamizi waweze kuzisimamia kwa usawa kwa kutumia zana zao. Hakuna haja ya snapshots vile. Kuna kichwa cha jumla kinachoonyesha picha ya nani ni int, uchawi wa injini, na mwili gani sio muhimu kwa mtu yeyote. Hili ni tatizo la injini iliyorekodi muhtasari.

Nitaelezea haraka kanuni ya operesheni. Kuna seva ambayo injini inaendesha. Anafungua rekodi mpya tupu ya kuandika na anaandika tukio la mabadiliko yake.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Wakati fulani, anaamua kuchukua picha mwenyewe, au anapokea ishara. Seva huunda faili mpya, huandika hali yake yote ndani yake, huongeza saizi ya sasa ya binlog - kukabiliana - hadi mwisho wa faili, na kuendelea kuandika zaidi. binlog mpya haijaundwa.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Wakati fulani, wakati injini ilianza tena, kutakuwa na binlog na snapshot kwenye diski. Injini inasoma snapshot nzima na kuinua hali yake kwa hatua fulani.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Husoma nafasi iliyokuwa wakati taswira iliundwa na saizi ya logi.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Husoma mwisho wa binlog ili kupata hali ya sasa na kuendelea kuandika matukio zaidi. Huu ni mpango rahisi; injini zetu zote hufanya kazi kulingana nayo.

Kurudia data

Matokeo yake, data replication katika yetu kauli-msingi - tunaandika kwenye binlog sio mabadiliko yoyote ya ukurasa, lakini yaani mabadiliko ya maombi. Sawa sana na kile kinachokuja kwenye mtandao, kilichobadilishwa kidogo tu.

Mpango huo huo hutumiwa sio tu kwa kurudia, bali pia kuunda chelezo. Tunayo injini - bwana wa uandishi anayeandika kwa binlog. Katika sehemu nyingine yoyote ambapo wasimamizi waliiweka, binlog hii inakiliwa, na ndivyo ilivyo - tuna nakala rudufu.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Ikihitajika kusoma nakalaIli kupunguza mzigo wa kusoma wa CPU, injini ya kusoma inazinduliwa tu, ambayo inasoma mwisho wa binlog na kutekeleza amri hizi ndani ya nchi.

Lag hapa ni ndogo sana, na inawezekana kujua ni kiasi gani replica iko nyuma ya bwana.

Kushiriki data katika proksi ya RPC

Kugawanya hufanya kazi vipi? Je, seva mbadala inaelewa ni nguzo gani ya kutuma kwa? Nambari haisemi: "Tuma kwa shards 15!" - hapana, hii inafanywa na wakala.

Mpango rahisi zaidi ni wa kwanza - nambari ya kwanza katika ombi.

get(photo100_500) => 100 % N.

Huu ni mfano wa itifaki rahisi ya maandishi ya memcached, lakini, bila shaka, maswali yanaweza kuwa magumu na yenye muundo. Mfano huchukua nambari ya kwanza kwenye hoja na salio ikigawanywa na saizi ya nguzo.

Hii ni muhimu tunapotaka kuwa na eneo la data la huluki moja. Wacha tuseme 100 ni kitambulisho cha mtumiaji au kikundi, na tunataka data yote ya huluki moja iwe kwenye shard moja kwa maswali changamano.

Ikiwa hatujali jinsi maombi yanasambazwa kwenye nguzo, kuna chaguo jingine - kunyoosha sehemu nzima.

hash(photo100_500) => 3539886280 % N

Pia tunapata heshi, salio la mgawanyiko na nambari ya shard.

Chaguzi hizi zote mbili hufanya kazi tu ikiwa tumejitayarisha kwa ukweli kwamba tunapoongeza ukubwa wa nguzo, tutaigawanya au kuiongeza kwa mara nyingi. Kwa mfano, tulikuwa na shards 16, hatuna za kutosha, tunataka zaidi - tunaweza kupata 32 kwa usalama bila wakati wa kupumzika. Ikiwa tunataka kuongeza sio nyingi, kutakuwa na wakati wa chini, kwa sababu hatutaweza kugawanya kila kitu kwa usahihi bila hasara. Chaguzi hizi ni muhimu, lakini si mara zote.

Ikiwa tunahitaji kuongeza au kuondoa idadi kiholela ya seva, tunatumia Hashing thabiti kwenye pete a la Ketama. Lakini wakati huo huo, tunapoteza kabisa eneo la data; inabidi tuunganishe ombi kwa nguzo ili kila kipande kirudishe majibu yake madogo, na kisha kuunganisha majibu kwa proksi.

Kuna maombi mahususi zaidi. Inaonekana hivi: Wakala wa RPC hupokea ombi, huamua ni nguzo gani ya kwenda na huamua shard. Halafu kuna mabwana wa uandishi, au, ikiwa nguzo ina usaidizi wa replica, hutuma kwa nakala kwa mahitaji. Wakala hufanya haya yote.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Kumbukumbu

Tunaandika kumbukumbu kwa njia kadhaa. Ya wazi zaidi na rahisi ni andika kumbukumbu kwa memcache.

ring-buffer: prefix.idx = line

Kuna kiambishi awali muhimu - jina la logi, mstari, na kuna ukubwa wa logi hii - idadi ya mistari. Tunachukua nambari nasibu kutoka 0 hadi nambari ya mistari toa 1. Ufunguo katika memcache ni kiambishi awali kilichoambatana na nambari hii nasibu. Tunahifadhi mstari wa logi na wakati wa sasa kwa thamani.

Wakati ni muhimu kusoma magogo, tunafanya Pata Multi funguo zote, zimepangwa kwa wakati, na hivyo kupata logi ya uzalishaji kwa wakati halisi. Mpango huo hutumiwa wakati unahitaji kurekebisha kitu katika uzalishaji kwa wakati halisi, bila kuvunja chochote, bila kuacha au kuruhusu trafiki kwa mashine nyingine, lakini logi hii haidumu kwa muda mrefu.

Kwa uhifadhi wa kuaminika wa magogo tuna injini magogo-injini. Hii ndiyo sababu iliundwa, na inatumiwa sana katika idadi kubwa ya makundi. Nguzo kubwa zaidi ninayojua ya maduka ya 600 TB ya magogo yaliyopakiwa.

Injini ni ya zamani sana, kuna makundi ambayo tayari yana umri wa miaka 6-7. Kuna matatizo nayo ambayo tunajaribu kutatua, kwa mfano, tulianza kutumia kikamilifu ClickHouse kuhifadhi kumbukumbu.

Kukusanya kumbukumbu katika ClickHouse

Mchoro huu unaonyesha jinsi tunavyotembea kwenye injini zetu.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Kuna msimbo ambao huenda ndani ya nchi kupitia RPC hadi kwa wakala wa RPC, na inaelewa mahali pa kwenda kwa injini. Ikiwa tunataka kuandika kumbukumbu katika ClickHouse, tunahitaji kubadilisha sehemu mbili katika mpango huu:

  • badilisha injini na ClickHouse;
  • badilisha proksi ya RPC, ambayo haiwezi kufikia ClickHouse, na suluhisho ambalo linaweza, na kupitia RPC.

Injini ni rahisi - tunaibadilisha na seva au kikundi cha seva na ClickHouse.

Na kwenda kwa ClickHouse, tulifanya Nyumba ya Kitten. Ikiwa tutaenda moja kwa moja kutoka kwa KittenHouse hadi ClickHouse, haitaweza kukabiliana. Hata bila maombi, inaongeza kutoka kwa miunganisho ya HTTP ya idadi kubwa ya mashine. Ili mpango ufanye kazi, kwenye seva iliyo na ClickHouse seva mbadala ya ndani imeinuliwa, ambayo imeandikwa kwa namna ambayo inaweza kuhimili kiasi kinachohitajika cha viunganisho. Inaweza pia kuakibisha data ndani yake kwa uhakika kiasi.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Wakati mwingine hatutaki kutekeleza mpango wa RPC katika suluhu zisizo za kawaida, kwa mfano, katika nginx. Kwa hiyo, KittenHouse ina uwezo wa kupokea magogo kupitia UDP.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Ikiwa mtumaji na mpokeaji wa kumbukumbu hufanya kazi kwenye mashine moja, basi uwezekano wa kupoteza pakiti ya UDP ndani ya mwenyeji wa ndani ni mdogo sana. Kama maelewano kati ya hitaji la kutekeleza RPC katika suluhisho la watu wengine na kutegemewa, tunatumia tu UDP kutuma. Tutarudi kwa mpango huu baadaye.

Ufuatiliaji

Tuna aina mbili za kumbukumbu: zile zilizokusanywa na wasimamizi kwenye seva zao na zile zilizoandikwa na wasanidi programu kutoka kwa nambari. Zinalingana na aina mbili za metriki: mfumo na bidhaa.

Vipimo vya mfumo

Inafanya kazi kwenye seva zetu zote mtandao, ambayo hukusanya takwimu na kuzituma kwa Kaboni ya Grafiti. Kwa hivyo, ClickHouse hutumiwa kama mfumo wa kuhifadhi, na sio Whisper, kwa mfano. Ikihitajika, unaweza kusoma moja kwa moja kutoka kwa ClickHouse, au utumie grafana kwa vipimo, grafu na ripoti. Kama wasanidi programu, tuna ufikiaji wa kutosha kwa Netdata na Grafana.

Vipimo vya bidhaa

Kwa urahisi, tumeandika mambo mengi. Kwa mfano, kuna seti ya kazi za kawaida zinazokuwezesha kuandika Hesabu, maadili ya UniqueCounts kwenye takwimu, ambayo hutumwa mahali pengine zaidi.

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

$stats = statlogsStatData($params)

Baadaye, tunaweza kutumia vichungi vya kupanga na kupanga na kufanya kila kitu tunachotaka kutoka kwa takwimu - kuunda grafu, kusanidi Walinzi.

Tunaandika sana vipimo vingi idadi ya matukio ni kutoka bilioni 600 hadi trilioni 1 kwa siku. Hata hivyo, tunataka kuwaweka angalau miaka michachekuelewa mienendo katika vipimo. Kuweka yote pamoja ni tatizo kubwa ambalo bado hatujatatua. Nitakuambia jinsi imekuwa ikifanya kazi kwa miaka michache iliyopita.

Tuna chaguo za kukokotoa zinazoandika vipimo hivi kwa memcache ya ndaniili kupunguza idadi ya maingizo. Mara moja kwa muda mfupi ilizinduliwa ndani ya nchi takwimu-daemon inakusanya kumbukumbu zote. Kisha, pepo huunganisha vipimo katika safu mbili za seva magogo-watoza, ambayo hukusanya takwimu kutoka kwa kundi la mashine zetu ili safu nyuma yao isife.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Ikiwa ni lazima, tunaweza kuandika moja kwa moja kwa watoza kumbukumbu.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Lakini kuandika kutoka kwa nambari moja kwa moja hadi kwa watoza, kupita stas-daemom, ni suluhisho duni kwa sababu huongeza mzigo kwenye mtoza. Suluhisho linafaa tu ikiwa kwa sababu fulani hatuwezi kuinua memcache stats-daemon kwenye mashine, au ilianguka na tukaenda moja kwa moja.

Ifuatayo, wakusanyaji kumbukumbu huunganisha takwimu meoDB - hii ni hifadhidata yetu, ambayo inaweza pia kuhifadhi metriki.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Kisha tunaweza kufanya chaguzi za "karibu na SQL" kutoka kwa msimbo.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Jaribio

Katika majira ya joto ya 2018, tulikuwa na hackathon ya ndani, na wazo lilikuja kujaribu kuchukua nafasi ya sehemu nyekundu ya mchoro na kitu ambacho kinaweza kuhifadhi metrics katika ClickHouse. Tunayo kumbukumbu kwenye ClickHouse - kwa nini usijaribu?

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Tulikuwa na mpango ambao uliandika kumbukumbu kupitia KittenHouse.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Tuliamua ongeza "*Nyumba" nyingine kwenye mchoro, ambayo itapokea vipimo haswa katika umbizo jinsi msimbo wetu unavyoziandika kupitia UDP. Kisha *Nyumba hii inazigeuza kuwa viingilizi, kama magogo, ambayo KittenHouse inaelewa. Anaweza kutoa kumbukumbu hizi kikamilifu kwa ClickHouse, ambayo inapaswa kuwa na uwezo wa kuzisoma.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Mpango ulio na hifadhidata ya memcache, stats-daemon na kumbukumbu-wakusanyaji hubadilishwa na hii.

Maswali yanayoulizwa mara kwa mara juu ya usanifu na kazi ya VKontakte

Mpango ulio na hifadhidata ya memcache, stats-daemon na kumbukumbu-wakusanyaji hubadilishwa na hii.

  • Kuna utumaji kutoka kwa nambari hapa, ambayo imeandikwa ndani ya StatsHouse.
  • StatsHouse huandika vipimo vya UDP, ambavyo tayari vimebadilishwa kuwa viingilio vya SQL, hadi KittenHouse katika makundi.
  • KittenHouse inazituma kwa ClickHouse.
  • Ikiwa tunataka kuzisoma, basi tutazisoma kwa kupita StatsHouse - moja kwa moja kutoka kwa ClickHouse kwa kutumia SQL ya kawaida.

Je! Bado majaribio, lakini tunapenda jinsi inavyogeuka. Ikiwa tutarekebisha shida na mpango huo, basi labda tutaibadilisha kabisa. Binafsi, natumai hivyo.

Mpango haihifadhi chuma. Seva chache zinahitajika, takwimu-daemons za ndani na wakusanyaji wa kumbukumbu hazihitajiki, lakini ClickHouse inahitaji seva kubwa kuliko zile zilizo kwenye mpango wa sasa. Seva chache zinahitajika, lakini lazima ziwe ghali zaidi na zenye nguvu zaidi.

Weka

Kwanza, hebu tuangalie kupelekwa kwa PHP. Tunaendeleza katika git: kutumia GitLab ΠΈ TeamCity kwa ajili ya kupelekwa. Matawi ya maendeleo yanaunganishwa katika tawi kuu, kutoka kwa bwana kwa ajili ya majaribio yanaunganishwa kwenye hatua, na kutoka kwa hatua hadi uzalishaji.

Kabla ya kupelekwa, tawi la sasa la uzalishaji na la awali linachukuliwa, na faili tofauti zinazingatiwa ndani yao - mabadiliko: kuundwa, kufutwa, kubadilishwa. Mabadiliko haya yanarekodiwa katika logi ya injini maalum ya kunakili, ambayo inaweza kuiga mabadiliko kwa haraka kwa kundi zima la seva zetu. Kinachotumika hapa sio kunakili moja kwa moja, lakini kuiga uvumi, seva moja inapotuma mabadiliko kwa majirani zake wa karibu, wale kwa majirani zao, na kadhalika. Hii hukuruhusu kusasisha msimbo katika makumi na vitengo vya sekunde kwenye kundi zima. Mabadiliko yanapofikia nakala ya ndani, inatumia viraka hivi kwake mfumo wa faili wa ndani. Rollback pia hufanywa kulingana na mpango huo huo.

Pia tunasambaza kPHP sana na pia ina maendeleo yake yenyewe git kulingana na mchoro hapo juu. Tangu hii Seva ya HTTP binary, basi hatuwezi kutoa diff - toleo la binary lina uzito wa mamia ya MB. Kwa hiyo, kuna chaguo jingine hapa - toleo limeandikwa kwa binlog copyfast. Kwa kila kujenga huongezeka, na wakati wa kurudi nyuma pia huongezeka. Toleo kuigwa kwa seva. Walio na nakala za ndani wanaona kuwa toleo jipya limeingia kwenye logi, na kwa urudiaji ule ule wa udaku wanajichukulia toleo jipya zaidi la mfumo wa jozi, bila kuchosha seva yetu kuu, lakini kwa uangalifu kueneza mzigo kwenye mtandao. Nini kinafuata uzinduzi wa neema kwa toleo jipya.

Kwa injini zetu, ambazo pia kimsingi ni binaries, mpango huo ni sawa sana:

  • git master tawi;
  • binary katika .deb;
  • toleo limeandikwa kwa binlog copyfast;
  • kuigwa kwa seva;
  • seva huchota .dep mpya;
  • dpkg -i;
  • neema kuzindua upya kwa toleo jipya.

Tofauti ni kwamba binary yetu imewekwa kwenye kumbukumbu .deb, na wakati wa kusukuma nje wao dpkg -i zimewekwa kwenye mfumo. Kwa nini kPHP inatumika kama mfumo wa jozi, na injini zimewekwa kama dpkg? Ilifanyika hivyo. Inafanya kazi - usiiguse.

Viungo muhimu:

Alexey Akulovich ni mmoja wa wale ambao, kama sehemu ya Kamati ya Programu, husaidia PHP Urusi mnamo Mei 17 litakuwa tukio kubwa zaidi kwa wasanidi wa PHP katika siku za hivi majuzi. Angalia nini PC baridi tuna, nini wasemaji (wawili kati yao wanatengeneza msingi wa PHP!) - inaonekana kama kitu ambacho huwezi kukosa ukiandika PHP.

Chanzo: mapenzi.com

Kuongeza maoni