Kuidas tõrketaluvat veebiarhitektuuri Mail.ru pilvelahenduste platvormis rakendatakse

Kuidas tõrketaluvat veebiarhitektuuri Mail.ru pilvelahenduste platvormis rakendatakse

Tere, Habr! Olen Artem Karamõšev, süsteemihaldusmeeskonna juht Mail.Ru pilvelahendused (MCS). Viimase aasta jooksul on meil olnud palju uusi tooteid. Tahtsime tagada, et API-teenused oleksid hõlpsasti skaleeritavad, tõrketaluvad ja kasutajakoormuse kiireks kasvuks valmis. Meie platvorm on juurutatud OpenStackis ja ma tahan teile öelda, millised komponentide tõrketaluvuse probleemid pidime tõrketaluva süsteemi saamiseks lahendama. Ma arvan, et see on huvitav neile, kes arendavad tooteid ka OpenStackis.

Platvormi üldine veataluvus seisneb selle komponentide vastupidavuses. Seega käime järk-järgult läbi kõik tasemed, kus tuvastasime riskid ja need sulgesime.

Selle loo videoversioon, mille esmaseks allikaks oli raport Uptime day 4 konverentsil, mille korraldas ITSumma, sa näed Uptime Community YouTube'i kanalil.

Füüsilise arhitektuuri vastupidavus

MCS pilve avalik osa asub nüüd kahes Tier III andmekeskuses, nende vahel on oma tume kiud, mis on füüsilisel tasandil reserveeritud erinevate marsruutide kaupa, läbilaskevõimega 200 Gbit/s. III tasand tagab füüsilise infrastruktuuri vajaliku veataluvuse taseme.

Tume kiud on reserveeritud nii füüsilisel kui ka loogilisel tasandil. Kanalite broneerimise protsess oli iteratiivne, tekkisid probleemid ja täiustame pidevalt andmekeskuste vahelist suhtlust.

Näiteks mõni aeg tagasi lõhkus ekskavaator ühe andmekeskuse lähedal kaevus töötades toru ja selle toru sees oli nii pea- kui ka varuoptiline kaabel. Meie tõrketaluv suhtluskanal andmekeskusega osutus ühel hetkel, kaevus, haavatavaks. Sellest tulenevalt oleme kaotanud osa infrastruktuurist. Tegime järeldused ja tegime mitmeid toiminguid, sealhulgas paigaldasime kõrvalasuvasse kaevu täiendava optika.

Andmekeskustes on sideteenuse pakkujate asukohapunktid, kellele edastame oma eesliiteid BGP kaudu. Iga võrgusuuna jaoks valitakse parim mõõdik, mis võimaldab erinevatele klientidele pakkuda parimat ühenduse kvaliteeti. Kui side ühe teenusepakkuja kaudu katkeb, loome marsruutimise ümber saadaolevate pakkujate kaudu.

Kui teenusepakkuja ebaõnnestub, lülitume automaatselt järgmisele teenusele. Ühe andmekeskuse rikke korral on meil teises andmekeskuses meie teenuste peegelkoopia, mis võtab enda peale kogu koormuse.

Kuidas tõrketaluvat veebiarhitektuuri Mail.ru pilvelahenduste platvormis rakendatakse
Füüsilise infrastruktuuri vastupidavus

Mida me kasutame rakenduse tasemel tõrketaluvuse jaoks

Meie teenus põhineb paljudel avatud lähtekoodiga komponentidel.

ExaBGP on teenus, mis rakendab mitmeid funktsioone, kasutades BGP-põhist dünaamilise marsruutimise protokolli. Kasutame seda aktiivselt oma lubatud IP-aadresside reklaamimiseks, mille kaudu kasutajad API-le pääsevad.

