ਜੇਕਰ ਤੁਸੀਂ file_exists($path) ਨੂੰ ਕਾਲ ਕਰਦੇ ਹੋ ਅਤੇ $path ਇੱਕ Amazon S3 bucket ਵੱਲ ਇਸ਼ਾਰਾ ਕਰਦਾ ਹੈ, ਤਾਂ ਤੁਸੀਂ ਕਿਸੇ ਲੋਕਲ ਡਿਸਕ (local disk) ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕਰ ਰਹੇ—ਬਲਕਿ ਤੁਸੀਂ ਇੱਕ ਨੈੱਟਵਰਕ ਰਿਕਵੈਸਟ (network request) ਕਰ ਰਹੇ ਹੋ। ਇਹ ਸਿੰਗਲ-ਲਾਈਨ ਚੈੱਕ S3 ਲਈ ਇੱਕ round-trip ਬਣ ਜਾਂਦਾ ਹੈ ਜੋ ਹਰ ਰਿਕਵੈਸਟ ਵਿੱਚ ਦਸਾਂ ਮਿਲੀਸੈਕਿੰਡ (milliseconds) ਵਾਧਾ ਕਰ ਸਕਦਾ ਹੈ।

PHP ਰਿਮੋਟ ਸਟੋਰ ਨੂੰ stream wrappers ਦੇ ਪਿੱਛੇ ਛੁਪਾਉਂਦਾ ਹੈ। fopen(), file_exists(), is_dir(), unlink() ਅਤੇ file_put_contents() ਵਰਗੇ ਫੰਕਸ਼ਨ ਇਹਨਾਂ wrappers ਰਾਹੀਂ ਚੱਲਦੇ ਹਨ, ਜੋ ਇਹਨਾਂ ਕਾਲਾਂ ਨੂੰ S3 API operations ਵਿੱਚ ਬਦਲ ਦਿੰਦੇ ਹਨ। ਇਹ ਮੈਪਿੰਗ ਬਹੁਤ ਸਿੱਧੀ ਹੈ:

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

ਹਰ ਕਾਲ ਵਿੱਚ ਉਨੀ ਹੀ ਲੇਟੈਂਸੀ (latency) ਆਉਂਦੀ ਹੈ ਜਿੰਨੀ ਕਿ ਉਸਦੇ ਸੰਬੰਧਿਤ S3 API ਰਿਕਵੈਸਟ ਵਿੱਚ। ਜਦੋਂ ਕੋਈ ਸਕ੍ਰਿਪਟ ਦਰਜਨਾਂ ਫਾਈਲਾਂ ਦੀ ਜਾਂਚ ਕਰਦੀ ਹੈ, ਤਾਂ ਇਹ N+1-ਸਟਾਈਲ ਪੈਟਰਨ ਬਣਾਉਂਦੀ ਹੈ: ਹਰ ਇੱਕ ਚੈੱਕ ਲਈ ਇੱਕ ਨੈੱਟਵਰਕ ਹੌਪ (network hop)।

ਇਹ ਹੁਣ ਕਿਉਂ ਮਹੱਤਵਪੂਰਨ ਹੈ

