Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu af

Notendur okkar skrifa skilaboð sín á milli án þess að vita um þreytu.
Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu af
Það er frekar mikið. Ef þú ætlar að lesa öll skilaboð allra notenda myndi það taka meira en 150 þúsund ár. Að því gefnu að þú sért frekar háþróaður lesandi og eyðir ekki meira en sekúndu í hvert skeyti.

Með slíku magni gagna er mikilvægt að rökfræðin fyrir geymslu og aðgang að þeim sé byggð upp sem best. Annars, á einni ekki svo dásamlegu augnabliki, getur komið í ljós að allt fer bráðum úrskeiðis.

Fyrir okkur kom þessi stund fyrir einu og hálfu ári síðan. Hvernig við komumst að þessu og hvað gerðist á endanum - við segjum ykkur í röð.

Bakgrunnur

Í fyrstu útfærslunni virkuðu VKontakte skilaboð á blöndu af PHP bakenda og MySQL. Þetta er algjörlega eðlileg lausn fyrir lítinn nemendavef. Hins vegar stækkaði þessi síða stjórnlaust og fór að krefjast hagræðingar á gagnaskipulagi fyrir sig.

Í lok árs 2009 var fyrsta textavélageymslan skrifuð og árið 2010 voru skilaboð flutt á hana.

Í textavélinni voru skilaboð geymd í listum - eins konar „pósthólf“. Hver slíkur listi er ákvarðaður af uid - notandanum sem á öll þessi skilaboð. Skilaboð hafa sett af eiginleikum: viðmælandaauðkenni, texta, viðhengi og svo framvegis. Skilaboðaauðkennið í „boxinu“ er local_id, það breytist aldrei og er úthlutað í röð fyrir ný skilaboð. „Kassarnir“ eru óháðir og eru ekki samstilltir hver við annan inni í vélinni; samskipti á milli þeirra eiga sér stað á PHP stigi. Þú getur skoðað gagnauppbyggingu og getu textavélarinnar innan frá hér.
Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu af
Þetta var alveg nóg fyrir bréfaskipti milli tveggja notenda. Giska á hvað gerðist næst?

Í maí 2011 kynnti VKontakte samtöl við nokkra þátttakendur - fjölspjall. Til að vinna með þeim bjuggum við til tvo nýja klasa - meðlimaspjall og spjallmeðlimi. Sá fyrsti geymir gögn um spjall notenda, sá seinni geymir gögn um notendur með spjalli. Auk listanna sjálfra felur þetta til dæmis í sér boðsnotandann og tímann sem þeim var bætt við spjallið.

„PHP, sendum skilaboð á spjallið,“ segir notandinn.
„Komdu svo, {notendanafn},“ segir PHP.
Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu af
Það eru ókostir við þetta kerfi. Samstilling er enn á ábyrgð PHP. Stór spjall og notendur sem senda þeim skilaboð samtímis eru hættuleg saga. Þar sem textavélin fer eftir uid, gætu spjallþátttakendur fengið sömu skilaboðin á mismunandi tímum. Maður gæti lifað við þetta ef framfarir stæðu í stað. En það mun ekki gerast.

Í lok árs 2015 settum við á markað samfélagsskilaboð og í byrjun árs 2016 settum við af stað API fyrir þau. Með tilkomu stórra spjallbotna í samfélögum var hægt að gleyma jöfnum álagsdreifingu.

Góður vélmenni býr til nokkrar milljónir skilaboða á dag - jafnvel orðheppnustu notendur geta ekki státað af þessu. Þetta þýðir að sum tilvik textavéla, sem slíkir vélmenni bjuggu á, fóru að þjást til hins ýtrasta.

Skilaboðavélar árið 2016 eru 100 tilvik spjallmeðlima og meðlimaspjalla og 8000 textavélar. Þeir voru hýstir á þúsund netþjónum, hver með 64 GB af minni. Sem fyrsta neyðarráðstöfun jók við minni um 32 GB til viðbótar. Við áætluðum spárnar. Án róttækra breytinga myndi þetta duga í um það bil eitt ár í viðbót. Þú þarft annað hvort að ná í vélbúnað eða fínstilla gagnagrunnana sjálfa.

Vegna eðlis arkitektúrsins er aðeins skynsamlegt að auka vélbúnað í margfeldi. Það er að minnsta kosti tvöföldun bíla - augljóslega er þetta frekar dýr leið. Við munum hagræða.

Ný hugmynd

Kjarninn í nýju nálguninni er spjall. Spjall hefur lista yfir skilaboð sem tengjast því. Notandinn hefur lista yfir spjall.