HAProxy on suure koormuse tasakaalustaja, mis võimaldab konfigureerida väga paindlikke liikluse tasakaalustamise reegleid OSI mudeli erinevatel tasanditel. Kasutame seda tasakaalustamiseks kõigi teenuste ees: andmebaasid, sõnumimaaklerid, API-teenused, veebiteenused, meie siseprojektid – kõik on HAProxy taga.

API rakendus — pythonis kirjutatud veebirakendus, millega kasutaja haldab oma infrastruktuuri ja teenust.

Töötaja taotlus (edaspidi lihtsalt töötaja) - OpenStacki teenustes on see infrastruktuuri deemon, mis võimaldab teil API käske infrastruktuurile edastada. Näiteks ketta loomine toimub töötajas ja loomise taotlus rakenduse API-s.

Standardne OpenStacki rakendusarhitektuur

Enamik OpenStacki jaoks välja töötatud teenuseid püüavad järgida ühte paradigmat. Teenus koosneb tavaliselt kahest osast: API ja töötajad (taustaprogrammi täitjad). API on reeglina pythonis WSGI rakendus, mis käivitatakse kas iseseisva protsessina (deemonina) või kasutades valmis Nginxi või Apache veebiserverit. API töötleb kasutaja päringut ja edastab täiendavad juhised töölise rakendusele täitmiseks. Edastamine toimub sõnumivahendaja, tavaliselt RabbitMQ abil, teised on halvasti toetatud. Kui sõnumid jõuavad maaklerini, töötlevad need töötajad läbi ja vajadusel tagastavad vastuse.

See paradigma hõlmab üksikuid ühiseid tõrkepunkte: RabbitMQ ja andmebaas. Kuid RabbitMQ on ühes teenuses isoleeritud ja teoreetiliselt võib see olla iga teenuse jaoks individuaalne. Seega eraldame MCS-is need teenused nii palju kui võimalik; iga üksiku projekti jaoks loome eraldi andmebaasi, eraldi RabbitMQ. Selline lähenemine on hea, sest mõnes haavatavas kohas õnnetuse korral ei purune mitte kogu teenus, vaid ainult osa sellest.

Töötajate rakenduste arv on piiramatu, nii et API saab hõlpsasti horisontaalselt tasakaalustajate taha skaleerida, et suurendada jõudlust ja tõrketaluvust.

Mõned teenused nõuavad teenuses koordineerimist, kui API-de ja töötajate vahel toimuvad keerulised järjestikused toimingud. Sel juhul kasutatakse ühte koordineerimiskeskust, klastrisüsteemi nagu Redis, Memcache jne, mis võimaldab ühel töötajal teisele öelda, et see ülesanne on talle määratud ("palun ära võta seda"). Kasutame jne. Töötajad suhtlevad reeglina aktiivselt andmebaasiga, kirjutavad ja loevad sealt infot. Andmebaasina kasutame mariadb, mis asub multimasterklastris.

See klassikaline üksikteenus on korraldatud OpenStacki jaoks üldiselt aktsepteeritud viisil. Seda võib pidada suletud süsteemiks, mille puhul on skaleerimise ja veataluvuse meetodid üsna ilmsed. Näiteks API tõrketaluvuse jaoks piisab, kui panna nende ette tasakaalustaja. Töötajate skaleerimine saavutatakse nende arvu suurendamisega.

Kogu skeemi nõrk koht on RabbitMQ ja MariaDB. Nende arhitektuur väärib eraldi artiklit. Selles artiklis tahan keskenduda API veataluvusele.

Kuidas tõrketaluvat veebiarhitektuuri Mail.ru pilvelahenduste platvormis rakendatakse
Openstacki rakenduste arhitektuur. Pilveplatvormi tasakaalustamine ja veataluvus

HAProxy tasakaalustaja muutmine ExaBGP abil tõrketaluvaks