ਇੱਕ ਆਮ ਡਿਵੈਲਪਮੈਂਟ ਮਾਹੌਲ (development environment) ਵਿੱਚ ਫਾਈਲਸਿਸਟਮ (filesystem) ਉਸੇ ਮਸ਼ੀਨ 'ਤੇ ਹੁੰਦਾ ਹੈ, ਇਸ ਲਈ ਚੈੱਕ ਲਗਭਗ ਤੁਰੰਤ ਨਤੀਜਾ ਦਿੰਦਾ ਹੈ। ਪਰ ਪ੍ਰੋਡਕਸ਼ਨ (production) ਵਿੱਚ, ਜਿੱਥੇ ਐਸੇਟਸ (assets) S3 'ਤੇ ਹੁੰਦੇ ਹਨ, ਉਹੀ ਕੋਡ ਪਰਫਾਰਮੈਂਸ ਵਿੱਚ ਵੱਡੀ ਗਿਰਾਵਟ (performance cliff) ਲਿਆ ਸਕਦਾ ਹੈ। AWS SDK ਕੁਝ ਨਤੀਜਿਆਂ ਨੂੰ ਮੈਮੋਰੀ ਵਿੱਚ ਕੈਸ਼ (cache) ਕਰਦਾ ਹੈ, ਜਿਸ ਨਾਲ ਇੱਕ ਸਿੰਗਲ PHP ਪ੍ਰੋਸੈਸ ਵਿੱਚ ਵਾਰ-ਵਾਰ ਕੀਤੇ ਗਏ ਚੈੱਕ ਤੇਜ਼ ਲੱਗਦੇ ਹਨ। ਹਾਲਾਂਕਿ, ਜ਼ਿਆਦਾਤਰ PHP ਡਿਪਲਾਈਮੈਂਟਸ ਹਰ ਵੈੱਬ ਰਿਕਵੈਸਟ ਲਈ ਇੱਕ ਨਵਾਂ ਪ੍ਰੋਸੈਸ ਸ਼ੁਰੂ ਕਰਦੇ ਹਨ, ਜਿਸ ਨਾਲ ਹਰ ਵਾਰ ਕੈਸ਼ ਸਾਫ਼ ਹੋ ਜਾਂਦਾ ਹੈ। ਨਤੀਜਾ: ਹਰ ਰਿਕਵੈਸਟ 'ਤੇ ਹਰ ਵੱਖਰੇ ਪਾਥ (path) ਲਈ ਇੱਕ ਪੂਰਾ ਨੈੱਟਵਰਕ round-trip।

ਇੱਕ ਵਾਰ ਇੱਕ WordPress ਸਾਈਟ ਨੂੰ ਆਪਣਾ ਹੋਮਪੇਜ ਰੈਂਡਰ (render) ਕਰਨ ਵਿੱਚ ਦਸ ਸੈਕਿੰਡ ਲੱਗੇ ਸਨ। ਡੇਟਾਬੇਸ ਕੁਏਰੀਆਂ (database queries) ਤੇਜ਼ ਸਨ, ਪਰ ਸਿਰਫ਼ ਕੰਟੈਂਟ ਇਕੱਠਾ ਕਰਨ ਲਈ ਪੇਜ ਨੇ 73 ਵੱਖ-ਵੱਖ S3 ਕਾਲਾਂ ਕੀਤੀਆਂ। ਹਰ ਕਾਲ ਇੱਕ 'cold request' ਸੀ, ਜਿਸ ਨੇ ਇੱਕ ਮਾਮੂਲੀ ਲੱਗਣ ਵਾਲੇ file_exists() ਨੂੰ ਇੱਕ ਵੱਡੀ ਦੇਰੀ ਵਿੱਚ ਬਦਲ ਦਿੱਤਾ।