Áskilið lágmark eru tveir nýir gagnagrunnar:

  • spjallvél. Þetta er geymsla spjallvigra. Hvert spjall hefur vektor af skilaboðum sem tengjast því. Hvert skeyti hefur texta og einstakt skilaboðaauðkenni inni í spjallinu - chat_local_id.
  • notendavél. Þetta er geymsla notendavigra - tenglar á notendur. Hver notandi hefur vektor af peer_id (viðmælendur - aðrir notendur, fjölspjall eða samfélög) og vektor af skilaboðum. Hvert peer_id hefur vektor af skilaboðum sem tengjast því. Hvert skeyti hefur chat_local_id og einstakt skilaboðaauðkenni fyrir þann notanda - user_local_id.

Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu af
Nýir klasar hafa samskipti sín á milli með TCP - þetta tryggir að röð beiðna breytist ekki. Beiðnirnar sjálfar og staðfestingar á þeim eru skráðar á harða diskinn - þannig að við getum endurheimt stöðu biðröðarinnar hvenær sem er eftir bilun eða endurræsingu vélarinnar. Þar sem notendavélin og spjallvélin eru 4 þúsund shards hvort, mun beiðniröðin milli þyrpinganna dreifast jafnt (en í raun er engin - og það virkar mjög hratt).

Vinna með disk í gagnagrunnum okkar byggist í flestum tilfellum á blöndu af tvíundarskrá breytinga (binlog), kyrrstæðum skyndimyndum og hluta mynd í minni. Breytingar yfir daginn eru skrifaðar á binlog og mynd af núverandi ástandi er reglulega búin til. Skyndimynd er safn gagnauppbygginga sem eru fínstillt í okkar tilgangi. Það samanstendur af haus (metaindex myndarinnar) og safni metafiles. Hausinn er varanlega geymdur í vinnsluminni og gefur til kynna hvar á að leita að gögnum úr skyndimyndinni. Hver lýsiskrá inniheldur gögn sem líklegt er að sé þörf á nálægum tíma - til dæmis tengd einum notanda. Þegar spurt er í gagnagrunninn með því að nota skyndimyndahausinn er tilskilin metafile lesin og síðan er tekið tillit til breytinga á binlognum sem áttu sér stað eftir að skyndimyndin var búin til. Þú getur lesið meira um kosti þessarar aðferðar hér.

Á sama tíma breytast gögnin á harða disknum sjálfum aðeins einu sinni á dag - seint á kvöldin í Moskvu, þegar álagið er í lágmarki. Þökk sé þessu (vitandi að uppbygging disksins er stöðug allan daginn) getum við leyft okkur að skipta út vektorum fyrir fylki af föstri stærð - og vegna þessa aukið minni.

Sending skilaboða í nýja kerfinu lítur svona út:

  1. PHP stuðningurinn hefur samband við notendavélina með beiðni um að senda skilaboð.
  2. notendavél sendir beiðnina til viðkomandi spjallvélatilviks, sem skilar sér í notandavél chat_local_id - einstakt auðkenni nýs skilaboða í þessu spjalli. Chat_engine sendir síðan skilaboðin til allra viðtakenda í spjallinu.
  3. user-engine fær chat_local_id frá chat-engine og skilar user_local_id í PHP - einstakt skilaboðaauðkenni fyrir þennan notanda. Þetta auðkenni er síðan notað til dæmis til að vinna með skilaboð í gegnum API.

Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu af
En auk þess að senda skilaboð í raun og veru þarftu að útfæra nokkra mikilvægari hluti:

  • Undirlistar eru til dæmis nýjustu skilaboðin sem þú sérð þegar þú opnar samtalalistann. Ólesin skilaboð, skilaboð með merkjum („Mikilvægt“, „Spam“ o.s.frv.).
  • Þjappa skilaboðum í spjallvél
  • Skilaboð í skyndiminni í notendavél
  • Leita (í gegnum alla glugga og innan ákveðins).
  • Rauntíma uppfærsla (Longpolling).
  • Vistar sögu til að innleiða skyndiminni á farsímabiðlara.

Allir undirlistar eru að breytast hratt. Til að vinna með þeim notum við Sprey tré. Þetta val skýrist af því að efst í trénu geymum við stundum heilan hluta af skilaboðum úr skyndimynd - til dæmis, eftir endurskráningu á nóttunni, samanstendur tréð af einum toppi sem inniheldur öll skilaboð undirlistans. Splay tréð gerir það auðvelt að setja inn í miðjan slíkan hornpunkt án þess að þurfa að hugsa um jafnvægi. Að auki geymir Splay ekki óþarfa gögn, sem sparar okkur minni.