Et muuta meie API-d skaleeritavaks, kiireks ja tõrketaluvaks, paneme nende ette koormuse tasakaalustaja. Valisime HAProxy. Minu arvates on sellel kõik meie ülesandeks vajalikud omadused: tasakaalustamine mitmel OSI tasemel, haldusliides, paindlikkus ja mastaapsus, suur hulk tasakaalustamismeetodeid, seansitabelite tugi.

Esimene probleem, mis vajas lahendamist, oli tasakaalustaja enda veataluvus. Lihtsalt tasakaalustaja paigaldamine loob ka tõrkepunkti: tasakaalustaja puruneb ja teenus jookseb kokku. Selle vältimiseks kasutasime HAProxyt koos ExaBGP-ga.

ExaBGP võimaldab teil rakendada mehhanismi teenuse oleku kontrollimiseks. Kasutasime seda mehhanismi HAProxy funktsionaalsuse kontrollimiseks ja probleemide korral BGP-st HAProxy teenuse keelamiseks.

ExaBGP+HAProksi skeem

  1. Paigaldame kolmele serverile vajaliku tarkvara, ExaBGP ja HAProxy.
  2. Loome igas serveris loopback-liidese.
  3. Kõigis kolmes serveris määrame sellele liidesele sama valge IP-aadressi.
  4. Valget IP-aadressi reklaamitakse Internetti ExaBGP kaudu.

Tõrketaluvus saavutatakse sama IP-aadressi reklaamimisega kõigis kolmes serveris. Võrgu seisukohast on samale aadressile juurdepääs kolmest erinevast järgmisest hüppest. Ruuter näeb kolme identset marsruuti, valib neist kõrgeima prioriteedi oma mõõdiku alusel (tavaliselt on see sama valik) ja liiklus läheb ainult ühte serveritest.

HAProxy tööprobleemide või serveri rikke korral lõpetab ExaBGP marsruudi teatamise ja liiklus lülitub sujuvalt teisele serverile.

Seega saavutasime tasakaalustaja veataluvuse.

Kuidas tõrketaluvat veebiarhitektuuri Mail.ru pilvelahenduste platvormis rakendatakse
HAProxy tasakaalustajate veataluvus

Skeem osutus ebatäiuslikuks: õppisime HAProxy reserveerimist, kuid ei õppinud teenuste sees koormust jaotama. Seetõttu laiendasime seda skeemi veidi: asusime tasakaalustama mitme valge IP-aadressi vahel.

Tasakaalustamine DNS pluss BGP alusel

Meie HAProxy koormuse tasakaalustamise probleem on endiselt lahendamata. Selle saab aga üsna lihtsalt lahendada, nagu siin tegime.

Kolme serveri tasakaalustamiseks vajate 3 valget IP-aadressi ja vana head DNS-i. Kõik need aadressid määratakse iga HAProxy loopback-liideses ja reklaamitakse Internetti.

OpenStackis kasutatakse ressursside haldamiseks teenusekataloogi, mis määrab konkreetse teenuse lõpp-punkti API. Selles kataloogis registreerime domeeninime - public.infra.mail.ru, mis lahendatakse DNS-i kaudu kolme erineva IP-aadressi abil. Selle tulemusena saame DNS-i kaudu koormuse jaotuse kolme aadressi vahel.

Kuid kuna valgete IP-aadresside väljakuulutamisel me ei kontrolli serveri valiku prioriteete, siis see ei ole veel tasakaalus. Tavaliselt valitakse IP-aadressi vanemuse põhjal ainult üks server ja ülejäänud kaks on jõude, kuna BGP-s pole mõõdikuid määratud.

Hakkasime saatma erinevate mõõdikutega marsruute ExaBGP kaudu. Iga tasakaalustaja reklaamib kõiki kolme valget IP-aadressi, kuid üks neist, selle tasakaalustaja peamine, on reklaamitud minimaalse mõõdikuga. Seega, kui kõik kolm tasakaalustajat töötavad, lähevad esimesele IP-aadressile tehtud kõned esimesele, teisele teisele ja kolmandale kolmandale.

