Chat Moja Nzito Inaweza Kuiangusha API Yetu
Septemba 28, takriban dakika 17 baada ya toleo jipya, seva zetu mbili za API za uzalishaji zilikosa kumbukumbu wakati mmoja, zikaanzishwa upya, na kwa takriban dakika tano load balancer haikuwa na seva yenye afya ya kutumia. Marekebisho yetu ya kwanza yalitoa API kumbukumbu mara mbili zaidi. Sababu ya kweli ilionekana baadaye siku hiyo: kufungua chat moja mahususi kulimfanya API aombe jumbe za MB 53 kwa ombi moja. Historia ya chat sasa inapakiwa kwa kurasa zenye kikomo cha ukubwa pamoja na idadi, na chat hiyo inafunguka kwa ukurasa wa kwanza wa MB 5 badala ya kuanguka.
Kilichoanguka
API yetu inaendeshwa kama kontena kwenye kila seva mbili nyuma ya load balancer. Kila kontena lilikuwa na kikomo cha kumbukumbu cha MiB 384. Wakati wa kupumzika linatumia MiB 130–140, kwa hiyo kikomo kilionekana kuwa na nafasi nyingi.
Kontena zote mbili zilifikia kikomo hicho pamoja na kuanguka kwa ujumbe "JavaScript heap out of memory". Heap ni kumbukumbu ambayo mchakato wa Node.js unatumia kwa vitu inavyofanyia kazi. Kwa kuwa seva zote mbili zilishindwa kwa wakati mmoja, hakukuwa na mahali pa kuelekeza maombi. Hiyo ndiyo aina mbaya zaidi ya kukatika kwa setup yenye seva mbili: upatikanaji mwingi unasaidia tu pale hitilafu zisipotokea kwa wakati mmoja.
Marekebisho ya kwanza: nafasi zaidi
Muda ulielekeza kwenye deploy. Baada ya toleo jipya, zamu za wakala ambazo deploy iliingilia zinaanzishwa tena na kuhifadhi nakala zao za mazungumzo, na wimbi hilo la kazi lilionekana kama chanzo dhahiri cha ongezeko la kumbukumbu.
Kwa hiyo mabadiliko ya kwanza yaliinua kikomo cha API kutoka MiB 384 hadi MiB 768. Tuliyatumia moja kwa moja kwenye seva zote mbili siku hiyohiyo, na pia tukayaweka kwenye usanidi wa deploy ili deploy ijayo isirudishe 384 kimya kimya. Marekebisho yanayofanywa kwa mkono kwenye seva ambayo deploy ijayo inayafuta ni njia ya kawaida ambayo kukatika kunarudi.
Kumbukumbu zaidi ilikuwa hifadhi ya usalama inayofaa. Haikuwa maelezo.
Sababu ya kweli: ombi moja, MB 71
Baadaye siku hiyo tulirudia kuanguka kwenye nakala ya chat moja, tukitumia kikomo cha zamani cha kumbukumbu cha uzalishaji. Nakala hiyo iliangusha API peke yake, bila deploy yoyote kuhusika.
Unapofungua mradi, programu ya wavuti inaomba historia ya chat kutoka kwenye API. Kipengele hicho kilirudisha jumbe 30 za mwisho, zikiwa nzima. Kwa chat nyingi, jumbe 30 ni ndogo. Kwa chat hii, jumbe 30 za mwisho zilikuwa MB 53 kwenye hifadhidata na jibu la MB 71. Baadhi ya majibu ya wakala yalikuwa MB 4–10 kila moja, hasa nakala za wasaidizi wadogo: mawakala wasaidizi ambao wakala mkuu anawaanzisha kufanya sehemu ya kazi kwa wakati mmoja, ambao kazi yao kamili imehifadhiwa pamoja na jibu.
Kujenga jibu hilo moja kulichukua kumbukumbu zaidi ya API ilivyokuwa nayo. Na kila kufungua au kuonyesha upya mradi kulituma ombi tena. Chat moja ingeweza kuangusha seva yoyote iliyoipokea, na kwa kuwa ukurasa unaweza kupakiwa upya, ingeweza kufikia seva zote mbili.
"Jumbe 30" hazikuwahi kuwa kikomo halisi cha ukubwa. Zilikuwa kikomo cha idadi ambacho kilitokea kuwa kidogo kwa chat za kawaida.
Suluhisho: kurasa zenye kikomo cha ukubwa pamoja na idadi
Ukurasa wa historia sasa ni jumbe 30 au takriban MB 4 zake, kipi kitakachofika kwanza.
Unafanya kazi kwa hatua mbili:
- Omba ukubwa kwanza. API inaomba hifadhidata vitambulisho na ukubwa uliohifadhiwa wa jumbe za mwisho, bila yaliyomo. Swali hilo ni la bei nafuu bila kujali jumbe ni kubwa kiasi gani.
- Pakia kile tu kinachotoshea. Kwa kutembea kutoka mpya hadi za zamani, inaongeza jumbe hadi inayofuata isukume ukurasa kupita MB 4. Ni safu hizo tu zinazopakiwa kikamilifu.
Kanuni mbili zinaulinda usalama huu:
- Ujumbe wa mwisho daima unaingia kwenye ukurasa, bila kujali ukubwa wake. Ukurasa usiorudisha chochote ungeacha chat imekwama, bila njia ya kurudi nyuma.
- Hakuna kinachokatwa. Hakuna ujumbe unaokatwa au kuachwa. Sehemu nyingine ya chat inapakiwa kupitia kidhibiti cha "Sogeza juu kwa jumbe za awali" ambacho jumbe za zamani tayari zilikuwa zinakitumia, ukurasa mmoja kwa wakati mmoja.
Tulipata sehemu nyingine yenye umbo lilelile. Unapositisha zamu, API inakagua majibu machache ya mwisho kuona kama yoyote ni tupu na yanapaswa kusafishwa. Ilifanya hivyo kwa kupakia jumbe nane nzima. Kwenye chat ya majibu ya MB kadhaa, hilo ni tatizo lilelile katika umbo dogo. Sasa inauliza hifadhidata swali la ndiyo-au-hapana — je, ujumbe huu una yaliyomo yoyote? — bila kupakia yaliyomo yenyewe.
Jinsi tulivyokagua
Kwenye nakala ya chat, kwa kutumia kikomo cha zamani cha MiB 384:
- Ukurasa wa kwanza ni MB 5. Kabla, ombi hilohilo liliangusha API.
- Tabo tano za kivinjari zikifungua chat kwa wakati mmoja zinafikia kilele cha MB 154 za kumbukumbu.
- Kurudi nyuma kupitia chat yote kunarudisha jumbe zote 190, kila moja mara moja, kwa mpangilio.
Mantiki ya kuchagua kurasa pia ina majaribio ya kitengo, ikiwemo moja iliyojengwa kutoka ukubwa halisi wa jumbe za mwisho za chat hiyo. Ukurasa wa kwanza unarudisha ujumbe mmoja, unasema kuna zaidi, na ukurasa unaofuata unaanza kwenye ule unaofuata.
Tuliyojifunza
- Idadi si kikomo cha ukubwa. Kipengele chochote kinachorudisha "mpya zaidi N" za kitu kinachoweza kukua bila kikomo kinahitaji bajeti ya baiti pia. Data hatimaye itapata pengo hilo.
- Mshukiwa wa wazi si mara zote chanzo. Deploy ilikuwa kichocheo halisi cha kazi ya ziada, na kumbukumbu zaidi ilistahili kuwepo. Lakini kuanguka kulirudiwa bila deploy, na bila kulirudia tungeishia kwenye ongezeko la kumbukumbu.
- Seva mbili hushindwa pamoja zikipokea ombi lilelile. Upatikanaji mwingi unalinda dhidi ya seva moja kufa. Haulindi dhidi ya ombi linaloua seva yoyote linayoifikia, hasa moja ambalo mtumiaji ataliomba tena kwa kuonyesha upya.
- Rekebisha kwenye usanidi, si kwenye kisanduku pekee. Ongezeko la kumbukumbu liliingia kwenye usanidi wa deploy siku hiyohiyo, kwa hiyo deploy ijayo ililihifadhi.
Hii ni hadithi yetu ya pili ya hivi karibuni ya kumbukumbu inayohusu matokeo ya wakala. Ya kwanza ilikuwa lebo ya hali iliyopanga mfuatano wa MB 690. Ukitumia wasaidizi wadogo kwenye Mythex, unaweza kusoma jinsi wanavyofanya kazi kwenye nyaraka.