మా సర్వర్లను స్తంభింపజేసిన తప్పిపోయిన స్వాప్ ఫైల్
సెప్టెంబర్ 24న, మా ప్రొడక్షన్ సర్వర్లలో ఒకటి స్పందించడం ఆపేసింది. లోడ్ బ్యాలెన్సర్ దాన్ని అనారోగ్యంగా గుర్తించింది, మరియు మా రిమోట్-కమాండ్ టూల్ దానిని చేరుకోలేకపోయింది — కానీ ఏదీ క్రాష్ కాలేదు, మరియు ఎక్కువ మెమరీ వాడినందుకు ఏదీ చంపబడలేదు. సర్వర్ థ్రాష్ అవుతోంది: స్వాప్ స్పేస్ లేదు, కంటైనర్లు యంత్రంలో ఉన్నదానికంటే ఎక్కువ మెమరీ వాడవచ్చు, కాబట్టి Linux తన సమయాన్ని రన్ చేయడానికి అవసరమైన ఫైళ్లను తొలగించి మళ్లీ చదవడంలో గడిపింది, దాదాపు ఏ పురోగతీ లేకుండా. ప్రతి సర్వర్పై 2 GB స్వాప్ ఫైల్ జోడించడంతో సమస్య పరిష్కారమైంది. ఇంకా ఆసక్తికరమైన పాఠం హెల్త్ చెక్ల గురించి.
“Hung” ఎలా కనిపించింది
- లోడ్ బ్యాలెన్సర్ హెల్త్ చెక్లు ఆ సర్వర్పై టైమ్అవుట్ అయ్యాయి.
- AWS Systems Manager ద్వారా పంపిన కమాండ్లు “Pending” లో ఉండిపోయి ఎప్పుడూ రన్ కాలేదు.
- లాగ్స్లో out-of-memory కిల్ లేదు. ఏ ప్రాసెస్ చనిపోలేదు.
ఒక వారం ముందు మేము ప్రొడక్షన్ను చిన్న ARM సర్వర్లకు మార్చాము, ఒక్కొక్కటికి 2 GB RAM. మా స్టేజింగ్ సర్వర్ — ఇంకా చిన్నది — ఒక డిప్లాయ్ సమయంలో కంటైనర్ ఇమేజ్ అన్ప్యాక్ చేస్తున్నప్పుడు అదే విధంగా స్తంభించింది.
మెమరీ ఎర్రర్ ఎందుకు లేదు?
Linux ఒక ప్రాసెస్ను చంపేది, అది నిజంగా రీక్లెయిమ్ చేయగల మెమరీ అయిపోయినప్పుడే. ఆ స్థాయికి ముందు, అది page cache నుంచి మెమరీని రీక్లెయిమ్ చేస్తుంది — RAM లో ఉంచే ఫైళ్ల కాపీలు, ప్రతి రన్ అవుతున్న ప్రోగ్రామ్ కోడ్తో సహా.
మా సర్వర్లపై, కంటైనర్ల సంయుక్త మెమరీ పరిమితులు సుమారు 1.8 GB ఉపయోగయోగ్య యంత్రంపై సుమారు 3.3 GB కు చేరాయి. సాధారణంగా అవన్నీ ఒకేసారి వాటి పరిమితిని వాడవు. వాడినప్పుడు, కెర్నల్ స్థలం కల్పించడానికి కాష్ నుంచి ప్రోగ్రామ్ కోడ్ను తొలగిస్తూనే ఉంది, ఆ కోడ్ మళ్లీ రన్ అయిన క్షణంలోనే డిస్క్ నుంచి తిరిగి చదవాల్సి వచ్చింది. ఆ చక్రం — థ్రాషింగ్ — మెమరీ అయిపోకుండానే యంత్రాన్ని దాదాపు పూర్తిగా స్పందించకుండా చేయగలదు. కాబట్టి ఏదీ చంపబడదు, మరియు ఏదీ కోలుకోదు.
స్వాప్ లేకుండా, కేటాయించబడిన కానీ అరుదుగా ఉపయోగించే మెమరీని ఉంచడానికి కెర్నల్కు స్థలం ఉండదు, కాబట్టి అది కాష్ నుంచి తీసుకోవాలి.
పరిష్కారం
సర్వర్ బూట్స్ట్రాప్ స్క్రిప్ట్ ఇప్పుడు ప్రతిసారి సర్వర్ బూట్ అయినప్పుడు లేదా మరమ్మత్తు చేయబడినప్పుడు తక్కువ swappiness సెట్టింగ్ (10) తో 2 GB స్వాప్ ఫైల్ను సృష్టిస్తుంది. తక్కువ swappiness అంటే కెర్నల్ ఇంకా పని మెమరీని RAMలో ఉంచడానికే ప్రాధాన్యత ఇస్తుంది, కానీ అరుదుగా తాకబడిన పేజీలు ప్రోగ్రామ్ కోడ్ను కాష్ నుంచి బలవంతంగా తొలగించే బదులు డిస్క్కు వెళ్లవచ్చు. మేము రెండు ప్రొడక్షన్ సర్వర్లు మరియు స్టేజింగ్కు లైవ్గా వర్తింపజేశాము, మరియు ప్రతి ప్రొడక్షన్ డిప్లాయ్లో డిప్లాయ్ పైప్లైన్ బూట్స్ట్రాప్ స్క్రిప్ట్ను మళ్లీ ప్రచురిస్తుంది, కాబట్టి మార్చబడిన సర్వర్కు కూడా అది వస్తుంది.
మమ్మల్ని ఎక్కువ ఆందోళనకు గురిచేసింది: అనారోగ్య సర్వర్ అలాగే ఉండిపోయింది
మా సర్వర్ గ్రూప్ EC2 హెల్త్ చెక్లు ఉపయోగించింది — “యంత్రం రన్ అవుతోందా?” — లోడ్ బ్యాలెన్సర్ హెల్త్ చెక్లు కాదు — “అది అభ్యర్థనలకు స్పందిస్తోందా?”. కాబట్టి లోడ్ బ్యాలెన్సర్ వదిలేసిన సర్వర్ గ్రూప్ దృష్టిలో ఇంకా ఆరోగ్యంగా ఉంది. అది ఎప్పుడూ భర్తీ చేయబడదు. ఎవరో గమనించి ఒకదాన్ని రీబూట్ చేసే వరకు ప్రొడక్షన్ నిశ్శబ్దంగా ఒకే సర్వర్పై నడుస్తూ ఉండేది.
గ్రూప్ను లోడ్-బ్యాలెన్సర్ హెల్త్ చెక్లకు మార్చడం స్పష్టమైన పరిష్కారంలా అనిపిస్తుంది, కానీ మాకు అది సులభం కాదు: డిప్లాయ్ సమయంలో, సర్వర్లు ఉద్దేశపూర్వకంగా తమ హెల్త్ ఎండ్పాయింట్కు ఎర్రర్తో స్పందిస్తాయి, తద్వారా బ్యాలెన్సర్ వాటిని డ్రెయిన్ చేస్తుంది (చూడండి మేము డిప్లాయ్లను జీరో 502లకు ఎలా తీసుకొచ్చాము). ఆ సిగ్నల్పై సర్వర్లను భర్తీ చేసే గ్రూప్ ప్రతి డిప్లాయ్ మధ్యలో వాటిని భర్తీ చేస్తుంది.
కాబట్టి ఇప్పుడు, మేము మా డిప్లాయ్ చెక్లిస్ట్లో ఒక దశ జోడించాము: ప్రతి డిప్లాయ్ తర్వాత, డిప్లాయ్ జాబ్ పాస్ అయిందా అని మాత్రమే కాకుండా, లోడ్ బ్యాలెన్సర్పై ప్రతి టార్గెట్ హెల్త్ను తనిఖీ చేయాలి. ఒక సర్వర్కు కమాండ్లు “Pending” లో ఉంటే, అది థ్రాష్ అవుతోంది — రీబూట్ చేయండి; అది ఇప్పటికే రొటేషన్ నుంచి బయట ఉంది.
మేము ఏమి నేర్చుకున్నాము
- “క్రాష్ అవ్వకపోవడం” అంటే “ఆరోగ్యంగా ఉండటం” కాదు. థ్రాషింగ్ ఎలాంటి ఎర్రర్ ఇవ్వదు, కేవలం యంత్రం స్పందించడం ఆగిపోయేంత తీవ్రమైన నెమ్మదితనం మాత్రమే.
- చిన్న సర్వర్లకు స్వాప్ అవసరం. కొద్దిగానైనా, తక్కువ swappiness తో, కెర్నల్కు చల్లని మెమరీని ఉంచడానికి స్థలం ఇస్తుంది.
- మెమరీ పరిమితులు యంత్రం కంటే ఎక్కువగా కలిపితే, అది ఒక పందెం. కొన్నిసార్లు మీరు ఓడిపోతారు. మీరు పందెం కట్టారని తెలుసుకోండి.
- మీ ఆటోస్కేలింగ్ ఏ హెల్త్ చెక్ను నమ్ముతుందో తెలుసుకోండి. VM ఆన్లో ఉందా అని మాత్రమే అడిగే హెల్త్ చెక్ పనిచేయడం ఆగిపోయిన సర్వర్ను భర్తీ చేయదు.