మీరు file_exists($path)ని పిలిచినప్పుడు మరియు $path అనేది Amazon S3 బకెట్ను సూచిస్తున్నట్లయితే, మీరు లోకల్ డిస్క్ను యాక్సెస్ చేయడం లేదు—మీరు ఒక నెట్వర్క్ రిక్వెస్ట్ను పంపుతున్నారు. ఆ సింగిల్-లైన్ చెక్ S3కి ఒక రౌండ్-ట్రిప్గా మారి, ప్రతి రిక్వెస్ట్కు పదుల మిల్లీసెకన్ల ఆలస్యాన్ని (latency) జోడించవచ్చు.
PHP రిమోట్ స్టోర్ను స్ట్రీమ్ రాపర్స్ (stream wrappers) వెనుక దాచి ఉంచుతుంది. fopen(), file_exists(), is_dir(), unlink() మరియు file_put_contents() వంటి ఫంక్షన్లు ఈ రాపర్స్ ద్వారానే పనిచేస్తాయి, ఇవి ఆ కాల్స్ను S3 API ఆపరేషన్లుగా మారుస్తాయి. వాటి మ్యాపింగ్ ఇలా ఉంటుంది:
file_exists()→ HeadObjectis_dir()→ ListObjectsunlink()→ DeleteObjectfile_put_contents()→ PutObject
ప్రతి కాల్, దానికి సంబంధించిన S3 API రిక్వెస్ట్తో సమానమైన లాటెన్సీని కలిగి ఉంటుంది. ఒక స్క్రిప్ట్ డజన్ల కొద్దీ ఫైళ్లను చెక్ చేసినప్పుడు, అది N+1-స్టైల్ ప్యాటర్న్ను సృష్టిస్తుంది: ప్రతి చెక్కు ఒక నెట్వర్క్ హాప్ (network hop) అవసరమవుతుంది.
ఇది ఇప్పుడు ఎందుకు ముఖ్యం
సాధారణ డెవలప్మెంట్ ఎన్విరాన్మెంట్లో ఫైల్సిస్టమ్ అదే మెషీన్లో ఉంటుంది, కాబట్టి చెక్ దాదాపు తక్షణమే ఫలితాన్ని ఇస్తుంది. కానీ ప్రొడక్షన్లో, అసెట్స్ (assets) S3లో ఉన్నప్పుడు, అదే కోడ్ పెర్ఫార్మెన్స్ను గణనీయంగా తగ్గిస్తుంది. AWS SDK కొన్ని ఫలితాలను మెమరీలో క్యాష్ చేస్తుంది, దీనివల్ల ఒకే PHP ప్రాసెస్లో పదేపదే చేసే చెక్లు వేగంగా కనిపిస్తాయి. అయితే, చాలా PHP డిప్లాయ్మెంట్లు ప్రతి వెబ్ రిక్వెస్ట్కు ఒక కొత్త ప్రాసెస్ను ప్రారంభిస్తాయి, దీనివల్ల ప్రతిసారీ క్యాష్ క్లియర్ అవుతుంది. ఫలితంగా: ప్రతి రిక్వెస్ట్లోని ప్రతి విభిన్న పాత్కు ఒక పూర్తి నెట్వర్క్ రౌండ్-ట్రిప్ జరుగుతుంది.
ఒక WordPress సైట్ హోమ్పేజీని రెండర్ చేయడానికి ఒకసారి పది సెకన్ల సమయం తీసుకుంది. డేటాబేస్ క్వెరీస్ వేగంగానే ఉన్నాయి, కానీ కంటెంట్ను అసెంబుల్ చేయడానికి ఆ పేజీ 73 విడివిడి S3 కాల్స్ను ట్రిగ్గర్ చేసింది. ప్రతి కాల్ ఒక 'కోల్డ్ రిక్వెస్ట్' (cold request) కావడంతో, సాధారణంగా హానిలేని file_exists() కూడా గణనీయమైన ఆలస్యానికి కారణమైంది.
నివారణ వ్యూహాలు
- రిక్వెస్ట్ల మధ్య క్యాష్ను నిల్వ చేయడం (Persist cache across requests) – ఇన్-ప్రాసెస్ క్యాష్ను Redis వంటి షేర్డ్ స్టోర్కు మార్చండి. ఒక రిక్వెస్ట్ ఒక కీ S3లో ఉందని కనుగొన్నప్పుడు, తదుపరి రిక్వెస్ట్లు మళ్ళీ S3ని సంప్రదించకుండా క్యాష్ చేయబడిన ఫలితాన్ని చదువుతాయి.
- లోకల్-ఫస్ట్ వర్క్ఫ్లోను అనుసరించడం (Adopt a local-first workflow) – ఫైళ్లను లోకల్ డిస్క్లో వ్రాయండి, ఆపై వాటిని అసింక్రోనస్గా (asynchronously) S3కి సింక్ చేయండి. మెయిన్ రిక్వెస్ట్ పాత్ కేవలం లోకల్ ఫైల్సిస్టమ్ను మాత్రమే తాకుతుంది; నెట్వర్క్ ఖర్చు బ్యాక్గ్రౌండ్ జాబ్కు మారుతుంది.
- కోడ్బేస్ను ఆడిట్ చేయడం (Audit the codebase) – రిమోట్ రాపర్కు దారితీసే ఫైల్-సిస్టమ్ ఫంక్షన్ల కోసం క్రమబద్ధంగా వెతకండి. టైట్ లూప్స్ (tight loops) లేదా రిక్వెస్ట్-క్రిటికల్ పాత్లలో కనిపించే వాటిని గుర్తించండి.
- APM డేటాను పరిశీలించడం (Inspect APM data) – డేటాబేస్ మెట్రిక్స్ స్థిరంగా ఉన్నప్పటికీ రెస్పాన్స్ టైమ్ పెరిగితే, స్టోరేజ్ SDK టైమింగ్స్ను లోతుగా పరిశీలించండి. SDK లాటెన్సీలో అకస్మాత్తుగా పెరగడం అనేది తరచుగా దాగి ఉన్న S3 కాల్స్ను సూచిస్తుంది.
ముఖ్యమైన విషయం ఏమిటంటే: మైక్రోసెకన్ లోకల్ చెక్లా కనిపించే ఒక ఫంక్షన్, పదుల మిల్లీసెకన్ల నెట్వర్క్ లాటెన్సీని దాచిపెట్టవచ్చు. S3లో file_exists()ని ఒక ఎక్స్టర్నల్ కాల్గా పరిగణించండి, దాని ఫలితాన్ని క్యాష్ చేయండి మరియు భారీ పనులను (heavy lifting) రిక్వెస్ట్ పాత్ నుండి దూరంగా తరలించండి. లేకపోతే, ఈ దాగి ఉన్న లాటెన్సీ మీ సైట్ను ఒక్కో అదృశ్య నెట్వర్క్ రిక్వెస్ట్తో నిరంతరం నెమ్మదింపజేస్తూనే ఉంటుంది.
