24.2
প্রতিটি স্তরে Caching
edge, API, অ্যাপ্লিকেশন, ডেটাবেস আর session-এ caching, আর প্রতিটার লাভ-ক্ষতি।
18 মিনিট পড়া + Animation
টিপস: ডটেড-আন্ডারলাইন করা যেকোনো শব্দে ট্যাপ বা Hover করলে তার অর্থ দেখবে।
এই লেসন শেষে তুমি পারবে
- একটা সাধারণ AWS application-এর পুরো caching-এর পথ এঁকে ফেলতে (client → CloudFront → API Gateway → Lambda বা EC2 → ElastiCache বা DAX → database, আর CloudFront-এর পেছনে S3), আর বলতে কোন স্তর কী cache করে।
- প্রতিটা স্তরের পেছনের একটাই লাভ-ক্ষতির হিসাব বুঝিয়ে বলতে: user-এর যত কাছে cache, প্রতিটা request তত দ্রুত আর সস্তা, কিন্তু কপিটা মুছে নতুন করা তত কঠিন, আর সেটা তত বেশি পুরোনো (stale) হতে পারে।
- প্রতিটা স্তরের TTL আর invalidation সেট করতে ও তা নিয়ে যুক্তি দিতে: CloudFront-এর TTL আর invalidation, API Gateway-র stage cache (শুধু REST, TTL, cache key,
Cache-Control: max-age=0দিয়ে client-এর bypass), ElastiCache-এর TTL আর লেখার সময় key মুছে দেওয়া, DAX-এর item TTL। - কখন একটা cache টাকা বাঁচায় আর কখন শুধু একটা নতুন bill যোগ করে, তা ঠিক করতে।
- এই পথে lazy loading, write-through নাকি দুটোই, তা বাছতে, আর কোন ডেটা কখনো cache করা যাবে না, তার নাম বলতে।
- DAX নাকি ElastiCache বাছতে, আর session state-কে web tier-এর বাইরে রাখতে।
- পরীক্ষার scenario-র keyword পড়ে বলতে, কোন caching স্তর চাওয়া হচ্ছে।
#সব স্তরেই cache কেন
আগের অধ্যায়গুলোতে একটা একটা করে cache শিখেছ: লেসন ১১.১-এ CloudFront, লেসন ৭.৫-এ ElastiCache, লেসন ১৫.৫-এ DAX, লেসন ১৫.৬-এ API Gateway-র stage cache। এই লেসনে সেগুলো আবার শেখানো হবে না। এখানে সবগুলোকে একটাই request-এর পথে বসিয়ে architect-এর প্রশ্নগুলো করা হবে: কোন request-এর উত্তর কোন স্তর দেবে, প্রতিটা কপি কতক্ষণ বাঁচবে, চারটা cache পেরোতে গিয়ে একটা দামের পরিবর্তনের কী হয়, আর কোন ডেটা কোথাও cache করাই চলবে না।
AWS-এ নানা স্তরে caching করা হয় তিনটা কারণে, আর পরীক্ষায় তিনটা শব্দই আসে: application-কে দ্রুত করা (latency কমানো), database আর তার পেছনের compute-এর চাপ কমানো, আর খরচ বাঁচানো।
#একটা flash sale-এর request কোন পথে যায়
ধরো Daraz-ধাঁচের একটা shop, ১১.১১ flash sale-এর রাত। ঢাকা, চট্টগ্রাম আর সিলেট থেকে shopper-রা app খুলছে; shop চলছে Singapore Region-এ।
| স্তর | Service | কী cache করতে পারে | সাধারণ TTL |
|---|---|---|---|
| Edge | CloudFront | ছবি, CSS/JS, পুরো page, এমনকি API response, shopper-এর কাছের একটা PoP-এ | কয়েক সেকেন্ড থেকে এক বছর; default ২৪ ঘণ্টা |
| API | API Gateway stage cache | REST API method-এর response (default-এ শুধু GET) | default ৩০০ s, সর্বোচ্চ ৩,৬০০ s |
| Application | ElastiCache (Valkey, Redis OSS, Memcached) | তোমার code যা রাখে: query-র ফল, বানানো page, session | প্রতিটা key-তে তুমি ঠিক করো |
| Database | DynamoDB-র জন্য DAX; RDS-এর জন্য read replica | DynamoDB-র item আর query-র ফল; RDS database-এর পড়ার কপি | DAX item: default ৫ মিনিট |
| Storage | CloudFront-এর পেছনে S3 | Edge যে static file cache করে, তার origin | (origin, cache নয়) |
#একটাই হিসাব: কাছে মানে দ্রুত, দূরে মানে টাটকা
পুরো ছবিটা ছয়টা শব্দে: caching, TTL, network, computation, cost, latency। প্রতিটা স্তর এগুলোকে একই দিকে কাটাকাটি করে:
- User-এর যত কাছে (edge): request-টাকে Region পর্যন্ত network-এর যাত্রা, পেছনের সব computation আর database query, কিছুই করতে হয় না। Latency সবচেয়ে কম, প্রতি request-এর খরচও সবচেয়ে কম। কিন্তু কপিটা ছড়িয়ে থাকে শত শত জায়গায়, তাই সেটা মুছে নতুন করা সবচেয়ে কঠিন, আর সেটাই হতে পারে সবচেয়ে পুরোনো।
- Database-এর যত কাছে (ElastiCache, DAX): প্রতিটা request-কে সামনের network আর compute-এর দাম দিতেই হয়, কিন্তু cache থাকে একটা জায়গায়, তোমার code-এর হাতে, তাই একটা key মুছতে একটা command-ই যথেষ্ট, আর ডেটা প্রায় টাটকা রাখা যায়।
- Stale-এর সময় যোগ হয়। API cache যদি একটা response ৬০ s রাখে, আর যে Valkey key থেকে সেটা বানানো তার TTL-ও ৬০ s হয়, তাহলে একজন shopper পুরোনো দাম প্রায় দুই মিনিট দেখতে পারে। সবচেয়ে খারাপ ক্ষেত্রে সময়টা হলো যত স্তর কপি রাখে, তাদের সবার TTL-এর যোগফল।
তাই প্রতিটা রকমের ডেটার জন্য design-এর প্রশ্ন একটাই: পথের কত ওপর পর্যন্ত এটা যেতে পারে, যতক্ষণ না এর পুরোনো হওয়াটা ক্ষতি করে? Product-এর ছবি edge পর্যন্ত যেতে পারে; product list API-তে এক মিনিট বসে থাকতে পারে; দাম Valkey-তে থাকতে পারে, যদি বদলালেই key মুছে দাও; আর শেষ ৪০টা phone-এর stock-এর সংখ্যা কোথাও cache করা যায় না।
একটাই request-এর পথ, cache রাখার চারটা জায়গা
একটা flash-sale shop: shopper-রা ঢাকায়, application Singapore Region-এ। একটা product-এর ছবি, একটা product list, পুরো miss, দাম বদলানো আর stock-এর সংখ্যা, একে একে দেখো কোন স্তর কোনটার উত্তর দেয়।
পরিস্থিতি
Static file shopper-এর কয়েক millisecond দূর থেকেই উত্তর পায়, Region পর্যন্ত যায়ই না।
সকালের প্রথম shopper একটা product-এর ছবি চাইল। কাছের PoP-এ এখনো ছবিটা নেই (miss), তাই CloudFront সেটা Regional Edge Cache হয়ে S3 bucket থেকে আনে; OAC থাকায় bucket private-ই থাকে।
#প্রথম স্তর: edge (CloudFront)
আগে যা শিখেছ (লেসন ১১.১ আর ১১.২): CloudFront হলো AWS-এর global CDN। User-এর কাছাকাছি ৭৫০-এর বেশি edge location-এ (PoP) সে কপি রাখে, আর তাদের পেছনে আছে বড় বড় Regional Edge Cache। Request-এর উত্তর দেয় সবচেয়ে কাছের PoP; শুধু miss হলে request origin-এ ফেরে (S3, একটা ALB, EC2, API Gateway বা যেকোনো HTTP server)।
পুরো পথের হিসাবে যেগুলো জরুরি:
- TTL। একটা কপি কতক্ষণ টাটকা ধরা হবে, তারপর CloudFront আবার origin-কে জিজ্ঞেস করবে। Origin-এর
Cache-Control: max-ageএটা ঠিক করে, cache policy-র minimum আর maximum TTL-এর ভেতরে; কোনো header না থাকলে default TTL ২৪ ঘণ্টা (৮৬,৪০০ s)। TTL শেষ হলে CloudFront revalidate করে বা নতুন version নিয়ে আসে। - Cache key। Default-এ domain আর URL path। Cache policy দিয়ে এতে যোগ করো ঠিক সেই query string, header আর cookie, যেগুলো response বদলায়, এর বেশি একটাও না: দরকারি একটা বাদ পড়লে ভুল কপি যায়, বাড়তি একটা ঢুকলে hit ratio ধসে পড়ে।
- Path ধরে behaviour।
/img/*-এর static file-এ লম্বা TTL-এর policy, যেমন CachingOptimized; dynamic/api/*-এ সাধারণত CachingDisabled, তাই edge request সামনে পাঠিয়ে দেয়। তখনো edge কাজে লাগে: TLS শেষ হয় user-এর কাছেই, আর request চলে AWS-এর network ধরে। - Invalidation।
create-invalidationTTL শেষ হওয়ার আগেই সব edge থেকে path মুছে দেয়। মাসে প্রথম ১,০০০টা path বিনা পয়সায়, তারপর প্রতি path ০.০০৫ USD (wildcard-ওয়ালা path একটাই গোনা হয়)। যে file বদলায়, তার জন্য ভালো অভ্যাস হলো নামে version রাখা (banner-v2.jpg,app.3f9a1c.js): নতুন নাম মানে নতুন cache key, মোছার কিছু নেই, আর browser-এর cache-কেও হারিয়ে দেয়, যেখানে invalidation পৌঁছাতেই পারে না। - CloudFront-এর পেছনে S3। Bucket private রাখো, আর শুধু distribution-কে পড়তে দাও Origin Access Control (OAC) দিয়ে। AWS-এর origin থেকে CloudFront-এ ডেটা যাওয়া বিনা পয়সায়, তাই S3-কে CloudFront দিয়ে serve করা সাধারণত দ্রুত তো বটেই, সস্তাও।
#দ্বিতীয় স্তর: API (API Gateway-র stage cache)
আগে যা শিখেছ (লেসন ১৫.৬): একটা REST API stage-এ cache রাখা যায়। Request-এর key cache-এ থাকলে API Gateway backend-কে না ডেকেই উত্তর দেয়। পুরো পথে এই স্তর edge-এর পেছনে আর তোমার সব compute-এর সামনে বসে: এখানে একটা hit Lambda invocation (বা EC2-এর কাজ) আর তার পেছনের সবকিছু বাঁচিয়ে দেয়।
পরীক্ষা আর production, দুই জায়গাতেই যে তথ্যগুলো লাগে:
- শুধু REST API। HTTP API আর WebSocket API-তে নিজস্ব cache নেই; দরকার হলে সামনে caching policy-সহ CloudFront বসাও।
- প্রতি stage-এ একটা, আকার 0.5 GB থেকে 237 GB। বানাতে বা আকার বদলাতে কয়েক মিনিট লাগে, আর আকার বদলালে cache খালি হয়ে যায়।
- TTL: default ৩০০ s, ০ (বন্ধ) থেকে ৩,৬০০ s পর্যন্ত। প্রতিটা method-এ আলাদা TTL দেওয়া যায়, বা caching বন্ধ রাখা যায়।
- Default-এ শুধু GET। Stage cache চালু করলে কেবল GET method cache হয়; অন্য method-এর জন্য আলাদা override লাগে (আর সেগুলো cache করা কদাচিৎ ঠিক)।
- Cache key: method আর path, সাথে তুমি যে cache key parameter বেছে নাও (query string, header, path parameter)। Response বদলায় এমন একটা parameter ভুলে গেলে একজন shopper আরেকজনের উত্তর পায়।
- 1 MB-এর বড় response cache হয় না। Cache-এর ডেটা encrypt করা যায়। CloudWatch-এ
CacheHitCountআরCacheMissCountmetric দেখো। - পুরো stage cache flush করা যায় console থেকে বা
flush-stage-cacheদিয়ে; তারপর cache আবার না ভরা পর্যন্ত পুরো চাপ backend নেয়।
#Client-এর bypass: Cache-Control: max-age=0
যে client-এর টাটকা উত্তর দরকার, সে Cache-Control: max-age=0 পাঠাতে পারে। তখন API Gateway backend-কে ডাকে আর রাখা entry-টার জায়গায় নতুন response বসিয়ে দেয়। কে এটা পারবে, তা ঠিক হয় stage বা method-এর দুটো setting দিয়ে:
- Require authorization (
requireAuthorizationForCacheControl)। এটা চালু থাকলে caller-এর ওই method-এর resource ARN-এexecute-api:InvalidateCacheaction-এর IAM permission লাগে। বন্ধ থাকলে যেকোনো client cache bypass করে নতুন করে দিতে পারে, আর AWS সাবধান করে যে এতে সবার latency বাড়তে পারে। - যাদের permission নেই, তাদের জন্য unauthorized request handling (
unauthorizedCacheControlHeaderStrategy):FAIL_WITH_403: request ফিরিয়ে দেওয়া হয় 403 দিয়ে।SUCCEED_WITH_RESPONSE_HEADER: header উপেক্ষা করে cache থেকেই উত্তর, সাথে একটা warning header।SUCCEED_WITHOUT_RESPONSE_HEADER: header চুপচাপ উপেক্ষা করা হয়।
#API cache কি সত্যিই টাকা বাঁচায়?
Notes-এর পরীক্ষার কৌশল বলে, API caching “backend call কমিয়ে API Gateway-র খরচ কমায়”। একটু খুঁটিয়ে পড়ো:
- Cache-এর bill ঘণ্টা ধরে, আকার অনুযায়ী, ব্যবহার হোক বা না হোক, আর এটা free tier-এ নেই: us-east-1-এ 0.5 GB-র জন্য ঘণ্টায় প্রায় ০.০২ USD (মাসে প্রায় ১৪.৬০ USD) থেকে 237 GB-র জন্য ঘণ্টায় ৩.৮০ USD (মাসে প্রায় ২,৭৭০ USD)।
- প্রতিটা request তবু API Gateway-র request। Cache hit-এর bill miss-এর মতোই (প্রথম ধাপে প্রতি দশ লাখ REST request-এ ৩.৫০ USD)। Bill-এর API Gateway-র লাইনটা কখনো কমে না।
- যেটা কমে, সেটা backend: Lambda-র invocation আর duration, EC2-এর capacity, database-এর চাপ।
একটা হিসাব করে দেখি। একটা catalogue API-তে মাসে ২,০০,০০০ GET request আসে, পেছনে 128 MB-র একটা Lambda function, প্রতিবার ১০০ ms চলে। Lambda-র দাম প্রতি দশ লাখ request-এ ০.২০ USD, আর প্রতি GB-second-এ ০.০০০০১৬৬৬৬৭ USD: ০.০৪ USD + ২,০০,০০০ × ০.১ × ০.১২৫ × ০.০০০০১৬৬৬৬৭ ≈ ০.০৪ + ০.০৪ = মাসে ০.০৮ USD। 0.5 GB-র একটা cache-এর দাম প্রায় ১৪.৬০ USD। এখানে caching API-কে দ্রুত করে, কিন্তু bill ১৮২ গুণ করে দেয়।
এবার flash sale: মাসে ৫ কোটি request, hit ratio ৯০%। Cache সাড়ে চার কোটি invocation বাঁচায়: request-এর ৯ USD + ৪,৫০,০০,০০০ × ০.১ × ০.১২৫ × ০.০০০০১৬৬৬৬৭ ≈ ৯.৩৮ USD duration, মোট প্রায় ১৮ USD, সাথে লক্ষ লক্ষ database query, যেগুলোর জন্য নইলে বড় database লাগত। এখানে ১৪.৬০ USD-র cache নিজের খরচ তুলে আনে। Backend-এর সাশ্রয় cache-এর fee-কে ছাড়ালে তবেই caching খরচ কমায়।
API Gateway-এর stage cache
একটা REST API stage, তাতে 0.5 GB cache আর ৬০ সেকেন্ডের TTL, পেছনে একটা Lambda function। দেখো একটা hit, একটা cache key যেটা একটা parameter ভুলে গেছে, আর কিছু client যারা cache এড়িয়ে যেতে চায়।
পরিস্থিতি
Deploy-এর পর প্রথম request। Stage cache চালু করলে default-এ শুধু GET method cache হয়; POST, PUT আর DELETE সবসময় backend-এ পৌঁছায়।
নিজেকে যাচাই করোপ্রশ্ন
Lambda-র সামনে একটা REST API-তে মাসে ৩,০০,০০০ GET request আসে, প্রায় সবগুলো আলাদা। “খরচ কমাতে” team 0.5 GB-র একটা stage cache চালু করল। Bill-এর কী হবে?
#তৃতীয় স্তর: application cache (ElastiCache)
আগে যা শিখেছ (লেসন ৭.৫): ElastiCache হলো একটা in-memory স্তর, যেটা তোমার code database-এর সামনে বসায় (RDS, Aurora, DynamoDB, যেকোনো কিছু), যাতে database-কে একই query বারবার চালাতে না হয়। ওপরের স্তরগুলোর মতো না, এটা cache করে তোমার code যা ঠিক করে: একটা query-র ফল, বানানো একটা product page, একটা session, একটা leaderboard।
#কোন engine
Notes দুটো version-এর কথা বলে, Redis আর Memcached। ২০২৪ থেকে ElastiCache-এ তিনটা engine:
- Valkey: Redis-এর open-source fork, Linux Foundation চালায়, একই command আর client। AWS-এর সুপারিশ করা default, অন্যদের চেয়ে সস্তাও।
- Redis OSS: open-source Redis engine (পরীক্ষা যাকে এখনো “Redis” বলে)।
- Memcached: সাদামাটা, পুরোনো cache।
সাথে ElastiCache Serverless (তিনটা engine-এর জন্যই): node-এর আকার ঠিক করতে হয় না, ডেটা কয়েকটা AZ-এ replicate হয়, bill হয় রাখা ডেটা আর processing unit ধরে। পরীক্ষা “Redis” নিয়ে যা বলে, সবই Valkey-র বেলায়ও খাটে।
| Valkey / Redis OSS | Memcached | |
|---|---|---|
| High availability | Replica, Multi-AZ automatic failover | নেই: replication নেই, failover নেই (node আলাদা AZ-এ রাখা যায়, কিন্তু হারানো node-এর ডেটা চলে যায়) |
| Persistence | Backup আর restore (snapshot) | Node-based cluster-এ নেই |
| ডেটার ধরন | String, hash, list, set, sorted set (leaderboard), geospatial, stream, pub/sub | সাধারণ key-value |
| Scaling | Read-এর জন্য replica, write-এর জন্য shard | Node যোগ করো; client key ছড়িয়ে দেয় (pure horizontal) |
| Thread | Command চলে এক thread-এ | Multi-threaded |
| অন্য Region | Global Datastore | নেই |
#এই পথে lazy loading আর write-through
লেসন ৭.৫ দুটো strategy ধাপে ধাপে শিখিয়েছে। এখানে দেখি, cache যখন চার স্তরের একটা পথের মাঝখানে বসে, তখন এদের মানে কী দাঁড়ায়।
- Lazy loading (cache-aside)। App আগে cache পড়ে; hit হলে উত্তর দেয়, miss হলে database পড়ে, উত্তর দেয়, আর ফলটা cache-এ লিখে রাখে। কেবল যা কেউ চায়, তা-ই cache হয়, তাই memory বাঁচে; আর একটা node নষ্ট বা খালি হলেও বিপদ নেই (read সোজা database-এ যায়)। খরচ: miss penalty (তিন যাত্রা: cache get, database query, cache set, তাই প্রথম read cache না থাকার চেয়েও ধীর), আর stale data, কারণ database update হলে cache-এ হাতই পড়ে না।
- Write-through। Database-এ প্রতিটা write-এর পরে cache-এও write। লেখা ডেটার read সবসময় hit, কখনো stale না। খরচ: write penalty (প্রতি update-এ দুবার লেখা), cache churn (যে ডেটা কেউ পড়বে না, সেটাও memory ভরায়), আর নতুন node-এ ডেটা নেই: কোনো key আবার লেখা না হওয়া পর্যন্ত নতুন node-এ সেটা খালিই থাকে।
বাস্তবে উত্তর হলো দুটো মিলিয়ে চালানো: lazy loading, যাতে যেকোনো miss cache আবার ভরে দেয় (নতুন node, পুরোনো ডেটা); write-through বা লেখার সময় key মুছে দেওয়া, যাতে বদলানো ডেটা টাটকা থাকে; আর প্রতিটা key-তে TTL, যাতে কেউ না পড়া ডেটা বিদায় নেয়, আর কোনো update বাদ পড়লেও সেটার সময় সীমিত থাকে। Memory ভরে গেলে eviction policy key সরায় (default volatile-lru TTL থাকা key-গুলোর মধ্যে সবচেয়ে কম সম্প্রতি ব্যবহৃত key-টা সরায়), প্রতিটা key-তে TTL রাখার এটা আরেকটা কারণ।
Valkey-তে দাম: lazy loading, write-through, আর যা কখনো ঢোকে না
Flash-sale shop product-এর দাম Aurora-র সামনে ElastiCache for Valkey-তে রাখে। দেখো একটা stale read, লেখার সময় key মুছে দেওয়ার সমাধান, write-through-এ খালি নতুন node, আর stock-এর সংখ্যা যা cache এড়িয়ে যায়।
পরিস্থিতি
একজন shopper phone-এর page খুলল। Lazy loading: app আগে Valkey-কে জিজ্ঞেস করে, আর ১,৪৯৯ দামটা সেখানে আছে (TTL ৬০ s)।
#যা কখনো cache-এ ঢোকে না
কিছু ডেটা যে মুহূর্তে ব্যবহার হয়, সেই মুহূর্তে নিখুঁত হতেই হবে। এদের কোথাও, যেকোনো TTL-এ cache করলে গতির সমস্যা পাল্টে ভুলের সমস্যা হয়ে যায়:
- Sale-এর সময় stock-এর সংখ্যা আর seat: database থেকে পড়ো, আর কেনাটাকে বানাও একটা শর্তসাপেক্ষ write (stock > 0 হলে তবেই কমাও)।
- Payment-এর মুহূর্তে account balance, যেমন bKash-ধাঁচের একটা wallet-এ: home screen-এর জন্য balance cache করা যায়, টাকা কাটার সিদ্ধান্তের জন্য কখনো না।
- Shared key-তে user-ভিত্তিক ডেটা: user ছাড়া একটা key-তে API স্তরে cache করা cart বা profile পরের user-কে দেখানো হয়।
- একবারের token, OTP আর নিরাপত্তা-সংক্রান্ত যেকোনো কিছু।
#DynamoDB-র তৃতীয় স্তর: DAX
আগে যা শিখেছ (লেসন ১৫.৫): DynamoDB উত্তর দেয় এক অঙ্কের millisecond-এ। DynamoDB Accelerator (DAX) হলো শুধু DynamoDB-র জন্য বানানো একটা in-memory cache cluster, যেটা cache করা read-এর উত্তর দেয় microsecond-এ, আর table-এর ওপর থেকে read-এর চাপ সরায়।
- API-compatible। DAX DynamoDB-র API-তেই কথা বলে। DynamoDB client-এর জায়গায় DAX client বসাও আর cluster-এর endpoint দেখিয়ে দাও;
GetItem,QueryআরPutItemএকই থাকে। Notes-এর “code নতুন করে লিখতে হয় না” কথাটা ঠিক, শুধু একটু নিখুঁত করে বললে client আর endpoint বদলায় (ছোট পরিবর্তন, শূন্য না)। - Read-through আর write-through: miss হলে table থেকে পড়ে cache করে; DAX-এর ভেতর দিয়ে write আগে table-এ যায়, তারপর item cache নতুন করে।
- কেবল eventually consistent read। Strongly consistent read (
ConsistentRead=true) বা transactional read সোজা table-এ চলে যায়, cache হয় না। - Item cache আর query cache, দুটোরই default TTL ৫ মিনিট। Query cache (
QueryআরScan-এর ফল) write-এ নতুন হয় না। - যে write DAX এড়িয়ে যায় (অন্য application, একটা import job, global table-এর replica), সেগুলো TTL শেষ না হওয়া পর্যন্ত cache-কে stale রেখে দেয়।
- চলে তোমার VPC-র ভেতরে একটা cluster হিসেবে (একটা primary আর সর্বোচ্চ ১০টা read replica; production-এ তিনটা AZ-এ তিনটা node), bill node-hour ধরে। এটা read-কে সাহায্য করে, write-কে না।
| প্রশ্নে যা থাকে | বাছো |
|---|---|
| DynamoDB + microsecond latency + application নতুন করে না লিখে | DAX |
| Read-heavy DynamoDB table, একটা hot key read throttle করছে | DAX |
| অনেক item জুড়ে একটা হিসাব বা aggregation-এর ফল cache করো | ElastiCache |
| RDS / Aurora বা DynamoDB ছাড়া অন্য কিছুর জন্য cache | ElastiCache |
| Session store, leaderboard, pub/sub, rate-limit counter | ElastiCache |
| Strongly consistent read দ্রুত করতে হবে | কোনোটাই কাজে আসে না; DAX এগুলো সোজা পার করে দেয় |
DAX: DynamoDB read-এ microsecond
Shop-এর product catalogue একটা DynamoDB table, সামনে তিন node-এর একটা DAX cluster। App একই GetItem call দিয়ে DAX client ব্যবহার করে। দেখো DAX কোন read দিতে পারে, আর কোনটা পারে না।
পরিস্থিতি
Code আগের মতোই GetItem call করে; বদলেছে শুধু client আর endpoint। DAX-এর ক্ষেত্রে “application নতুন করে লিখতে হয় না” মানে এটাই।
#Session state: web tier-কে stateless রাখো
আগে যা শিখেছ (লেসন ৯.১, ৯.২ আর ৬.৪): session-এর ডেটা, যেমন কে login করে আছে আর cart-এ কী আছে, শুধু একটা EC2 instance-এ থাকা চলবে না। এটা রাখো একটা বাইরের store-এ, আর browser-কে দাও শুধু একটা session ID। Notes একে বলে session caching।
- ElastiCache for Valkey বা Redis OSS: millisecond-এরও কম সময়ে read, প্রতিটা session-এ session timeout-এর সমান TTL; replica আর Multi-AZ রাখো, কারণ store হারালে সবাই logout হয়ে যায়।
- DynamoDB: টেকসই আর serverless, সাথে একটা TTL attribute, যাতে মেয়াদ ফুরানো session নিজে থেকেই মুছে যায়। Session-কে যেকোনো অবস্থায় টিকে থাকতে হলে এটা ভালো।
- Node নষ্ট হলে session হারানো যদি মেনে নেওয়া যায়, তাহলে Memcached-ও চলে।
Sticky session (ALB-র stickiness cookie) হলো শর্টকাট, সমাধান না। এটা একজন user-কে একটা instance-এ আটকে রাখে, তাই memory-তে রাখা cart ততক্ষণই বাঁচে, যতক্ষণ সেই instance বাঁচে: একটা scale in, একটা ব্যর্থ health check বা একটা deployment, আর cart শেষ। চাপও ছড়ায় অসমানভাবে: scale out-এ আসা নতুন instance পায় শুধু নতুন user-দের, আর ব্যস্ত instance-টা তার আটকে থাকা user-দের নিয়েই থাকে। Shared store-এ session রাখলে দুটো সমস্যাই চলে যায়; web tier হয়ে যায় stateless, আর যেকোনো instance যেকোনো request-এর উত্তর দিতে পারে।
Session state: instance-এ, নাকি সবার জন্য একটা store-এ
Flash sale-এর সময় একটা ALB আর Auto Scaling group-এর পেছনে cart। প্রথমে cart থাকে instance-এর memory-তে, সাথে sticky session; তারপর একটা DynamoDB table-এ, যেটা সব instance পড়তে পারে।
পরিস্থিতি
Sticky session একজন shopper-কে একটা instance-এ আটকে রাখে; সেই instance গেলে cart-ও যায়।
রহিম cart-এ দুটো phone রাখল। EC2 A cart-টা নিজের memory-তে রাখে, আর ALB একটা stickiness cookie বসায়, যাতে ওর পরের request-গুলোও A-তেই যায়।
#Cache-এর মতো আরও দুটো বিকল্প
- RDS read replica (লেসন ৭.১) কোনো cache code ছাড়াই primary-র ওপর থেকে read query সরিয়ে নেয়: report আর শুধু-পড়ার page replica endpoint-এ পাঠাও। এগুলো পুরো database-এর কপি, asynchronous ভাবে হালনাগাদ হয় (কয়েক সেকেন্ডের lag), আর প্রতিটা query তবু চালায়; cache কিছু না চালিয়েই রাখা উত্তর দিয়ে দেয়। Read নানা রকম হলে (report, search page) আর একটু lag চললে replica বাছো; একই কয়েকটা ফল বারবার পড়া হলে ElastiCache।
- OAC-সহ CloudFront-এর পেছনে S3: static file-এর জন্য “cache স্তর” শুধু edge-ই, আর S3 হলো private origin। ছবি, script বা download-এর জন্য ElastiCache লাগে না।
#কোথায় কী cache করবে
| ডেটা | Edge (CloudFront) | API cache | Valkey / DAX | কখনো cache নয় | কেন |
|---|---|---|---|---|---|
| Product-এর ছবি, CSS/JS (নামে version) | হ্যাঁ, ১ বছর | একই নামে কখনো বদলায় না | |||
| Anonymous user-দের home page-এর HTML | হ্যাঁ, ৩০–৬০ s | সবার জন্য একই, একটু পুরোনো হলে চলে | |||
| Category ধরে product list | ছোট TTL-এ সম্ভব | হ্যাঁ, ৬০ s | হ্যাঁ, ব্যাকআপ হিসেবে | সবার জন্য একই, হাজার হাজার বার চাওয়া হয় | |
| একটা product-এর দাম | শুধু ছোট TTL-এ | হ্যাঁ, লেখায় মুছে দাও | Checkout-এ | টাকার ব্যাপারে টাটকা হতেই হবে | |
| Shopper-এর cart আর login | না | Session: Valkey বা DynamoDB | User-ভিত্তিক; instance হারালেও টিকতে হবে | ||
| DynamoDB item read (catalogue) | DAX | Microsecond, একই code | |||
| Sale-এর সেরা ক্রেতাদের leaderboard | Valkey sorted set | হিসাব করা ডেটা, ঘনঘন বদলায় | |||
| Stock-এর সংখ্যা, wallet balance, OTP | হ্যাঁ | প্রতি মুহূর্তে নিখুঁত হতে হবে |
#শুরু থেকে শেষ: একটা ১১.১১ flash sale
Daraz-ধাঁচের shop-এর ১১.১১-এর design, স্তর ধরে ধরে:
Edge: product-এর ছবি আর script
সব ছবি আর script থাকে CloudFront-এর পেছনে একটা private S3 bucket-এ, OAC দিয়ে, নামে version আর এক বছরের TTL-সহ। প্রতিটা edge-এ প্রথম request-এর পরে এগুলো আর Region-এ ফেরে না।
API: product list ৬০ সেকেন্ডের জন্য
GET /api/products?cat=…REST API stage-এ ৬০ s-এর জন্য cache হয়,catআরpageহলো cache key parameter। Sale-এর সময় এই একটা setting মিনিটে হাজার হাজার একই request-কে প্রতি category-তে মিনিটে একবার Lambda চলায় নামিয়ে আনে। Cache control-এর জন্য authorization চালু রাখো, যাতে শুধু admin app জোর করে নতুন করাতে পারে।Application: দাম Valkey-তে
Lambda function-গুলো ElastiCache for Valkey থেকে দাম পড়ে, lazy loading আর ছোট TTL দিয়ে, আর seller দাম বদলালে key মুছে যায়। Valkey cluster-এর replica আছে অন্য AZ-এ, তাই node নষ্ট হলে সেটা failover হয়, খালি cache আর database-এ হুড়োহুড়ি না।
Session: cart DynamoDB-তে
Cart আর login থাকে একটা DynamoDB table-এ, session ID দিয়ে, সাথে TTL attribute। যেকোনো function বা instance যেকোনো shopper-কে serve করতে পারে।
কখনো cache নয়: stock-এর সংখ্যা
Sale-এর ৪০টা phone-এর stock পড়া হয় database থেকে, আর প্রতিটা কেনা একটা শর্তসাপেক্ষ write। কয়েক millisecond ধীর, কিন্তু কখনো বাড়তি বিক্রি হয় না।
নিচের tracer-এ design-টা চালিয়ে দেখো: প্রতিটা স্তর চালু-বন্ধ করো, TTL আর seller-এর শেষ পরিবর্তনের পর কত সময় গেছে বদলাও, আর দেখো প্রতিটা request-এর উত্তর কোথা থেকে আসে, কত সময় লাগে, আর উত্তর ভুল হতে পারে কিনা।
Request tracer: উত্তর আসে কোথা থেকে?
Shopper ঢাকায়, shop Singapore Region-এ। একটা request আর cache-এর স্তরগুলো বেছে নাও, seller কত আগে ডেটা বদলেছে বলো, তারপর request পাঠাও।
Request
CloudFront ছবি cache করে
API Gateway cache-এর TTL
App-এ Valkey
Seller ডেটা বদলেছে … আগে
Trace দেখতে “Request পাঠাও” চাপো।
#কোথায় গোলমাল হয়
- জমে থাকা TTL। প্রতিটা স্তরের TTL আলাদাভাবে নিরীহ মনে হয়েছিল; সব মিলিয়ে একটা দামের পরিবর্তন shopper-এর কাছে পৌঁছাতে কয়েক মিনিট লাগে। একই ডেটা যত স্তর রাখে, তাদের TTL যোগ করো, আর নিচ থেকে ওপরে invalidate করো (database, Valkey key, API stage, edge)।
- User ছাড়া cache key। User-ভিত্তিক response shared key-তে cache হলে একজনের cart বা profile আরেকজনকে দেখায়। User-ভিত্তিক method-এ caching বন্ধ রাখো, বা key-তে user রাখো।
- Parameter ছাড়া cache key, যে parameter response বদলায়: laptop-এর page-এ phone দেখায়।
- খোলা cache bypass। API stage-এ “require authorization” বন্ধ: যেকোনো client প্রতিটা request-এ
max-age=0পাঠাতে পারে, আর পুরো চাপ backend-এর ঘাড়ে। - Default TTL-এর চমক।
Cache-Controlছাড়া object CloudFront ২৪ ঘণ্টা রাখে; দুপুরে বদলানো দামের তালিকা কাল পর্যন্ত পুরোনো থাকে। - Node নষ্টের পর ঠান্ডা cache। Replica ছাড়া lazy-loaded cache খালি হয়ে ফেরে, সব read miss করে, আর database-এর ওপর হুড়োহুড়ি (stampede) নামে। Replica আর Multi-AZ রাখো, TTL-এ jitter দাও।
- অলস cache-এর জন্য টাকা দেওয়া। কম পুনরাবৃত্ত request-এর API-তে stage cache যতটা বাঁচায়, তার চেয়ে বেশি খরচ করায়।
- ভুল read-এর জন্য DAX। Strongly consistent read, write-heavy table আর cluster এড়িয়ে যাওয়া write, এদের কেউই DAX থেকে কিছু পায় না।
- Session store হিসেবে sticky session। Instance-এর সাথে cart-ও উধাও।
#System design-এ caching
- শুরু করো ডেটা থেকে, service থেকে না: প্রতিটা রকমের ডেটা কতটা পুরোনো হতে পারে ঠিক করো, আর সেই পুরোনো হওয়া যতদূর সয়, পথের ততটা ওপরে সেটা cache করো।
- Static থাকে edge-এ, সবার জন্য একই জিনিস API-তে, হিসাব করা জিনিস app cache-এ, নিখুঁত জিনিস database-এ।
- প্রতিটা cache-কে ফেলে দেওয়ার যোগ্য রাখো: যেকোনো cache খালি হলেও system ঠিক থাকবে (শুধু ধীর হবে)। মানে কোনো কিছুর একমাত্র কপি cache-এ রাখা চলবে না, আর এই কারণেই আসল সত্য থাকে database-এ।
- প্রতিটা স্তরের hit ratio দেখো (CloudFront-এ
CacheHitRate, API Gateway-তেCacheHitCount/CacheMissCount, ElastiCache-এCacheHits/CacheMissesআরEvictions)। কম hit ratio-র cache টাকা খরচ করায় আর একটা বাড়তি ধাপ যোগ করে। - এই একই পথ আবার আসে event-এর জন্য লেসন ২৪.১-এ, আর খারাপ client আটকানোর জন্য লেসন ২৪.৩-এ: অনাকাঙ্ক্ষিত traffic থামানোর সবচেয়ে সস্তা জায়গাও edge।
| পরীক্ষার ভাষা | স্তর আর service |
|---|---|
| Global user, latency, origin offload, static আর dynamic content | Edge: CloudFront |
| REST API-র পেছনের Lambda / EC2-এর চাপ কমাও, একই request বারবার | API: API Gateway caching |
| Client জোর করে টাটকা ডেটা নেবে | Cache-Control: max-age=0 + execute-api:InvalidateCache |
| HA, Multi-AZ, failover, backup, pub/sub, leaderboard | ElastiCache for Redis (Valkey / Redis OSS) |
| সাধারণ key-value, purely horizontal, multi-threaded | ElastiCache for Memcached |
| Stale data ঠেকাও | Write-through |
| Memory বাঁচাও, শুধু চাওয়া ডেটা cache করো | TTL-সহ lazy loading |
| DynamoDB, microsecond, code নতুন করে লেখা নয় | DAX |
| Stateless web tier, terminate হলেও টিকে থাকা, sticky session এড়ানো | Session ElastiCache বা DynamoDB-তে |
#নিজে করে দেখো
# 1. Edge: see whether CloudFront answered from cache, then invalidate one path
curl -sI https://d111111abcdef8.cloudfront.net/img/p881-v3.webp | grep -iE 'x-cache|age'
# x-cache: Hit from cloudfront
# age: 5312
aws cloudfront create-invalidation --distribution-id E1ABCDEXAMPLE \
--paths "/api-docs/index.html"
# { "Invalidation": { "Id": "I2J0I21PCUYOIK", "Status": "InProgress", ... } }
# 2. API: provision a 0.5 GB stage cache and cache every GET for 60 s
aws apigateway update-stage --rest-api-id a1b2c3d4e5 --stage-name prod \
--patch-operations op=replace,path=/cacheClusterEnabled,value=true \
op=replace,path=/cacheClusterSize,value=0.5 \
op=replace,path=/*/*/caching/enabled,value=true \
op=replace,path=/*/*/caching/ttlInSeconds,value=60
# { "stageName": "prod", "cacheClusterEnabled": true, "cacheClusterSize": "0.5",
# "cacheClusterStatus": "CREATE_IN_PROGRESS", ... }
# 3. API: only callers with execute-api:InvalidateCache may bypass; others get 403
aws apigateway update-stage --rest-api-id a1b2c3d4e5 --stage-name prod \
--patch-operations op=replace,path=/*/*/caching/requireAuthorizationForCacheControl,value=true \
'op=replace,path=/*/*/caching/unauthorizedCacheControlHeaderStrategy,value=FAIL_WITH_403'
# 4. API: turn caching off for the per-user cart method (path /cart is written ~1cart)
aws apigateway update-stage --rest-api-id a1b2c3d4e5 --stage-name prod \
--patch-operations op=replace,path=/~1cart/GET/caching/enabled,value=false
# 5. API: empty the whole stage cache after an urgent price correction
aws apigateway flush-stage-cache --rest-api-id a1b2c3d4e5 --stage-name prod
# 6. Application: a serverless Valkey cache for prices
aws elasticache create-serverless-cache --serverless-cache-name prices \
--engine valkey --subnet-ids subnet-0a1b2c3d subnet-0e5f6a7b \
--security-group-ids sg-0123456789abcdef0
# { "ServerlessCache": { "ServerlessCacheName": "prices", "Status": "creating", "Engine": "valkey", ... } }
# 7. Lazy loading by hand with valkey-cli: miss, set with a TTL, hit, delete on write
valkey-cli -h prices-abc123.serverless.apse1.cache.amazonaws.com --tls GET price:881
# (nil)
valkey-cli -h prices-abc123.serverless.apse1.cache.amazonaws.com --tls SET price:881 1499 EX 60
# OK
valkey-cli -h prices-abc123.serverless.apse1.cache.amazonaws.com --tls TTL price:881
# (integer) 57
valkey-cli -h prices-abc123.serverless.apse1.cache.amazonaws.com --tls DEL price:881
# (integer) 1
# 8. DynamoDB: a three-node DAX cluster in front of the catalogue table
aws dax create-cluster --cluster-name catalogue-dax --node-type dax.r5.large \
--replication-factor 3 --iam-role-arn arn:aws:iam::111122223333:role/DAXServiceRole \
--subnet-group-name dax-private --security-group-ids sg-0123456789abcdef0
# { "Cluster": { "ClusterName": "catalogue-dax", "TotalNodes": 3, "Status": "creating", ... } }
# 9. Sessions: let DynamoDB delete expired sessions on its own
aws dynamodb update-time-to-live --table-name sessions \
--time-to-live-specification Enabled=true,AttributeName=expiresAt
# { "TimeToLiveSpecification": { "Enabled": true, "AttributeName": "expiresAt" } }
# 10. Clean up the paid caches
aws apigateway update-stage --rest-api-id a1b2c3d4e5 --stage-name prod \
--patch-operations op=replace,path=/cacheClusterEnabled,value=false
aws dax delete-cluster --cluster-name catalogue-dax
aws elasticache delete-serverless-cache --serverless-cache-name prices
তারপর hit-এর হিসাব দেখো: একই request আর একটা আলাদা request বারবার পাঠাতে পাঠাতে CloudWatch-এ API stage-এর CacheHitCount আর CacheMissCount, আর Valkey cache-এর CacheHits, CacheMisses আর Evictions লক্ষ করো।
#সারসংক্ষেপ
মূল কথাগুলো
- একটা পথ, চারটা cache: CloudFront (edge) → API Gateway-র stage cache → ElastiCache বা DAX (application/database) → database, আর CloudFront-এর পেছনে S3।
- লাভ-ক্ষতির হিসাব: user-এর যত কাছে, প্রতি request-এ latency আর খরচ তত কম, কিন্তু invalidate করা তত কঠিন, ডেটা তত পুরোনো। স্তরে স্তরে stale-এর সময় যোগ হয়: সবচেয়ে খারাপ ক্ষেত্রে TTL-গুলোর যোগফল।
- CloudFront: default TTL ২৪ ঘণ্টা, behaviour ধরে cache key আর cache policy, invalidation (মাসে ১,০০০ path বিনা পয়সায়, তারপর প্রতি path ০.০০৫ USD) বা আরও ভালো নামে version; S3 origin private, OAC দিয়ে।
- API Gateway cache: শুধু REST API, প্রতি stage-এ, 0.5–237 GB, TTL default ৩০০ s, সর্বোচ্চ ৩,৬০০ s, default-এ শুধু GET, cache key parameter, flush।
Cache-Control: max-age=0দিয়ে bypass-এexecute-api:InvalidateCacheলাগে কেবল require authorization চালু থাকলে। Bill ঘণ্টা ধরে, আর request-এর bill তবু হয়: backend-এর সাশ্রয় fee-কে ছাড়ালে তবেই টাকা বাঁচে। - ElastiCache: Valkey (সুপারিশ করা), Redis OSS, Memcached, সাথে Serverless। HA, Multi-AZ, backup, pub/sub, leaderboard-এ Redis; সাধারণ, multi-threaded, purely horizontal key-value-তে Memcached।
- Lazy loading: শুধু চাওয়া ডেটা, কিন্তু miss penalty আর stale read। Write-through: কখনো stale না, কিন্তু write penalty, churn আর খালি নতুন node। দুটো মিলিয়ে চালাও, TTL জোরালোভাবে উচিত (বাধ্যতামূলক না), লেখায় key মুছে দাও।
- DAX: শুধু DynamoDB, microsecond, API-compatible (client বদলাও), কেবল eventually consistent read, default TTL ৫ মিনিট, তোমার VPC-তে।
- ElastiCache বা DynamoDB-তে session রাখলে web tier stateless হয়; sticky session state হারায় আর চাপ অসমানভাবে ছড়ায়।
- Stock-এর সংখ্যা, payment-এর মুহূর্তের balance, OTP, বা shared key-তে user-ভিত্তিক ডেটা কখনো cache কোরো না।
আগে নিজে উত্তর দাও, তারপর ব্যাখ্যাটা পড়ো। ঠিক হলেও পড়ো, কারণ ভুল Option-গুলো কেন ভুল, সেটাও ওখানে আছে।
নিজেকে যাচাই করোপ্রশ্ন
Origin কোনো Cache-Control বা Expires header পাঠায় না, আর CloudFront-এর cache behaviour default TTL setting-এ আছে। Edge object-টা কতক্ষণ রাখবে?
নিজেকে যাচাই করোপ্রশ্ন
API Gateway-র কোন রকমের API-তে নিজস্ব response cache আছে?
নিজেকে যাচাই করোপ্রশ্ন
API Gateway-র stage cache-এর default আর সর্বোচ্চ TTL কত?
নিজেকে যাচাই করোপ্রশ্ন
DAX item cache-এর default TTL কত?
নিজেকে যাচাই করোপ্রশ্ন
ElastiCache for Valkey বা Redis OSS-এর কোন দুটো ক্ষমতা ElastiCache for Memcached-এর নেই?
বেছে নাও ২
নিজেকে যাচাই করোপ্রশ্ন
একটা media company এক Region-এর একটা ALB থেকে এশিয়া, ইউরোপ আর আমেরিকার user-দের serve করে। Page-এ static ছবি আর dynamic অংশ দুটোই আছে। কম পরিবর্তনে সারা বিশ্বে latency কমাতে আর ALB-র চাপ কমাতে চায়। কী করা উচিত?
নিজেকে যাচাই করোপ্রশ্ন
একটা game player profile DynamoDB-তে রাখে। Read microsecond-এ নামাতে হবে, আর team data-access logic নতুন করে লিখতে পারবে না। কোন সমাধান মানায়?
নিজেকে যাচাই করোপ্রশ্ন
একটা shop product list API Gateway stage-এ ৩০০ s TTL দিয়ে cache করে। পেছনের Lambda দাম পড়ে Valkey থেকে, lazy loading আর ৩০০ s TTL দিয়ে, কখনো key মোছে না। Database-এ একটা দাম বদলানো হলো। একজন shopper সবচেয়ে বেশি কতক্ষণ পুরোনো দাম দেখতে পারে?
নিজেকে যাচাই করোপ্রশ্ন
পরীক্ষার একটা প্রশ্ন বলছে, update-এর পরে cache কখনো পুরোনো ডেটা দিতে পারবে না, আর read দ্রুত থাকতে হবে। কোন strategy সবচেয়ে মানায়?
নিজেকে যাচাই করোপ্রশ্ন
একটা team cache memory ছোট রাখতে চায়, আর শুধু সেই ডেটাই cache করতে চায় যা user সত্যিই চায়; প্রথম read একটু ধীর হলে আপত্তি নেই। কোন strategy মানায়?
নিজেকে যাচাই করোপ্রশ্ন
Write-through caching-এর কোন দুটো অসুবিধা?
বেছে নাও ২
নিজেকে যাচাই করোপ্রশ্ন
Notes বলে lazy loading-এর সাথে TTL বাধ্যতামূলক। কোনটা সঠিক?
নিজেকে যাচাই করোপ্রশ্ন
একটা API stage-এ cache আছে, কিন্তু cache control-এর জন্য require authorization কেউ চালু করেনি। একটা দাম-তুলনা bot প্রতিটা request-এ Cache-Control: max-age=0 পাঠায়। কী হয়?
নিজেকে যাচাই করোপ্রশ্ন
অনুমতিহীন cache-invalidation request API Gateway stage কীভাবে সামলাবে, তার বৈধ মান কোন দুটো?
বেছে নাও ২
নিজেকে যাচাই করোপ্রশ্ন
একটা product list API /products?cat=phones আর /products?cat=laptops ব্যবহার করে। Stage cache চালুর পর laptop চাওয়া shopper মাঝে মাঝে phone পায়। সমাধান কী?
নিজেকে যাচাই করোপ্রশ্ন
Stage cache চালুর পর একজন user জানাল, GET /cart-এ সে অন্য কারও cart দেখছে। User-কে চেনা যায় header-এর একটা token দিয়ে। সবচেয়ে ভালো সমাধান কী?
নিজেকে যাচাই করোপ্রশ্ন
ALB-র পেছনে EC2 instance-এর একটা web tier sticky session দিয়ে memory-তে session রাখে। Auto Scaling group scale in করলে user-রা cart হারায়। কোন দুটো পরিবর্তন tier-কে stateless বানায়?
বেছে নাও ২
নিজেকে যাচাই করোপ্রশ্ন
Flash sale-এর সময় Auto Scaling group দুটো instance যোগ করল, কিন্তু পুরোনো instance ৯০% CPU-তেই রইল, নতুনগুলো প্রায় অলস। Session-এ ALB stickiness ব্যবহার হচ্ছে। কারণ কী?
নিজেকে যাচাই করোপ্রশ্ন
একটা application DAX ব্যবহার করে। Checkout ConsistentRead=true দিয়ে item পড়ে আর সেটা ধীর লাগে। কেন?
নিজেকে যাচাই করোপ্রশ্ন
একটা dashboard বিক্রির হিসাবে সেরা ১০০টা product দেখায়, প্রতি মিনিটে লক্ষ লক্ষ DynamoDB item থেকে হিসাব করে। এই ফলের জন্য কোন cache সবচেয়ে মানায়?
নিজেকে যাচাই করোপ্রশ্ন
রাতে একটা import job সাধারণ DynamoDB client দিয়ে সরাসরি table-এ নতুন দাম লেখে। Website DAX-এর ভেতর দিয়ে পড়ে, আর প্রতি সকালে কয়েক মিনিট পুরোনো দাম দেখায়। কেন?
নিজেকে যাচাই করোপ্রশ্ন
একটা flash sale-এ বিশেষ দামে ৪০টা phone বিক্রি হচ্ছে। বাকি stock-এর সংখ্যা কোথায় cache করা উচিত?
নিজেকে যাচাই করোপ্রশ্ন
একটা RDS MySQL database নানা রকম report query-তে ভারাক্রান্ত, যেগুলো কয়েক সেকেন্ডের lag মেনে নিতে পারে। Team cache code লিখতে চায় না। কোনটা সবচেয়ে মানায়?
নিজেকে যাচাই করোপ্রশ্ন
CloudFront দিয়ে S3 থেকে serve করা static ছবির জন্য কোন দুটো অভ্যাস মানানসই?
বেছে নাও ২
নিজেকে যাচাই করোপ্রশ্ন
একটা team এক মাসে তাদের distribution-গুলোতে ৪,০০০টা আলাদা path invalidate করে। প্রথম ১,০০০ path বিনা পয়সায়, তারপর প্রতি path ০.০০৫ USD। খরচ কত?
নিজেকে যাচাই করোপ্রশ্ন
ElastiCache for Memcached নিয়ে কোন কথাটা সঠিক নয়?
নিজেকে যাচাই করোপ্রশ্ন
একটা জরুরি দামের ভুল সবার জন্য একসাথে সরাতে হবে। কোন cache করা কপি দ্রুত সরানো সবচেয়ে কঠিন?
নিজেকে যাচাই করোপ্রশ্ন
পরীক্ষার কোন দুটো কথা Memcached না, বরং ElastiCache for Redis (Valkey বা Redis OSS)-এর দিকে ইঙ্গিত করে?
বেছে নাও ২
নিজেকে যাচাই করোপ্রশ্ন
একটা mobile backend হলো Lambda-র সামনে API Gateway-র একটা HTTP API। Catalogue endpoint-এ মিনিটে হাজার হাজার বার একই request আসে, আর team ৬০ সেকেন্ডের TTL-সহ একটা response cache চায়। কী করা উচিত?
নিজেকে যাচাই করোপ্রশ্ন
একটা node আর lazy loading-ওয়ালা একটা Valkey cache hardware-এর গোলমালে বদলানো হলো। কয়েক মিনিট database-এর CPU ১০০%-এ লাফিয়ে উঠল। সবচেয়ে সরাসরি কী এটা ঠেকাত?
নিজেকে যাচাই করোপ্রশ্ন
একজন architect এমন একটা page-এর জন্য প্রতি request-এ সবচেয়ে সস্তা আর দ্রুত উত্তর চান, যেটা সব anonymous visitor-এর জন্য একই আর ৩০ সেকেন্ড পুরোনো হলেও চলে। কোথায় cache করা উচিত?