Blog

Upozornenia, ktoré sa spustia raz, nie raz na každý server

Jedno z našich prevádzkových upozornení — „nízke kredity“ pre publikovanú aplikáciu tvorcu — má prísť najviac raz denne. Jedno popoludnie prišlo päťkrát. Príčina: každá kópia nášho API si pamätala, ktoré upozornenia už poslala, vo vlastnej pamäti, takže dva servery ho poslali dvakrát a každé nasadenie tú pamäť vymazalo a nechalo ich poslať ho znova. Rovnaký vzorec mal aj úloha na pozadí, ktorá robila svoju prácu dvakrát. Obe teraz koordinujú cez zdieľané úložisko a obe v prípade jeho nedostupnosti zlyhajú na bezpečnej strane.

Príznak

Mythex posiela tímové upozornenia, keď niečo potrebuje pozornosť: služba je nedostupná, úloha uviazla alebo zostatok kreditov tvorcovej publikovanej aplikácie klesá. Každé upozornenie má okno deduplikácie — obdobie, počas ktorého sa rovnaké upozornenie pošle iba raz. Pri upozornení na nízke kredity je toto okno 24 hodín.

Päť kópií rovnakého upozornenia za jedno popoludnie znamenalo, že okno nefungovalo. Horšie bolo, že prichádzali v dvojiciach, zhruba 11 minút od seba.

Prečo sa to stalo

Náš balík upozornení držal deduplikáciu v pamäti: tabuľku „kľúč upozornenia → kedy naposledy odoslané“ vnútri bežiaceho procesu. To funguje, keď je jeden proces, ktorý sa nikdy nereštartuje. Produkcia nemá ani jedno:

  • Dve repliky API. Produkcia beží na dvoch kópiách API. Každá mala vlastnú tabuľku, takže každá poslala upozornenie raz. To sú tie dvojice.
  • Nasadenia. Každé nasadenie nahradí obe repliky novými procesmi s prázdnymi tabuľkami. Po nasadení sa upozornenie odoslalo znova, akoby nikdy predtým odoslané nebolo.

Medzera približne 11 minút medzi dvoma upozorneniami v každej dvojici pochádzala z úlohy, ktorá upozornenie vyvoláva. Beží na oboch replikách a berie zámok, takže repliky ho získavajú striedavo a každá upozornenie vyvolala, keď na ňu prišiel rad.

V tom istom kóde bola ešte tichšia chyba. Aby tabuľka nerástla donekonečna, pri päťstich kľúčoch sa sama vyčistila — vymazala každú položku staršiu ako 15 minút, bez ohľadu na jej okno. Pri záťaži tak mohla 24-hodinová deduplikácia trvať štvrť hodiny.

Oprava

Jeden zdieľaný záznam na upozornenie

Predtým, než API upozornenie odošle, si teraz nárokuje jeho deduplikačný kľúč v Redis — zdieľanom úložisku v pamäti, ku ktorému sa obe repliky pripájajú a ktoré sa nerestartuje, keď sa reštartuje API. Nárokovanie je jedna operácia: „nastav tento kľúč, iba ak ešte neexistuje, a vyprší po danom okne“. Ktorákoľvek replika ho nárokuje prvá, pošle upozornenie; druhá nájde kľúč obsadený a zostane ticho. Nový proces po nasadení nájde kľúč stále tam.

Kľúč a okno pochádzajú z rovnakého pravidla, ktoré používa balík upozornení, teraz zdieľaného medzi nimi, takže sa obe vrstvy nemôžu rozísť v tom, čo je „to isté upozornenie“.

Zlyhať otvorene, nie zatvorene

Najdôležitejšie rozhodnutie bolo, čo urobiť, keď sa Redis nedá dosiahnuť. Zvolili sme odoslať upozornenie aj tak. Ak je Redis nedostupný alebo neodpovie do 1,5 sekundy, upozornenie odíde. Duplicitné upozornenie je šum. Zahodené upozornenie znamená, že niekomu nikto nič nepovedal.

Najzávažnejšie upozornenia, P0, deduplikácia vôbec nezadržiava.

Každý záznam si drží vlastné okno

V deduplikácii v pamäti samotného balíka teraz každá položka ukladá, kedy sa jej okno končí, a čistenie odstraňuje iba položky, ktorých okno už uplynulo. 24-hodinový kľúč zostane 24 hodín, bez ohľadu na to, koľko ďalších upozornení príde.

Rovnaká chyba, inde

Rovnaký vzorec zdvojnásobil aj kus práce na pozadí: rekonciliačnú úlohu, ktorá udržiava náš záznam o stave každého workspace v súlade so stavom nášho poskytovateľa sandboxov. Každý prechod vypíše každý sandbox v účte — v produkcii tisíce, asi päť sekúnd — plus každý bežiaci alebo pozastavený projekt. Obe repliky ju spúšťali každé dve minúty.

Jej zápisy sú idempotentné — spustenie dvakrát dá rovnaký výsledok ako raz — takže sa nič nerozbilo. Išlo len o dvojnásobnú prácu. Teraz sa každé dvojminútové okno nárokuje v Redis rovnako, ako naše merania využitia nárokovali svoje, a prechod spustí len tá replika, ktorá ho nárokuje. Ak sa Redis nedá dosiahnuť, prechod sa spustí aj tak: robiť prácu dvakrát je neškodné, nerobiť ju nie.

Ako sme to testovali

Testy modelujú skutočné nastavenie. Načítajú modul upozornení dvakrát ako dve samostatné „repliky“, nasmerujú obe na jedno zdieľané úložisko, vyvolajú z každej to isté upozornenie a potom načítajú tretiu čerstvú kópiu, ktorá má zastupovať „po nasadení“, a vyvolajú ho znova. Odošle sa presne jedno upozornenie. Ďalšie testy kontrolujú, že upozornenie iného tvorcu stále odíde, že P0 sa odošle z oboch replík a že sa upozornenie odošle aj vtedy, keď je úložisko nedostupné alebo visí za časovým limitom. Oprava čistenia má vlastný test: 24-hodinový kľúč prežije 600 ďalších upozornení, ktoré prídu o 20 minút neskôr.

Pri rekonciliačnej úlohe dve repliky bežiace naraz plus tretí tik v tom istom okne vytvoria jeden výpis.

Čo sme si z toho odniesli

  • Stav v pamäti patrí jednému procesu. Všetko, čo musí platiť naprieč servermi — „odoslané raz“, „spustené raz“ — musí žiť niekde, čo zdieľajú.
  • Nasadenia sú reštarty. Stav, ktorý prežije len do ďalšieho reštartu, neprežije ani bežný pracovný deň.
  • Rozhodnite, ktorým smerom zlyhať. Pri upozorneniach by nedostupnosť zdieľaného úložiska mala znamenať viac upozornení, nie menej.
  • Hľadajte vzorec, nie len výskyt. Upozornenie bolo hlasný prípad; zdvojnásobená rekonciliačná úloha bola tá istá chyba, ktorá potichu stála prácu.

Nič z toho nie je v Mythexe viditeľné zvnútra. Viac o tom, ako udržiavame platformu stabilnú, nájdete v článkoch ako sme dostali nasadenia na nulu chýb 502 a chýbajúci swap súbor. Ak ste nováčik v myšlienke prevádzkovania viacerých kópií služby, náš sprievodca čo je server pokrýva základy.

Mythex · Pricing · Vytvorte čokoľvek s AI · Šablóny webov a aplikácií · Mythex v porovnaní · Slovník pojmov tvorby aplikácií s AI · Bezplatné nástroje na tvorbu aplikácií s 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 Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)