ఒక భారీ చాట్ మా API ను ఎలా కిందకు తీసుకెళ్లగలదు
సెప్టెంబర్ 28న, ఒక విడుదల తర్వాత సుమారు 17 నిమిషాలకు, మా ఉత్పత్తి API యొక్క రెండు సర్వర్లు ఒకే క్షణంలో మెమరీ అయిపోయి, రీస్టార్ట్ అయ్యాయి, మరియు సుమారు ఐదు నిమిషాల పాటు లోడ్ బ్యాలెన్సర్కు ట్రాఫిక్ పంపడానికి ఆరోగ్యకరమైన సర్వర్ లేకుండా పోయింది. మా మొదటి పరిష్కారం API కి రెండు రెట్లు మెమరీ ఇవ్వడం. అసలు కారణం ఆ రోజు తర్వాత బయటపడింది: ఒక నిర్దిష్ట చాట్ను తెరవడం ఒకే అభ్యర్థనలో 53 MB సందేశాలను లోడ్ చేయమని API ని అడిగింది. ఇప్పుడు చాట్ చరిత్ర సంఖ్యతో పాటు పరిమాణంతో కూడా పరిమితం చేయబడిన పేజీలలో లోడ్ అవుతుంది, మరియు ఆ చాట్ క్రాష్కు బదులుగా 5 MB మొదటి పేజీతో తెరుచుకుంటుంది.
ఏమి ఆగిపోయింది
మా API రెండు సర్వర్లలో ప్రతిదానిపై ఒక కంటైనర్గా, లోడ్ బ్యాలెన్సర్ వెనుక నడుస్తుంది. ప్రతి కంటైనర్కు 384 MiB మెమరీ పరిమితి ఉంది. విశ్రాంతిలో అది 130–140 MiB వాడుతుంది, కాబట్టి పరిమితి చాలా హెడ్రూమ్ ఉన్నట్టు కనిపించింది.
రెండు కంటైనర్లూ కలిసి ఆ పరిమితిని తాకి, “JavaScript heap out of memory” తో క్రాష్ అయ్యాయి. హీప్ అంటే Node.js ప్రాసెస్ తాను పనిచేస్తున్న ఆబ్జెక్ట్ల కోసం ఉపయోగించే మెమరీ. రెండు సర్వర్లూ ఒకేసారి విఫలమవడంతో, అభ్యర్థనలను పంపడానికి మిగిలిన చోటు లేదు. రెండు సర్వర్ల సెటప్కు ఇది అత్యంత చెడ్డ రకం అంతరాయం: వైఫల్యాలు ఒకేసారి జరగనప్పుడు మాత్రమే రిడండెన్సీ సహాయపడుతుంది.
మొదటి పరిష్కారం: ఎక్కువ స్థలం
సమయం విడుదల వైపే చూపింది. విడుదల తర్వాత, డిప్లాయ్ అంతరాయం కలిగించిన ఏజెంట్ టర్న్లు మళ్లీ ప్రారంభించబడి, తమ ట్రాన్స్క్రిప్ట్లను మళ్లీ సేవ్ చేస్తాయి, మరియు ఆ పని పేలుడు మెమరీ స్పైక్కు స్పష్టమైన మూలంగా కనిపించింది.
కాబట్టి మొదటి మార్పు API పరిమితిని 384 MiB నుండి 768 MiB కు పెంచింది. అదే రోజు రెండు సర్వర్లలో చేతితో వర్తింపజేసి, తదుపరి డిప్లాయ్ 384 ని మౌనంగా తిరిగి పెట్టకుండా ఉండేలా డిప్లాయ్ కాన్ఫిగరేషన్లో కమిట్ చేశాం. సర్వర్పై చేతితో చేసిన పరిష్కారాన్ని తర్వాతి డిప్లాయ్ తిరగ్గొడితే, అదే అంతరాయం మళ్లీ రావడానికి ఇది ఒక సాధారణ మార్గం.
ఎక్కువ మెమరీ ఒక సహేతుకమైన భద్రతా మార్జిన్. కానీ అది వివరణ కాదు.
అసలు కారణం: ఒక అభ్యర్థన, 71 MB
ఆ తర్వాత మేము పాత ఉత్పత్తి మెమరీ పరిమితిని ఉపయోగించి ఒక చాట్ కాపీపై క్రాష్ను పునరుత్పత్తి చేశాం. ఆ కాపీ డిప్లాయ్ ప్రమేయం లేకుండానే API ను స్వయంగా క్రాష్ చేసింది.
మీరు ఒక ప్రాజెక్ట్ తెరిచినప్పుడు, వెబ్ యాప్ చాట్ చరిత్ర కోసం API ని అడుగుతుంది. ఎండ్పాయింట్ అత్యంత కొత్త 30 సందేశాలను పూర్తిగా తిరిగి ఇచ్చేది. చాలా చాట్లకు 30 సందేశాలు చిన్నవి. ఈ ఒక చాట్కు, అత్యంత కొత్త 30 సందేశాలు డేటాబేస్లో 53 MB, మరియు స్పందనలో 71 MB. ఏజెంట్ సమాధానాలలో కొన్ని ఒక్కొక్కటి 4–10 MB ఉన్నాయి, ఎక్కువగా సబ్-ఏజెంట్ల ట్రాన్స్క్రిప్ట్లు: పనిలో కొంత భాగాన్ని సమాంతరంగా చేయడానికి ప్రధాన ఏజెంట్ ప్రారంభించే సహాయక ఏజెంట్లు, వాటి పూర్తి పని సమాధానంతో పాటు సేవ్ చేయబడుతుంది.
ఆ ఒక స్పందనను నిర్మించడం API కి ఉన్న హీప్ కంటే ఎక్కువ తీసుకుంది. మరియు ఆ ప్రాజెక్ట్ను తెరిచిన లేదా రిఫ్రెష్ చేసిన ప్రతిసారీ అభ్యర్థన మళ్లీ వెళ్లింది. ఒకే చాట్ దానికి చేరిన ఏ సర్వర్నైనా కిందకు తీసుకెళ్లగలదు, మరియు పేజీని రిఫ్రెష్ చేయవచ్చు కాబట్టి, రెండింటికీ చేరగలదు.
“30 సందేశాలు” ఎప్పుడూ నిజమైన పరిమాణ పరిమితి కాలేదు. అది ఒక సంఖ్య పరిమితి, సాధారణ చాట్లకు అది చిన్నదిగా ఉండేది.
పరిష్కారం: పరిమాణంతో పాటు సంఖ్యతో కూడా పరిమితం చేసిన పేజీలు
చరిత్ర పేజీ ఇప్పుడు 30 సందేశాలు లేదా వాటిలో దాదాపు 4 MB, ఏది ముందు వస్తే అది.
ఇది రెండు దశల్లో పనిచేస్తుంది:
- మొదట పరిమాణాలు అడగండి. API డేటాబేస్ను అత్యంత కొత్త సందేశాల IDలు మరియు నిల్వ చేసిన పరిమాణాలను, వాటి కంటెంట్ లేకుండా అడుగుతుంది. ఆ ప్రశ్న సందేశాలు ఎంత పెద్దవైనా చౌకగానే ఉంటుంది.
- సరిపోయేవి మాత్రమే లోడ్ చేయండి. కొత్త నుండి పాత వైపు నడుస్తూ, తర్వాతి సందేశం పేజీని 4 MB దాటేలా చేసే వరకు సందేశాలను జోడిస్తుంది. ఆ వరుసలు మాత్రమే పూర్తిగా లోడ్ అవుతాయి.
ఈ రెండు నియమాలు దీన్ని సురక్షితంగా ఉంచుతాయి:
- అత్యంత కొత్త సందేశం ఎప్పుడూ పేజీలో ఉంటుంది, దాని పరిమాణం ఎంతైనా. ఏమీ తిరిగి ఇవ్వని పేజీ చాట్ను ఇరుక్కుపోయేలా చేస్తుంది, వెనక్కి స్క్రోల్ చేసే మార్గం లేకుండా.
- ఏమీ కత్తిరించబడదు. ఏ సందేశమూ ట్రిమ్ చేయబడదు లేదా వదిలేయబడదు. మిగతా చాట్ “Scroll up for earlier messages” నియంత్రణ ద్వారా లోడ్ అవుతుంది, పాత సందేశాలు ఇప్పటికే ఉపయోగించిన దానిద్వారా, ఒక్కో పేజీ చొప్పున.
ఇదే ఆకారం ఉన్న మరో చోటును కూడా కనుగొన్నాం. ఒక టర్న్ ఆపినప్పుడు, API చివరి కొన్ని సమాధానాలు ఖాళీగా ఉన్నాయో లేదో, శుభ్రం చేయాలా అని తనిఖీ చేస్తుంది. అది ఎనిమిది పూర్తి సందేశాలను లోడ్ చేయడం ద్వారా చేసేది. మల్టీ-మెగాబైట్ సమాధానాలున్న చాట్పై, అది అదే సమస్యకు చిన్న రూపం. ఇప్పుడు అది డేటాబేస్ను ఒక అవును-కాదు ప్రశ్న అడుగుతుంది — ఈ సందేశంలో ఏదైనా కంటెంట్ ఉందా? — కంటెంట్ను లోడ్ చేయకుండానే.
మేము దీన్ని ఎలా తనిఖీ చేశాం
చాట్ కాపీపై, పాత 384 MiB పరిమితితో నడుపుతూ:
- మొదటి పేజీ 5 MB. ముందు, అదే అభ్యర్థన API ను క్రాష్ చేసింది.
- ఒకేసారి ఆ చాట్ను తెరిచే ఐదు బ్రౌజర్ ట్యాబ్లు 154 MB గరిష్ట మెమరీ చూపుతాయి.
- చాట్ మొత్తం వెనక్కి స్క్రోల్ చేస్తే మొత్తం 190 సందేశాలు తిరిగి వస్తాయి, ప్రతిది ఒకసారి, క్రమంగా.
పేజీ-ఎంపిక తర్కానికి యూనిట్ పరీక్షలు కూడా ఉన్నాయి, అందులో ఆ చాట్ యొక్క అత్యంత కొత్త సందేశాల నిజమైన పరిమాణాల నుండి నిర్మించిన ఒకటి కూడా ఉంది. మొదటి పేజీ ఒక సందేశంతో వస్తుంది, ఇంకా ఉన్నాయని చెబుతుంది, మరియు తదుపరి పేజీ దాని తర్వాతి దానితో మొదలవుతుంది.
మేము నేర్చుకున్నది
- సంఖ్య పరిమాణ పరిమితి కాదు. అనంతంగా పెరగగల దేనికైనా “అత్యంత కొత్త N” ఇచ్చే ఏ ఎండ్పాయింట్కైనా బైట్ బడ్జెట్ కూడా అవసరం. డేటా చివరికి ఆ గ్యాప్ను కనుగొంటుంది.
- స్పష్టమైన అనుమానితుడు ఎప్పుడూ కారణం కాదు. డిప్లాయ్ అదనపు పనికి నిజమైన ట్రిగ్గర్, మరియు ఎక్కువ మెమరీ విలువైనదే. కానీ క్రాష్ డిప్లాయ్ లేకుండానే పునరుత్పత్తి అయింది, మరియు దానిని పునరుత్పత్తి చేయకపోతే మెమరీ పెరుగుదల దగ్గరే ఆగిపోయేవాళ్లం.
- ఒక అభ్యర్థనను ఏ సర్వర్ తీసుకున్నా చంపితే, రెండు సర్వర్లు కలిసి విఫలమవుతాయి. రిడండెన్సీ ఒక సర్వర్ చనిపోవడం నుండి రక్షిస్తుంది. అది చేరిన ఏ సర్వర్నైనా చంపే అభ్యర్థన నుండి రక్షించదు, ముఖ్యంగా రిఫ్రెష్ చేయడం ద్వారా వినియోగదారు సహజంగా మళ్లీ ప్రయత్నించే అభ్యర్థన నుండి.
- కాన్ఫిగ్లో పరిష్కరించండి, కేవలం బాక్స్లో కాదు. అదే రోజు మెమరీ పెంపు డిప్లాయ్ కాన్ఫిగరేషన్లోకి వెళ్లింది, కాబట్టి తర్వాతి డిప్లాయ్ దానిని నిలుపుకుంది.
ఏజెంట్ అవుట్పుట్కు సంబంధించిన మా ఇటీవలి రెండో మెమరీ కథ ఇది. మొదటిది 690 MB స్ట్రింగ్స్ను క్యూలో పెట్టిన స్టేటస్ లేబుల్. Mythex లో సబ్-ఏజెంట్లను ఉపయోగిస్తే, అవి ఎలా పనిచేస్తాయో docs లో చదవవచ్చు.