Mis juhtub, kui üks tasakaalustajatest kukub? Kui mõni tasakaalustaja ebaõnnestub, reklaamitakse selle peamist aadressi ikkagi kahest teisest ja liiklus jagatakse nende vahel ümber. Seega anname kasutajale DNS-i kaudu korraga mitu IP-aadressi. DNS-i ja erinevate mõõdikute järgi tasakaalustades saame koormuse ühtlase jaotuse kõigi kolme tasakaalustaja vahel. Ja samas ei kaota me veataluvust.

Kuidas tõrketaluvat veebiarhitektuuri Mail.ru pilvelahenduste platvormis rakendatakse
HAProxy tasakaalustamine DNS + BGP alusel

ExaBGP ja HAProxy vaheline koostoime

Seega rakendasime tõrketaluvuse juhuks, kui server lahkub, lähtudes marsruutide teatamise peatamisest. Kuid HAProxy võib välja lülituda ka muudel põhjustel kui serveri rike: haldusvead, teenusesisesed tõrked. Ka nendel juhtudel tahame katkise tasakaalustaja koormuse alt eemaldada ja vajame teistsugust mehhanismi.

Seetõttu rakendasime eelmist skeemi laiendades ExaBGP ja HAProxy vahel südamelöögid. See on ExaBGP ja HAProxy vahelise suhtluse tarkvararakendus, kui ExaBGP kasutab rakenduste oleku kontrollimiseks kohandatud skripte.

Selleks tuleb ExaBGP konfiguratsioonis konfigureerida tervisekontroll, mis saab kontrollida HAProxy olekut. Meie puhul konfigureerisime tervise taustaprogrammi HAProxys ja ExaBGP poolelt kontrollime lihtsa GET-päringuga. Kui teade enam ei ilmu, siis HAProxy tõenäoliselt ei tööta ja seda pole vaja reklaamida.

Kuidas tõrketaluvat veebiarhitektuuri Mail.ru pilvelahenduste platvormis rakendatakse
HAProxy tervisekontroll

HAProxy Peers: seansi sünkroonimine

Järgmine asi, mida teha, oli seansside sünkroonimine. Hajutatud tasakaalustajate kaudu töötades on kliendiseansside kohta teabe salvestamist keeruline korraldada. Kuid HAProxy on üks väheseid tasakaalustajaid, mis suudab seda teha tänu Peersi funktsionaalsusele – võimalusele edastada sessioonitabeleid erinevate HAProxy protsesside vahel.

Tasakaalustusmeetodeid on erinevaid: lihtsaid nagu ümmargune röövel, ja pikendatakse, kui kliendi seanss jääb meelde ja iga kord, kui ta satub samasse serverisse, kus varem. Tahtsime rakendada teist võimalust.

HAProxy kasutab selle mehhanismi kliendiseansside salvestamiseks stick-tabeleid. Need salvestavad kliendi algse IP-aadressi, valitud sihtaadressi (tagaprogrammi) ja osa teenuseteavet. Tavaliselt kasutatakse pulgatabeleid lähte-IP + sihtkoha-IP paari salvestamiseks, mis on eriti kasulik rakenduste jaoks, mis ei saa kasutaja seansi konteksti üle kanda, kui lülituvad teisele tasakaalustajale, näiteks RoundRobini tasakaalustamisrežiimis.

Kui pulgalauda õpetatakse liikuma erinevate HAProxy protsesside vahel (mille vahel toimub tasakaalustamine), saavad meie tasakaalustajad töötada ühe pulgalauaga. See võimaldab sujuvalt vahetada kliendi võrku, kui üks tasakaalustajatest ebaõnnestub; töö kliendiseanssidega jätkub samadel taustaprogrammidel, mis valiti varem.

Korralikuks tööks tuleb lahendada tasakaalustaja lähte IP-aadressi probleem, millest seanss loodi. Meie puhul on see loopback-liidese dünaamiline aadress.

