Blog

Alarme që ndizen një herë, jo një herë për çdo server

Një nga alarmet tona operacionale — "kredite të pakta" për një aplikacion të publikuar të ndërtuesit — synon të arrijë tek ne të paktën një herë në ditë. Një pasdite arriti pesë herë. Shkaku: çdo kopje e API-t tonë mbante në memorjen e vet cilat alarme kishte dërguar tashmë, kështu që dy serverët e dërguan dy herë, dhe çdo deploy e fshinte atë memorje dhe i linte të dërgonin përsëri. I njëjti model kishte bërë që një punë në sfond të ekzekutohej dy herë. Të dyja tani koordinohen përmes një depoje të përbashkët, dhe të dyja dështojnë në anën e sigurt nëse ajo depo nuk është e disponueshme.

Simptoma

Mythex dërgon alarme për ekipin kur diçka kërkon vëmendje: një shërbim është jashtë funksionit, një punë është ngecur, ose bilanci i kredive të një ndërtuesi është duke u shteruar ndërsa aplikacioni i tij është publikuar. Çdo alarm ka një dritare deduplikimi — një periudhë gjatë së cilës i njëjti alarm dërgohet vetëm një herë. Për alarmin e kredive të pakta, ajo dritare është 24 orë.

Pesë kopje të të njëjtit alarm në një pasdite do të thoshte që dritarja nuk po mbahej. Më keq, vinin në çifte, afërsisht 11 minuta larg njëri-tjetrit.

Pse ndodhi

Paketa jonë e alarmeve mbante deduplikimin në memorje: një tabelë "çelës alarmi → kur u dërgua për herë të fundit", brenda procesit që po ekzekutohet. Kjo funksionon kur ka një proces të vetëm që nuk rinisët kurrë. Prodhimi nuk ka asnjërin nga të dyja:

  • Dy replika të API-t. Prodhimi ekzekuton dy kopje të API-t. Secila kishte tabelën e vet, kështu që secila e dërgonte alarmin një herë. Ky është çifti.
  • Deploy-et. Çdo deploy zëvendëson të dyja repliket me procese të reja dhe tabela bosh. Pas një deploy-i, alarmi dilte sërish, sikur të mos ishte dërguar kurrë.

Vonesa ~11-minutëshe midis dy alarmeve të çiftit vinte nga puna që e ngre këtë alarm. Ajo ekzekutohet në të dy repliket dhe merr një bllokim, kështu që repliket e fitojnë me radhë, dhe secila e ngrinte alarmin kur vinte radha e saj.

Kishte edhe një gabim të dytë, më të heshtur, në të njëjtin kod. Për të mos u rritur tabela përgjithmonë, ajo pastrohej vetvetiu sapo arrinte 500 çelësa — duke fshirë çdo hyrje më të vjetër se 15 minuta, pa marrë parasysh dritaren e saj. Nën ngarkesë, një deduplikim 24-orësh mund të zgjaste një çerek ore.

Rregullimi

Një regjistrim i përbashkët për çdo alarm

Para se API-ja të dërgojë një alarm, tani ai e rezervon çelësin e deduplikimit të alarmit në Redis — një depo e përbashkët në memorje, me të cilën flasin të dy repliket dhe që nuk rinisët kur rinisët API-ja. Rezervimi është një operacion i vetëm: "vendose këtë çelës vetëm nëse nuk ekziston, dhe skadoje pas dritares". Ai replikë që e rezervon së pari e dërgon alarmin; tjetra e gjen çelësin të zënë dhe heshtë. Një proces i ri pas një deploy-i e gjen çelësin ende aty.

Çelësi dhe dritarja vijnë nga i njëjti rregull që përdor paketa e alarmeve, tani e ndarë mes tyre, kështu që dy shtresat nuk mund të mos pajtohen se çfarë konsiderohet "i njëjti alarm".

Dështo i hapur, jo i mbyllur

Vendimi më i rëndësishëm ishte çfarë të bëjmë kur Redis nuk mund të arrihet. Zgjodhëm ta dërgojmë alarmin gjithsesi. Nëse Redis është jashtë funksionit, ose nuk përgjigjet brenda 1.5 sekondash, alarmi del. Një alarm i dyfishtë është zhurmë. Një alarm i humbur do të thotë që dikush nuk u informua.