Skilaboð fela í sér mikið magn upplýsinga, aðallega texta, sem er gagnlegt til að geta þjappað saman. Það er mikilvægt að við getum tekið nákvæmlega úr geymslu jafnvel einu einstökum skilaboðum. Notað til að þjappa skilaboðum Huffman reiknirit með okkar eigin heuristics - til dæmis vitum við að í skilaboðum skiptast orð á "ekki orð" - bil, greinarmerki - og við munum líka eftir sumum eiginleikum þess að nota tákn fyrir rússneska tungumálið.

Þar sem það eru miklu færri notendur en spjall, til að vista diskabeiðnir af handahófi í spjallvél, vistum við skilaboð í notendavél.

Skilaboðaleit er útfærð sem ská fyrirspurn frá notandavél til allra spjallvélatilvika sem innihalda spjall þessa notanda. Niðurstöðurnar eru sameinaðar í notendavélinni sjálfri.

Jæja, allar upplýsingar hafa verið teknar með í reikninginn, það eina sem er eftir er að skipta yfir í nýtt kerfi - og helst án þess að notendur taki eftir því.

Gagnaflutningur

Þannig að við erum með textavél sem geymir skilaboð eftir notendum og tvo hópa spjallmeðlima og meðlimaspjall sem geyma gögn um fjölspjallrásir og notendur í þeim. Hvernig á að fara úr þessu yfir í nýju notendavélina og spjallvélina?

meðlimaspjall í gamla kerfinu var fyrst og fremst notað til hagræðingar. Við fluttum fljótt nauðsynleg gögn frá því til spjallmeðlima og tók þá ekki lengur þátt í flutningsferlinu.

Biðröð fyrir spjallmeðlimi. Það inniheldur 100 tilvik, en spjallvélin hefur 4 þúsund. Til að flytja gögnin þarftu að koma þeim í samræmi - til þess var spjallmeðlimum skipt í sömu 4 þúsund eintökin og síðan var lesið á spjallmeðlimabókinni virkt í spjallvélinni.
Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu af
Nú veit spjallvélin um fjölspjall frá spjallmeðlimum, en veit ekkert um samtöl við tvo viðmælendur ennþá. Slíkar samræður eru staðsettar í textavélinni með vísan til notenda. Hér tókum við gögnin „á hausinn“: hvert spjallvélatilvik spurði öll textavélatilvik hvort þau hefðu samræðurnar sem það þurfti.

Frábært - spjallvélin veit hvaða fjölspjallspjall er til og veit hvaða samræður það eru.
Þú þarft að sameina skilaboð í fjölspjallspjalli þannig að þú endar með lista yfir skilaboð í hverju spjalli. Í fyrsta lagi sækir spjallvél öll notendaskilaboð frá þessu spjalli úr textavélinni. Í sumum tilfellum er töluvert mikið af þeim (allt að hundruðum milljóna), en með mjög sjaldgæfum undantekningum passar spjallið algjörlega í vinnsluminni. Við höfum óraðað skilaboð, hvert í nokkrum eintökum - þegar allt kemur til alls eru þau öll dregin úr mismunandi textavélatilvikum sem samsvara notendum. Markmiðið er að flokka skilaboð og losna við afrit sem taka óþarfa pláss.

Hvert skeyti hefur tímastimpil sem inniheldur tímann sem þau voru send og textaskilaboð. Við notum tíma til að flokka - við setjum ábendingar á elstu skilaboð þátttakenda í fjölspjalli og berum saman kjötkássa úr texta fyrirhugaðra eintaka og förum í átt að auknum tímastimpli. Það er rökrétt að afritin verði með sama kjötkássa og tímastimpil, en í reynd er það ekki alltaf raunin. Eins og þú manst var samstilling í gamla kerfinu framkvæmd af PHP - og í einstaka tilfellum var tíminn til að senda sömu skilaboðin mismunandi eftir mismunandi notendum. Í þessum tilvikum leyfðum við okkur að breyta tímastimplinum - venjulega innan sekúndu. Annað vandamálið er mismunandi röð skilaboða fyrir mismunandi viðtakendur. Í slíkum tilvikum leyfðum við að búa til auka eintak, með mismunandi pöntunarvalkostum fyrir mismunandi notendur.

Eftir þetta eru gögn um skilaboð í fjölspjalli send til notendavélarinnar. Og hér kemur óþægilegur eiginleiki innfluttra skilaboða. Í venjulegri notkun eru skilaboð sem koma til vélarinnar raðað í hækkandi röð eftir user_local_id. Skilaboð sem flutt voru inn úr gömlu vélinni í notendavélina misstu þessa gagnlegu eiginleika. Á sama tíma, til að auðvelda prófunina, þarftu að geta nálgast þau fljótt, leitað að einhverju í þeim og bætt við nýjum.