Eakaaslaste korrektne töö saavutatakse ainult teatud tingimustel. See tähendab, et TCP ajalõpud peavad olema piisavalt suured või lülitus piisavalt kiire, et TCP-seansil ei oleks aega lõpetada. See võimaldab aga sujuvat ümberlülitamist.

IaaS-is on meil sama tehnoloogia abil loodud teenus. See Load Balancer OpenStacki teenusena, mida nimetatakse Octaviaks. See põhineb kahel HAProxy protsessil ja sisaldab algselt kaaslaste tuge. Nad on end selles teenuses suurepäraselt tõestanud.

Pilt näitab skemaatiliselt partnertabelite liikumist kolme HAProxy eksemplari vahel, pakutakse konfiguratsiooni, kuidas seda konfigureerida:

Kuidas tõrketaluvat veebiarhitektuuri Mail.ru pilvelahenduste platvormis rakendatakse
HAProxy Peers (seansi sünkroonimine)

Kui rakendate sama skeemi, tuleb selle toimimist hoolikalt testida. Pole tõsi, et see töötab 100% ajast samamoodi. Kuid vähemalt ei kaota te pulgatabeleid, kui peate meeles pidama kliendi lähte-IP-d.

Sama kliendi samaaegsete päringute arvu piiramine

Kõikidele avalikult kättesaadavatele teenustele, sealhulgas meie API-dele, võib tulla taotluste laviin. Nende põhjused võivad olla täiesti erinevad, alates kasutaja vigadest kuni suunatud rünnakuteni. IP-aadressid kontrollivad meid perioodiliselt. Kliendid teevad sageli oma skriptides vigu ja annavad meile mini-DDoS-e.

Nii või teisiti tuleb pakkuda lisakaitset. Ilmselge lahendus on piirata API päringute arvu ja mitte raisata protsessori aega pahatahtlike päringute töötlemiseks.

Selliste piirangute rakendamiseks kasutame HAProxy alusel korraldatud kiiruspiiranguid, kasutades samu pulgatabeleid. Limiitide seadistamine on üsna lihtne ja võimaldab piirata kasutajat API-le esitatavate taotluste arvu järgi. Algoritm jätab meelde lähte IP-aadressi, kust päringuid tehakse, ja piirab ühe kasutaja samaaegsete päringute arvu. Loomulikult arvutasime iga teenuse jaoks välja keskmise API koormusprofiili ja seadsime limiidiks ≈ 10 korda selle väärtuse. Jätkame olukorra tähelepanelikku jälgimist ja hoiame kätt pulsil.

Kuidas see praktikas välja näeb? Meil on kliente, kes kasutavad meie automaatse skaleerimise API-sid kogu aeg. Nad loovad umbes kaks kuni kolmsada virtuaalmasinat hommikul ja kustutavad need õhtul. OpenStacki puhul nõuab virtuaalmasina loomine, ka PaaS-i teenustega, vähemalt 1000 API päringut, kuna teenustevaheline suhtlus toimub ka API kaudu.

Selline ülesannete üleandmine põhjustab üsna suure koormuse. Hindasime seda koormust, kogusime igapäevaseid tippe, suurendasime neid kümnekordseks ja sellest sai meie kiiruse piir. Hoiame sõrme pulsil. Sageli näeme roboteid ja skannereid, kes üritavad meid vaadata, et näha, kas meil on CGA-skripte, mida saaks käivitada, ja me lõikame neid aktiivselt.

Kuidas värskendada oma koodibaasi, ilma et kasutajad seda märkaksid

Samuti rakendame tõrketaluvust koodi juurutamise protsesside tasemel. Avaldamise ajal võib esineda tõrkeid, kuid nende mõju teenuse kättesaadavusele saab minimeerida.