ਘਟਾਉਣ ਦੀਆਂ ਰਣਨੀਤੀਆਂ

  • ਰਿਕਵੈਸਟਾਂ ਦਰਮਿਆਨ ਕੈਸ਼ ਨੂੰ ਬਰਕਰਾਰ ਰੱਖੋ (Persist cache across requests) – ਇਨ-ਪ੍ਰੋਸੈਸ ਕੈਸ਼ ਨੂੰ Redis ਵਰਗੇ ਸਾਂਝੇ ਸਟੋਰ (shared store) ਵਿੱਚ ਬਦਲੋ। ਜਦੋਂ ਇੱਕ ਰਿਕਵੈਸਟ ਨੂੰ ਪਤਾ ਲੱਗਦਾ ਹੈ ਕਿ ਕੋਈ ਕੀ (key) S3 'ਤੇ ਮੌਜੂਦ ਹੈ, ਤਾਂ ਅਗਲੀਆਂ ਰਿਕਵੈਸਟਾਂ S3 ਨਾਲ ਦੁਬਾਰਾ ਸੰਪਰਕ ਕਰਨ ਦੀ ਬਜਾਏ ਕੈਸ਼ ਕੀਤੇ ਹੋਏ ਨਤੀਜੇ ਨੂੰ ਪੜ੍ਹਦੀਆਂ ਹਨ।
  • ਲੋਕਲ-ਫਸਟ ਵਰਕਫਲੋ (local-first workflow) ਅਪਣਾਓ – ਫਾਈਲਾਂ ਨੂੰ ਲੋਕਲ ਡਿਸਕ 'ਤੇ ਲਿਖੋ, ਫਿਰ ਉਹਨਾਂ ਨੂੰ ਅਸਿੰਕਰੋਣ ਤੌਰ 'ਤੇ (asynchronously) S3 ਨਾਲ ਸਿੰਕ ਕਰੋ। ਮੁੱਖ ਰਿਕਵੈਸਟ ਪਾਥ ਸਿਰਫ਼ ਲੋਕਲ ਫਾਈਲਸਿਸਟਮ ਨੂੰ ਹੀ ਛੂਹਦਾ ਹੈ; ਨੈੱਟਵਰਕ ਦੀ ਲਾਗਤ ਬੈਕਗ੍ਰਾਊਂਡ ਜੌਬ (background job) ਵਿੱਚ ਚਲੀ ਜਾਂਦੀ ਹੈ।
  • ਕੋਡਬੇਸ ਦੀ ਜਾਂਚ (Audit the codebase) ਕਰੋ – ਵਿਵਸਥਿਤ ਤਰੀਕੇ ਨਾਲ ਉਹਨਾਂ ਫਾਈਲ-ਸਿਸਟਮ ਫੰਕਸ਼ਨਾਂ ਦੀ ਭਾਲ ਕਰੋ ਜੋ ਰਿਮੋਟ ਵੈਪਰ (remote wrapper) ਵਿੱਚ ਬਦਲ ਸਕਦੇ ਹਨ। ਉਹਨਾਂ ਨੂੰ ਫਲੈਗ ਕਰੋ ਜੋ ਟਾਈਟ ਲੂਪਸ (tight loops) ਜਾਂ ਰਿਕਵੈਸਟ-ਕ੍ਰਿਟੀਕਲ ਪਾਥਾਂ ਦੇ ਅੰਦਰ ਦਿਖਾਈ ਦਿੰਦੇ ਹਨ।
  • APM ਡੇਟਾ ਦੀ ਜਾਂਚ ਕਰੋ – ਜੇਕਰ ਡੇਟਾਬੇਸ ਮੈਟ੍ਰਿਕਸ ਸਥਿਰ ਰਹਿਣ ਦੇ ਬਾਵਜੂਦ ਰਿਸਪਾਂਸ ਟਾਈਮ ਵਧਦਾ ਹੈ, ਤਾਂ ਸਟੋਰੇਜ SDK ਟਾਈਮਿੰਗਜ਼ ਦੀ ਡੂੰਘਾਈ ਨਾਲ ਜਾਂਚ ਕਰੋ। SDK ਲੇਟੈਂਸੀ ਵਿੱਚ ਅਚਾਨਕ ਵਾਧਾ ਅਕਸਰ ਲੁਕੀਆਂ ਹੋਈਆਂ S3 ਕਾਲਾਂ ਵੱਲ ਇਸ਼ਾਰਾ ਕਰਦਾ ਹੈ।

ਮੁੱਖ ਗੱਲ: ਇੱਕ ਫੰਕਸ਼ਨ ਜੋ ਮਾਈਕਰੋਸਕਿੰਡ ਲੋਕਲ ਚੈੱਕ ਵਾਂਗ ਲੱਗਦਾ ਹੈ, ਉਹ ਦਸਾਂ ਮਿਲੀਸੈਕਿੰਡ ਦੀ ਨੈੱਟਵਰਕ ਲੇਟੈਂਸੀ ਨੂੰ ਛੁਪਾ ਸਕਦਾ ਹੈ। S3 'ਤੇ file_exists() ਨੂੰ ਇੱਕ ਬਾਹਰੀ ਕਾਲ ਵਜੋਂ ਮੰਨੋ, ਇਸਦੇ ਨਤੀਜੇ ਨੂੰ ਕੈਸ਼ ਕਰੋ, ਅਤੇ ਭਾਰੀ ਕੰਮ (heavy lifting) ਨੂੰ ਰਿਕਵੈਸਟ ਪਾਥ ਤੋਂ ਬਾਹਰ ਕੱਢੋ। ਨਹੀਂ ਤਾਂ, ਲੁਕੀ ਹੋਈ ਲੇਟੈਂਸੀ ਤੁਹਾਡੀ ਸਾਈਟ ਨੂੰ ਇੱਕ ਸਮੇਂ 'ਤੇ ਇੱਕ ਅਦਿੱਖ ਨੈੱਟਵਰਕ ਰਿਕਵੈਸਟ ਨਾਲ ਹੌਲੀ ਕਰਦੀ ਰਹੇਗੀ।