நீங்கள் file_exists($path) என்பதை அழைத்தால் மற்றும் $path என்பது ஒரு Amazon S3 bucket-ஐக் குறித்தால், நீங்கள் ஒரு உள்ளூர் வன்வட்டை (local disk) அணுகவில்லை—நீங்கள் ஒரு நெட்வொர்க் கோரிக்கையை (network request) செய்கிறீர்கள். அந்த ஒற்றை வரிச் சரிபார்ப்பு, S3-க்கு ஒரு round-trip ஆக மாறி, ஒவ்வொரு கோரிக்கைக்கும் பல மில்லி விநாடிகளைச் சேர்க்கக்கூடும்.
PHP, தொலைதூரச் சேமிப்பகத்தை (remote store) stream wrappers மூலம் மறைத்து வைக்கிறது. fopen(), file_exists(), is_dir(), unlink() மற்றும் file_put_contents() போன்ற செயல்பாடுகள் இந்த wrappers வழியாகவேச் செல்கின்றன, இவை அந்த அழைப்புகளை S3 API செயல்பாடுகளாக மாற்றுகின்றன. அதன் வரைபடம் (mapping) எளிமையானது:
file_exists()→ HeadObjectis_dir()→ ListObjectsunlink()→ DeleteObjectfile_put_contents()→ PutObject
ஒவ்வொரு அழைப்பும் அதற்குரிய S3 API கோரிக்கைக்கு இணையான தாமதத்தையே (latency) ஏற்படுத்துகிறது. ஒரு ஸ்கிரிப்ட் டஜன் கணக்கான கோப்புகளைச் சரிபார்க்கும்போது, அது N+1-பாணியிலான முறையை உருவாக்குகிறது: ஒவ்வொரு சரிபார்ப்பிற்கும் ஒரு நெட்வொர்க் தாவல் (network hop) தேவைப்படுகிறது.
இது இப்போது ஏன் முக்கியமானது
ஒரு சாதாரண மேம்பாட்டுச் சூழலில் (development environment), கோப்பு முறைமை (filesystem) அதே இயந்திரத்தில் இருப்பதால், சரிபார்ப்பு கிட்டத்தட்ட உடனடியாக முடிந்துவிடும். ஆனால், சொத்துக்கள் (assets) S3-இல் இருக்கும் தயாரிப்புச் சூழலில் (production), அதே குறியீடு செயல்திறன் சரிவை (performance cliff) ஏற்படுத்துகிறது. AWS SDK சில முடிவுகளை நினைவகத்தில் (memory) சேமித்து வைப்பதால் (cache), ஒரே PHP செயல்முறையில் (process) மீண்டும் மீண்டும் செய்யப்படும் சரிபார்ப்புகள் வேகமாகத் தோன்றலாம். இருப்பினும், பெரும்பாலான PHP வரிசைப்படுத்தல்களில் (deployments), ஒவ்வொரு இணையக் கோரிக்கைக்கும் ஒரு புதிய செயல்முறை உருவாக்கப்பட்டு, ஒவ்வொரு முறையும் cache அழிக்கப்படுகிறது. இதன் விளைவாக: ஒவ்வொரு கோரிக்கைக்கும் ஒவ்வொரு தனித்துவமான பாதையிலும் (path) ஒரு முழுமையான நெட்வொர்க் round-trip நிகழ்கிறது.
ஒரு WordPress தளம் அதன் முகப்புப் பக்கத்தை (homepage) காண்பிக்க ஒருமுறை பத்து விநாடிகள் எடுத்துக்கொண்டது. தரவுத்தளக் கோரிக்கைகள் (Database queries) விரைவாக இருந்தன, ஆனால் பக்கத்தின் உள்ளடக்கத்தை ஒருங்கிணைக்க மட்டுமே அந்தப் பக்கம் 73 தனிப்பட்ட S3 அழைப்புகளைத் தூண்டியது. ஒவ்வொரு அழைப்பும் ஒரு cold request ஆக இருந்ததால், பார்ப்பதற்குப் பாதிப்பற்றதாகத் தோன்றும் file_exists() ஒரு குறிப்பிடத்தக்கத் தாமதமாக மாறியது.
தணிப்பு உத்திகள் (Mitigation strategies)
- கோரிக்கைகளுக்கு இடையேயான cache-ஐத் தக்கவைத்தல் – செயல்முறைக்குள் இருக்கும் cache-ஐ Redis போன்ற ஒரு பகிரப்பட்ட சேமிப்பகத்திற்கு (shared store) மாற்றவும். ஒரு கோரிக்கை ஒரு key S3-இல் இருப்பதை கண்டறியும்போது, அடுத்தடுத்த கோரிக்கைகள் மீண்டும் S3-ஐத் தொடர்பு கொள்ளாமல், சேமிக்கப்பட்ட (cached) முடிவை வாசிக்கும்.
- உள்ளூர் சார்ந்த பணிப்பாய்வைப் (local-first workflow) பின்பற்றுதல் – கோப்புகளை உள்ளூர் வன்வட்டில் (local disk) எழுதி, பின்னர் அவற்றை S3-க்கு asynchronous முறையில் ஒத்திசைக்கவும் (sync). முக்கியக் கோரிக்கைப் பாதை உள்ளூர் கோப்பு முறைமையை மட்டுமே அணுகும்; நெட்வொர்க் செலவு ஒரு பின்னணிப் பணிக்கு (background job) மாற்றப்படும்.
- குறியீட்டுத் தொகுப்பை (codebase) ஆய்வு செய்தல் – தொலைதூர wrapper-க்கு வழிவகுக்கக்கூடிய கோப்பு முறைமைச் செயல்பாடுகளை முறையாகத் தேடவும். சுழற்சிகளுக்குள் (loops) அல்லது கோரிக்கை சார்ந்த முக்கியமான பாதைகளில் (request-critical paths) தோன்றும் செயல்பாடுகளைக் கண்டறியவும்.
- APM தரவை ஆய்வு செய்தல் – தரவுத்தள அளவீடுகள் (database metrics) நிலையாக இருக்கும்போது, பதிலளிக்கும் நேரம் (response time) திடீரென அதிகரித்தால், storage SDK நேரத்தைக் கவனியுங்கள். SDK தாமதம் திடீரென அதிகரிப்பது பெரும்பாலும் மறைமுகமான S3 அழைப்புகளைக் குறிக்கிறது.
முக்கியக் கருத்து: ஒரு மைக்ரோ விநாடி உள்ளூர் சரிபார்ப்பு போலத் தோன்றும் ஒரு செயல்பாடு, பல மில்லி விநாடிகள் நெட்வொர்க் தாமதத்தை மறைத்து வைத்திருக்கக்கூடும். S3-இல் file_exists() என்பதை ஒரு வெளிப்புற அழைப்பாகக் கருதி, அதன் முடிவை cache செய்து, கடினமான பணிகளை கோரிக்கைப் பாதையிலிருந்து (request path) வெளியேற்றவும். இல்லையெனில், மறைமுகமான தாமதங்கள் ஒவ்வொரு கண்ணுக்குத் தெரியாத நெட்வொர்க் கோரிக்கை மூலமாகவும் உங்கள் தளத்தின் வேகத்தைக் குறைத்துக் கொண்டே இருக்கும்.