Við notum sérstaka gagnauppbyggingu til að geyma innflutt skilaboð.

Það táknar vektor af stærð Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu afhvar eru allir Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu af - eru mismunandi og raðað í lækkandi röð, með sérstakri röð frumefna. Í hverjum hluta með vísitölum Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu af þættir eru flokkaðir. Það tekur tíma að leita að frumefni í slíkri uppbyggingu Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu af gegnum Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu af tvíundarleit. Viðbót þáttar er afskrifuð yfir Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu af.

Svo komumst við að því hvernig á að flytja gögn frá gömlum vélum yfir í nýjar. En þetta ferli tekur nokkra daga - og það er ólíklegt að á þessum dögum hætti notendur okkar að skrifa hver á annan. Til að missa ekki skilaboð á þessum tíma skiptum við yfir í vinnukerfi sem notar bæði gamla og nýja klasa.

Gögn eru skrifuð til spjallmeðlima og notendavélar (en ekki á textavél, eins og í venjulegri notkun samkvæmt gamla kerfinu). user-engine umboðs beiðni til chat-engine - og hér fer hegðunin eftir því hvort þetta spjall hefur þegar verið sameinað eða ekki. Ef spjallið hefur ekki enn verið sameinað, skrifar spjallvélin ekki skilaboðin til sjálfrar sín og vinnsla þess fer aðeins fram í textavélinni. Ef spjallið hefur þegar verið sameinað í spjallvél, skilar það chat_local_id í notendavél og sendir skilaboðin til allra viðtakenda. notendavél setur öll gögn í textavél - þannig að ef eitthvað gerist getum við alltaf snúið okkur til baka, með öll núverandi gögn í gömlu vélinni. text-engine skilar user_local_id, sem notendavél geymir og skilar aftur til bakendans.
Endurskrifaðu VKontakte skilaboðagagnagrunninn frá grunni og lifðu af
Fyrir vikið lítur umbreytingarferlið svona út: við tengjum saman tóma notendavél og spjallvélaklasa. spjallvélin les allan binlog spjallmeðlima, síðan hefst umboð í samræmi við kerfið sem lýst er hér að ofan. Við flytjum gömlu gögnin og fáum tvo samstillta klasa (gamla og nýja). Allt sem er eftir er að skipta lestri úr textavél yfir í notendavél og slökkva á umboði.

Niðurstöður

Þökk sé nýju nálguninni hafa allar frammistöðumælingar vélanna verið bættar og vandamál með samkvæmni gagna hafa verið leyst. Nú getum við fljótt innleitt nýja eiginleika í skilaboðum (og erum þegar byrjuð að gera þetta - við fjölguðum hámarksfjölda spjallþátttakenda, innleiddum leit að áframsendum skilaboðum, settum af stað fest skilaboð og hækkuðum mörkin á heildarfjölda skilaboða á hvern notanda) .

Breytingarnar á rökfræði eru sannarlega gríðarlegar. Og ég vil taka það fram að þetta þýðir ekki alltaf heil ár af þróun með risastóru teymi og mýgrútur af kóðalínum. spjallvél og notendavél ásamt öllum viðbótarsögum eins og Huffman fyrir skilaboðaþjöppun, Splay tré og uppbygging fyrir innflutt skilaboð er minna en 20 þúsund línur af kóða. Og þau voru skrifuð af 3 forriturum á aðeins 10 mánuðum (það er hins vegar þess virði að hafa í huga að allt þrír verktaki - heimsmeistarar í íþróttaforritun).

Þar að auki, í stað þess að tvöfalda fjölda netþjóna, fækkuðum við fjölda þeirra um helming - nú eru notendavélin og spjallvélin lifandi á 500 líkamlegum vélum, á meðan nýja kerfið hefur mikið rými fyrir hleðslu. Við spöruðum mikla peninga í búnaði - um $5 milljónir + $750 þúsund á ári í rekstrarkostnað.

Við leitumst við að finna bestu lausnirnar fyrir flóknustu og umfangsmestu vandamálin. Við eigum nóg af þeim - og þess vegna erum við að leita að hæfileikaríkum forriturum í gagnagrunnsdeildina. Ef þú elskar og veist hvernig á að leysa slík vandamál, hefur framúrskarandi þekkingu á reikniritum og gagnagerð, bjóðum við þér að slást í hópinn. Hafðu samband við okkar HRfyrir nánari upplýsingar.

Jafnvel þó þessi saga sé ekki um þig, vinsamlega athugaðu að við metum tillögur. Segðu vini frá laus störf verktaki, og ef hann lýkur reynslutímanum færðu 100 þúsund rúblur í bónus.

Heimild: www.habr.com

Bæta við athugasemd