നിങ്ങൾ file_exists($path) എന്ന് വിളിക്കുകയും $path ഒരു Amazon S3 ബക്കറ്റിലേക്ക് വിരൽ ചൂണ്ടുകയും ചെയ്യുന്നുവെങ്കിൽ, നിങ്ങൾ ഒരു ലോക്കൽ ഡിസ്കിലല്ല പ്രവർത്തിക്കുന്നത്—മറിച്ച് ഒരു നെറ്റ്‌വർക്ക് റിക്വസ്റ്റ് ആണ് നടത്തുന്നത്. ആ ഒറ്റവരി പരിശോധന S3-ലേക്ക് ഒരു റൗണ്ട്-ട്രിപ്പ് ആയി മാറുകയും ഓരോ റിക്വസ്റ്റിനും ഡസൻ കണക്കിന് മില്ലിസെക്കൻഡുകൾ അധികമായി കൂട്ടിച്ചേർക്കുകയും ചെയ്യുന്നു.

PHP റിമോട്ട് സ്റ്റോറിനെ സ്ട്രീം റാപ്പറുകൾക്ക് (stream wrappers) പിന്നിൽ ഒളിപ്പിച്ചു വെക്കുന്നു. fopen(), file_exists(), is_dir(), unlink(), file_put_contents() തുടങ്ങിയ ഫംഗ്ഷനുകൾ ഈ റാപ്പറുകളിലൂടെയാണ് പ്രവർത്തിക്കുന്നത്, ഇവ ഈ കോളുകളെ S3 API ഓപ്പറേഷനുകളായി മാറ്റുന്നു. ഇതിന്റെ മാപ്പിംഗ് ലളിതമാണ്:

  • file_exists()HeadObject
  • is_dir()ListObjects
  • unlink()DeleteObject
  • file_put_contents()PutObject

ഓരോ കോളും അതത് S3 API റിക്വസ്റ്റിന് തുല്യമായ ലേറ്റൻസി (latency) ഉണ്ടാക്കുന്നു. ഒരു സ്ക്രിപ്റ്റ് ഡസൻ കണക്കിന് ഫയലുകൾ പരിശോധിക്കുമ്പോൾ, അത് ഒരു N+1 ശൈലിയിലുള്ള പാറ്റേൺ സൃഷ്ടിക്കുന്നു: ഓരോ പരിശോധനയ്ക്കും ഓരോ നെറ്റ്‌വർക്ക് ഹോപ്പ് (network hop).

എന്തുകൊണ്ട് ഇത് ഇപ്പോൾ പ്രധാനമാകുന്നു

ഒരു സാധാരണ ഡെവലപ്‌മെന്റ് എൻവയോൺമെന്റിൽ ഫയൽസിസ്റ്റം ഒരേ മെഷീനിൽ തന്നെയായിരിക്കും, അതിനാൽ പരിശോധനകൾ ഉടനടി ഫലം നൽകുന്നു. എന്നാൽ അസറ്റുകൾ S3-യിൽ ഇരിക്കുന്ന പ്രൊഡക്ഷൻ സാഹചര്യത്തിൽ, ഇതേ കോഡ് പെർഫോമൻസ് വലിയ രീതിയിൽ കുറയ്ക്കുന്നു. AWS SDK ചില ഫലങ്ങൾ മെമ്മറിയിൽ കാഷെ (cache) ചെയ്യുന്നുണ്ട്, ഇത് ഒരു സിംഗിൾ 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() ഒരു എക്സ്റ്റേണൽ കോൾ ആയി പരിഗണിക്കുക, അതിന്റെ ഫലം കാഷെ ചെയ്യുക, കഠിനമായ ജോലികൾ റിക്വസ്റ്റ് പാത്തിൽ നിന്ന് മാറ്റുക. അല്ലാത്തപക്ഷം, ഓരോ അദൃശ്യ നെറ്റ്‌വർക്ക് റിക്വസ്റ്റിലൂടെയും മറഞ്ഞിരിക്കുന്ന ലേറ്റൻസി നിങ്ങളുടെ സൈറ്റിന്റെ വേഗത കുറച്ചുകൊണ്ടേയിരിക്കും.