Alarmet P0, më të rëndësishmet, nuk ndalohen kurrë nga deduplikimi.

Çdo hyrje mban dritaren e vet

Deduplikimi në memorje i paketës së alarmeve ruan tani kur mbaron dritarja e secilës hyrje, dhe pastrimi heq vetëm hyrjet ku dritarja ka mbaruar. Një çelës 24-orësh mbetet për 24 orë, pavarësisht sa alarme të tjera vijnë.

E njëjta gabim, diku tjetër

I njëjti model kishte dyfishuar edhe një pjesë punës në sfond: një punë pajtimi që mban regjistrin tonë të statusit të çdo hapësire pune në përputhje me ofruesin tonë të sandbox-eve. Çdo kalim liston çdo sandbox në llogari — mijëra në prodhim, rreth pesë sekonda — plus çdo projekt që po ekzekutohet ose është në pauzë. Të dy repliket e ekzekutonin çdo dy minuta.

Shkrimet e saj janë idempotente — ekzekutimi i tyre dy herë jep të njëjtin rezultat sa një herë — kështu që asgjë nuk u prish. Thjesht ishte punë e dyfishtë. Tani çdo dritare dy-minutëshe rezervohet në Redis në të njëjtën mënyrë si e rezervonin tashmë matësit tanë të përdorimit, dhe vetëm replika që e rezervon e ekzekuton kalimin. Nëse Redis nuk arrihet, kalimi ekzekutohet gjithsesi: të bësh punën dy herë është e padëmshme, ndërsa të mos e bësh fare nuk është.

Si e testuam

Testet modelojnë konfigurimin real. Ngarkojnë modulin e alarmeve dy herë, si dy "replika" të veçanta, i drejtojnë të dyja te një depo e përbashkët, ngrenë të njëjtin alarm nga secila, pastaj ngarkojnë një kopje të tretë të freskët për të përfaqësuar "pas një deploy-i" dhe e ngrenë sërish. Dërgohet saktësisht një alarm. Teste të tjera kontrollojnë që alarmi i një ndërtuesi tjetër të dalë ende, që një P0 të dërgohet nga të dyja repliket, dhe që alarmi të dërgohet edhe kur depoja është jashtë funksionit ose vonohet përtej afatit. Rregullimi i pastrimit ka testin e vet: një çelës 24-orësh mbijeton 600 alarme të tjera që arrijnë 20 minuta më vonë.

Për punën e pajtimit, dy replika që tiktakojnë njëkohësisht, plus një tik i tretë në të njëjtën dritare, prodhojnë një listim të vetëm.

Çfarë morëm nga kjo

  • Gjendja në memorje është për proces. Çdo gjë që duhet të jetë e vërtetë në të gjithë serverët — "u dërgua një herë", "u ekzekutua një herë" — duhet të jetojë diku që ata e ndajnë.
  • Deploy-et janë rinisje. Gjendja që mbijeton vetëm deri në rinisjen tjetër nuk mbijeton një ditë normale pune.
  • Vendos se si të dështosh. Për alarmet, nëse një depo e përbashkët është jashtë funksionit, duhet të thotë më shumë alarme, jo më pak.
  • Kërko modelin, jo vetëm rastin. Alarmi ishte rasti i zhurmshëm; puna e dyfishtë e pajtimit ishte e njëjta gabim, që kushtonte heshtazi punë.

Asgjë nga kjo nuk është e dukshme nga brenda Mythex. Për më shumë rreth mënyrës si e mbajmë platformën të qëndrueshme, shiko si arritëm deploy-e pa asnjë gabim 502 dhe skedarin e humbur të swap-it. Nëse je i ri me idenë e ekzekutimit të më shumë se një kopjeje të një shërbimi, udhëzuesi ynë për çfarë është një server mbulon bazat.

Mythex · Pricing · Ndërtoni çdo gjë me AI · Shablone faqesh dhe aplikacionesh · Mythex në krahasim · Fjalori i ndërtimit të aplikacioneve me AI · Mjete falas për ndërtimin e aplikacioneve me AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)