Uuendame oma teenuseid pidevalt ja peame tagama, et koodibaasi värskendatakse kasutajaid mõjutamata. Meil õnnestus see probleem lahendada, kasutades HAProxy haldusvõimalusi ja Graceful Shutdowni juurutamist meie teenustes.

Selle probleemi lahendamiseks oli vaja tagada tasakaalustaja juhtimine ja teenuste "õige" väljalülitamine:

  • HAProxy puhul toimub juhtimine statistikafaili kaudu, mis on sisuliselt pesa ja on määratletud HAProxy konfiguratsioonis. Saate sellele stdio kaudu käske saata. Kuid meie peamine konfiguratsiooni juhtimistööriist on võimalik, seega on sellel HAProxy haldamiseks sisseehitatud moodul. Mida me aktiivselt kasutame.
  • Enamik meie API ja Engine'i teenuseid toetavad graatsilisi sulgemistehnoloogiaid: väljalülitamisel ootavad nad praeguse toimingu lõpuleviimist, olgu selleks siis http-päring või mõni teenindusülesanne. Sama juhtub ka töötajaga. Ta teab kõiki ülesandeid, mida ta teeb, ja lõpetab, kui on kõik edukalt täitnud.

Tänu nendele kahele punktile näeb meie juurutamise turvaline algoritm välja selline.

  1. Arendaja koostab uue koodipaketi (meie jaoks on see RPM), testib seda arenduskeskkonnas, testib etapis ja jätab etapi hoidlasse.
  2. Arendaja määrab juurutamise ülesande koos "artefaktide" kõige üksikasjalikuma kirjeldusega: uue paketi versioon, uue funktsionaalsuse kirjeldus ja vajadusel muud juurutamise üksikasjad.
  3. Süsteemiadministraator alustab värskendamist. Käivitab Ansible mänguraamatu, mis omakorda teeb järgmist.
    • Võtab etapihoidlast paketi ja kasutab seda tootehoidlas oleva paketi versiooni värskendamiseks.
    • Koostab värskendatud teenuse taustaprogrammide loendi.
    • Sulgeb esimese HAProxys värskendatava teenuse ja ootab, kuni selle protsessid käitamise lõpetavad. Tänu graatsilisele sulgemisele oleme kindlad, et kõik praegused klienditaotlused täidetakse edukalt.
    • Pärast API ja töötajate täielikku peatamist ning HAProxy väljalülitamist värskendatakse koodi.
    • Ansible juhib teenuseid.
    • Iga teenuse jaoks tõmmatakse teatud "käepidemed", mis teostavad üksuse testimist mitmel eelnevalt määratletud võtmetestil. Toimub uue koodi põhikontroll.
    • Kui eelmises etapis vigu ei leitud, aktiveeritakse taustaprogramm.
    • Liigume edasi järgmise taustaprogrammi juurde.
  4. Pärast kõigi taustaprogrammide värskendamist käivitatakse funktsionaalsed testid. Kui need puuduvad, vaatab arendaja kõiki enda loodud uusi funktsioone.

See viib juurutamise lõpule.

Kuidas tõrketaluvat veebiarhitektuuri Mail.ru pilvelahenduste platvormis rakendatakse
Teenuse värskendustsükkel

See skeem ei töötaks, kui meil poleks ühte reeglit. Toetame lahingus nii vanu kui ka uusi versioone. Eelnevalt on tarkvara arendamise etapis ette nähtud, et isegi kui teenuse andmebaasis on muudatusi, ei riku need eelmist koodi. Selle tulemusena uuendatakse koodibaasi järk-järgult.

Järeldus

Jagades oma mõtteid tõrketaluva veebiarhitektuuri kohta, tahaksin veel kord märkida selle põhipunktid:

  • füüsiline veataluvus;
  • võrgu tõrketaluvus (balansseerijad, BGP);
  • kasutatava ja arendatud tarkvara veataluvus.

Stabiilne tööaeg kõigile!

Allikas: www.habr.com

Lisa kommentaar