০০ যে প্রশ্নগুলোর উত্তর খুঁজবো
এই প্রশ্নগুলোর উত্তর জানার পর আপনি cache এর basic idea বুঝবেন। Production এ cache কীভাবে fail করে, সেটাও বুঝবেন।
- ১ আমার cache কেন দরকার?
- ২ Cache আসলে কতটা fast? এত ঝামেলা কি worth?
- ৩ Application এ cache কীভাবে ব্যবহার করবো?
- ৪ DB এর data পরিবর্তন হলে cache কীভাবে adjust হবে?
- ৫ Cache এর memory সীমিত। Cache full হলে কী হবে?
- ৬ Invalidation আর Eviction এর মধ্যে পার্থক্য কী?
- ৭ আমি কি সব কিছু cache করবো?
- ৮ Production caching এ কী কী জটিলতা আসতে পারে?
- ৯ আমাদের পুরো system এখন দেখতে কেমন?
০১ Cache কেন দরকার?
ভাবুন, আপনি একটা সরকারি অফিসে কাজ করেন। সারাদিন মানুষ আপনার কাছে একই form নিতে আসেন। প্রতিবার আপনাকে basement এ যেতে হয়। সেখানে file খুলে form টা বের করেন, photocopy করেন, তারপর ফিরে এসে হাতে দেন। প্রতিবার ৫ মিনিট লাগে।
৫০ বার এভাবে করার পর একজন বুদ্ধিমান মানুষ কী করবেন? যে form গুলো সবচেয়ে বেশি লাগে, সেগুলোর কিছু কপি নিজের desk এ রেখে দেবেন। কেউ চাইলে ২ সেকেন্ডে হাতে দিয়ে দেবেন। Basement এ যাবেন শুধু desk এর কপি শেষ হলে।
এটাই Caching। এখানে desk এর কপিগুলো হলো cache, আর basement হলো database।
যে কাজ করতে অনেক সময় বা খরচ লাগে, তার উত্তর একটা দ্রুত জায়গায় রেখে দেওয়াকে বলে caching। এতে একই কাজ বারবার করতে হয় না।
০২ Cache আসলে কতটা fast?
Cache সাধারণত data রাখে RAM এ। এবার নিচের সংখ্যাগুলো দেখুন:
| Operation | Time |
|---|---|
| CPU cache (L1) | ~১ nanosecond |
| RAM | ~১০০ nanoseconds |
| SSD | ~১,০০,০০০ nanoseconds (১০০ µs) |
| HDD | ~১,০০,০০,০০০ nanoseconds (১০ ms) |
| Redis এর মতো আলাদা cache server (একই data center, network সহ) | ~০.৫-১ millisecond |
| Database (network এর মধ্য দিয়ে) | ~১-১০ milliseconds |
| Across continents | ~১৫০ milliseconds |
RAM থেকে read করা HDD থেকে read করার চেয়ে ১,০০,০০০ গুণ দ্রুত। একই server এর RAM থেকে data নেওয়া (~১০০ ns) আর network পেরিয়ে database থেকে data আনার (~১ ms) মধ্যে প্রায় ১০,০০০ গুণ পার্থক্য।
তবে cache সবসময় একই server এর RAM এ থাকে না। Redis এর মতো আলাদা cache server এ গেলে network এর সময়ও যোগ হয়, তাই এক বার আনতে প্রায় ১ ms লাগে। তবু এটা database query এর চেয়ে অনেক দ্রুত। কারণ Redis এ data আগে থেকেই RAM এ তৈরি থাকে, disk থেকে পড়তে বা query চালাতে হয় না।
ধীর কাজকে (DB query, network call, হিসাব করা) একটা দ্রুত memory lookup এ বদলে ফেলা।
অফিসের গল্প থেকে চারটা কঠিন প্রশ্ন আসে:
- কী cache করবো: Desk এ জায়গা সীমিত।
- Cache full হলে কী সরাবো: এর নাম eviction।
- Data বদলালে cache কীভাবে fresh রাখবো: এর নাম invalidation।
- Cache down হলে কী হবে: তখনো DB ই source of truth।
০৩ Application এ cache কীভাবে ব্যবহার করবো?
একটা আধুনিক application এ cache একাধিক জায়গায় থাকতে পারে:
- Browser cache: User এর browser নিজেই image, CSS, JS এর মতো file জমিয়ে রাখে।
- CDN (Content Delivery Network): User এর কাছাকাছি server এ static file এর copy রাখা হয়। বিস্তারিত সেশন ০৬ এ।
- Application server এর নিজের memory: প্রতিটা app server নিজের RAM এ কিছু data রাখে। এটা সবচেয়ে দ্রুত, কিন্তু প্রতিটা server এর copy আলাদা থাকে।
- Distributed cache: একটা আলাদা cache server, যেটা সব app server মিলে ব্যবহার করে। এর সবচেয়ে পরিচিত উদাহরণ হলো Redis আর Memcached।
- Database এর নিজের cache: Database নিজেও বারবার পড়া data RAM এ রেখে দেয়।
এই সেশনে আমরা Distributed Cache নিয়ে কথা বলবো, কারণ system design এ এটাই সবচেয়ে জরুরি layer। এর সবচেয়ে জনপ্রিয় উদাহরণ Redis। Redis একটা আলাদা server, যেটা সব data RAM এ key-value আকারে রাখে। যেমন key user:42 আর value হলো সেই user এর data।
Cache-Aside Pattern (সবচেয়ে common)
Application প্রথমে cache এ খোঁজে। Data পেলে সেটাই ব্যবহার করে (hit)। না পেলে (miss) DB তে যায় আর data নিয়ে আসে। তারপর সেই data cache এ রেখে দেয়, যাতে পরের বার কাজে লাগে।
function getUser(id):
user = cache.get(id)
if user exists:
return user # cache hit
user = database.get(id) # cache miss
cache.set(id, user)
return user
দুটো জরুরি term জেনে রাখুন:
- Cache hit (ক্যাশ হিট): Data cache এ পাওয়া গেছে।
- Cache miss (ক্যাশ মিস): Data cache এ ছিলো না, তাই DB তে যেতে হয়েছে।
মোট request এর কত ভাগ cache থেকে উত্তর পেলো, তাকে বলে hit rate। যেমন ১০০টা request এর ৯০টা cache থেকে এলে hit rate ৯০%। একটা ভালো cache এর লক্ষ্য থাকে ৯০% এর বেশি hit rate।
০৪ DB এর data পরিবর্তন হলে cache কীভাবে adjust হবে?
“There are only two hard things in computer science: cache invalidation and naming things.” - Phil Karlton
সমস্যা:
Step 1: User 31 এর name "Roy"। Step 2: DB তে name update হলো "Mr. Roy"। Cache এ এখনো "Roy"। Step 3: পরের read cache থেকে আসবে, আর "Roy" return হবে। এটা ভুল ডেটা!
তিনটা strategy
DB আর cache, দুটোতেই একসাথে write করা হয়।
- সুবিধা: Cache সবসময় fresh থাকে।
- Downside: Write ধীর হয়। আর DB তে write সফল হলো কিন্তু cache এ write fail করলে, কেউ টের না পেয়েই দুই জায়গায় দুই রকম data থেকে যায়।
Update হলে DB তে write করা হয়, আর cache এর entry টা ডিলিট করে দেওয়া হয়। পরের read টা তখন miss হয়, আর DB থেকে fresh data এসে cache এ জমা হয়।
- সুবিধা: নিয়মটা সহজ। Cache এ হয় সঠিক data থাকে, নয়তো কিছুই থাকে না। ভুল data থাকে না।
- Downside: Delete এর পরপরই একসাথে অনেক read এলে অনেকগুলো miss হয়, আর DB তে চাপ পড়ে।
প্রতিটা cache entry একটা নির্দিষ্ট সময় পর (যেমন ৬০ সেকেন্ড) নিজে থেকেই expire হয়ে যায়।
- সুবিধা: খুব সহজ। Invalidation এর code এ ভুল থাকলেও entry একসময় নিজে থেকেই সরে যায়, আর DB থেকে fresh data আসে।
- Downside: TTL শেষ না হওয়া পর্যন্ত cache পুরোনো data দেখাতে পারে।
Real system এ তিনটা একসাথে
- Read এর জন্য Cache-aside ব্যবহার হয়।
- Invalidation এর জন্য Delete-on-write ব্যবহার হয়।
- Invalidation fail করলে বাঁচার জন্য TTL রাখা হয়।
এখানে একাধিক স্তরে সুরক্ষা আছে। একটা fail করলে আরেকটা কাজ করে।
০৫ Cache full হলে কী হবে?
Cache এর memory সীমিত। Memory full হলে কিছু entry সরিয়ে জায়গা খালি করতে হয়। এটাকে বলে Eviction (ইভিকশন)।
| Policy | আচরণ | কখন ব্যবহার করবেন |
|---|---|---|
| LRU (Least Recently Used) | যে entry সবচেয়ে বেশি সময় ধরে কেউ read করেনি, সেটা সরায় | সবচেয়ে common, বাস্তবে বেশিরভাগ ক্ষেত্রে ভালো কাজ করে |
| LFU (Least Frequently Used) | যে entry সবচেয়ে কম বার read হয়েছে, সেটা সরায় | সম্প্রতি কে read হলো তার চেয়ে কে বেশি জনপ্রিয় সেটা জরুরি হলে |
| FIFO (First In First Out) | যে entry সবার আগে cache এ এসেছে, সেটা সরায় | সহজ, কিন্তু বেশিরভাগ ক্ষেত্রে ভুল strategy (শুধু কখন entry এসেছে সেটা দেখে, কতবার ব্যবহার হয়েছে সেটা দেখে না) |
| TTL | নির্দিষ্ট সময় পর entry ডিলিট করে | সাধারণত অন্য policy (LRU/LFU) এর সাথে মিলিয়ে ব্যবহার হয় |
Real system এ বেশিরভাগ সময় LRU ব্যবহার হয়।
০৬ Invalidation বনাম Eviction এর পার্থক্য কী?
অনেকেই Invalidation আর Eviction, এই দুটো term গুলিয়ে ফেলেন।
কে করে: আপনি (application code)।
DB এর data বদলায়। তখন আপনি নিজে cache কে জানান, “এই entry আর valid না।”
এর দুটো উপায় আছে:
- Delete করুন: Entry টা সরিয়ে দিন। পরের read এ cache miss হয়, DB থেকে fresh data আসে, আর cache আবার ভরে যায়। এটা সহজ আর নিরাপদ।
- Replace করুন: Entry ডিলিট না করে নতুন data দিয়ে বদলে দিন। পরের read সরাসরি cache থেকেই data পায়, DB তে যেতে হয় না।
উপায় আলাদা, কিন্তু লক্ষ্য একটাই: cache এ যেন পুরোনো data না থাকে।
কে করে: Cache নিজে।
Cache নিজেই entry সরিয়ে দেয়, আপনাকে জিজ্ঞেস করে না।
যেমন memory full হলো। তখন LRU policy সেই entry সরায়, যেটা সবচেয়ে বেশি সময় ধরে কেউ read করেনি। অথবা কোনো entry এর TTL শেষ হলো, তাই সেটা expire হয়ে গেলো।
| Invalidation | Eviction | |
|---|---|---|
| কে সরায় | আপনি (application code) | Cache নিজে |
| কেন সরায় | Source of truth বদলে গেছে | Memory full, TTL শেষ, বা restart |
| Goal | Freshness নিশ্চিত করা | Memory manage করা |
| পরের read এ কী হয় | Delete করলে miss হয়, DB থেকে fresh data আসে। Replace করলে সরাসরি cache থেকে latest data পাওয়া যায়। | Miss হয়, DB থেকে data আসে (থাকলে) |
০৭ সব কিছু cache করবো?
প্রতিটা data এর জন্য তিনটা প্রশ্ন করুন:
- এই data কি প্রায়ই read হয়?
- এই data কি ঘন ঘন বদলায়?
- একটু পুরোনো data দেখালে কি চলবে?
ভালো cache candidate এর উদাহরণ:
| Data | কেন |
|---|---|
| User profile | প্রায়ই read হয়, কম বদলায়, একটু পুরোনো হলেও চলে |
| Product catalog | সবসময় read হয়, কম বদলায় |
| Homepage feed | অনেক user এর জন্য একই, হিসাব করতে অনেক খরচ |
| Top 10 trending posts | হিসাব করতে অনেক খরচ, একটু পুরোনো হলেও চলে |
| Search results | জনপ্রিয় query বারবার আসে, short TTL দিয়ে cache করুন |
খারাপ cache candidate এর উদাহরণ:
| Data | কেন |
|---|---|
| Bank account balance | পুরোনো হলে মারাত্মক ভুল হয় |
| Live chat messages | সারাক্ষণ বদলায় |
| Real-time stock price | পুরোনো হলে ভুল হয় |
| One-time token | একবার ব্যবহারের জন্য, cache এ রেখে কোনো লাভ নেই |
“সবকিছু cache করুন” কেন বিপজ্জনক
- Cache free না: Memory এর খরচ আছে।
- পুরোনো data এর ক্ষতি সব জায়গায় সমান না: Tweet এর count একটু পুরোনো হলে চলে, কিন্তু bank balance পুরোনো হলে চলে না।
- কিছু data এত দ্রুত বদলায় যে cache এ রাখার আগেই সেটা পুরোনো হয়ে যায়।
- কিছু data প্রতিটা request এর জন্য আলাদা: এগুলো cache করে কোনো লাভ নেই।
যে data প্রায়ই read হয়, যেটা বানাতে সময় লাগে, আর যেটা একটু পুরোনো হলেও চলে, সেটা cache করুন। Critical real-time data বা একবার ব্যবহারের data cache করবেন না।
০৮ Production caching এ কী কী জটিলতা আসতে পারে?
সমস্যা ১: Cache Stampede (Thundering Herd)
একটা জনপ্রিয় cached item expire হলো। ঠিক সেই মুহূর্তে হাজার হাজার request এসে cache miss পেলো। সবাই একসাথে DB তে query পাঠালো। DB এত চাপ নিতে না পেরে crash করলো।
At t=60s: cache entry expire হলো। At t=60.001s: ১০,০০০ request এলো। ১০,০০০টাই cache miss করলো। ১০,০০০টাই DB তে query পাঠালো। DB এত চাপ নিতে না পেরে down হলো।
সমাধান:
- Lock + recompute: শুধু একটা request DB তে যায়, বাকিরা অপেক্ষা করে।
- Stale-while-revalidate: একটা request fresh data আনতে যায়। ততক্ষণ বাকিরা পুরোনো value পায়।
- TTL jitter: প্রতিটা entry এর TTL এ একটু random পার্থক্য রাখা হয়। যেমন সবাইকে ঠিক ৬০ second না দিয়ে ৫৫ থেকে ৬৫ second এর মধ্যে আলাদা আলাদা সময় দেওয়া হয়। তাহলে সব entry একসাথে expire হয় না।
সমস্যা ২: Cache Penetration
এমন data এর জন্য request আসে, যেটা DB তেই নেই। এখানে cache কোনো সাহায্য করতে পারে না।
Request: "Get user_999999999" (নেই) Cache: miss DB: nothing Cache: store করার মতো কিছু নেই Request আবার এলো → DB আবার query → অনন্তকাল চলবে...
সমাধান:
- “পাওয়া যায়নি” উত্তরটাও cache করুন: “NOT_FOUND” কিছু সময়ের জন্য cache এ রেখে দিন।
- Bloom filter ব্যবহার করুন: Bloom filter একটা probabilistic data structure, অর্থাৎ এটা সম্ভাবনার ভিত্তিতে উত্তর দেয়। এটা খুব দ্রুত বলে দিতে পারে, “এই key টা DB তে নিশ্চিতভাবে নেই” অথবা “হয়তো আছে”। Bloom filter “নেই” বললে DB তে query করার দরকারই নেই, request টা সরাসরি reject করুন। এভাবে cache penetration attack থেকে DB রক্ষা পায়।
সমস্যা ৩: Cache Avalanche
অনেকগুলো cache entry একসাথে expire হলো, অথবা cache server নিজেই down হলো। তখন সব চাপ গিয়ে পড়ে DB তে, আর DB সামলাতে পারে না।
সমাধান:
- TTL jitter: Entry গুলোর expire হওয়ার সময় একটু করে আলাদা রাখুন, যাতে সব একসাথে expire না হয়।
- Cache redundancy: একাধিক cache server রাখুন, যাতে একটা down হলেও অন্যটা কাজ করে।
- Graceful degradation: মানে পুরো system বন্ধ না করে একটু ধীরে বা কম সেবা দিয়ে চালু থাকা। Cache হঠাৎ down হলে সব request একসাথে DB তে চলে আসে। DB সেই চাপ নিতে না পেরে crash করে। তাই একটা rate limit সেট করুন, অর্থাৎ প্রতি second এ সর্বোচ্চ কতগুলো request DB তে যাবে তার একটা সীমা। বাকি request গুলোকে অপেক্ষা করান বা reject করুন। Application ধীর হবে, কিন্তু পুরো system fail করবে না।
সমস্যা ৪: Cold Cache
Cache restart হওয়ার মুহূর্তে cache পুরোপুরি খালি থাকে। তখন প্রতিটা request miss করে, আর DB overloaded হয়ে যায়।
সমাধান: Cache warming, অর্থাৎ traffic আসার আগেই জরুরি data দিয়ে cache ভরে রাখা।
০৯ System এখন দেখতে কেমন?
সেশন ০৩ এর system এর সাথে এখন একটা Cache layer যোগ হলো। অনেক read এখন database পর্যন্ত যায়ই না।
এখন পর্যন্ত কী কী ঠিক করা হলো?
- DB এর load অনেক কমেছে: বেশিরভাগ read এখন cache থেকেই উত্তর পায়।
- Response time অনেক কমেছে: DB query তে প্রায় ১০ms লাগতো। Redis থেকে আনতে network সহ প্রায় ১ms লাগে।
- একই DB এখন আরো বেশি traffic সামলাতে পারে: Cache hit rate ৯৫% হলে মাত্র ৫% request DB তে যায়, তাই DB এর load ২০ গুণ কমে।
নতুন যেসব সমস্যা তৈরি হলো
- Cache Invalidation: DB তে data বদলালে cache এর সেই entry কখন আর কীভাবে আপডেট বা ডিলিট করবো, সেটা সামলানো কঠিন।
- Cache Stampede / Penetration / Avalanche: Cache কাজ না করলে সব চাপ একসাথে DB তে পড়ে, আর DB down হয়ে যেতে পারে।
- Cold cache: Cache restart হলে সব load DB তে যায়, যেটা বিপজ্জনক।
- Memory cost: Cache এর জন্য আলাদা machine লাগে।
যা এখনো বাকি
- দূরের user: Cache একটা data center এ থাকলে শুধু সেই এলাকার user রা সুবিধা পান। অন্য মহাদেশের user দের জন্য network latency রয়েই গেছে। দূরত্বের কারণে cache তাদের খুব একটা সাহায্য করতে পারে না।
- Static content (image, CSS, JS): একটা web page এ database call হয়তো ২-৩ টা, কিন্তু image/CSS/JS file থাকতে পারে ৫০-১০০ টা। এই static file গুলো প্রতিবার origin server থেকে download হচ্ছে। প্রতিটা file এর জন্য পুরো network round trip লাগছে।
- সব write এখনো এক Primary তে: Cache শুধু read এ সাহায্য করছে।
১০ মগজে প্রেশার দিন
আগে নিজে ভাবুন। তারপর দেখুন সবাই যেভাবে ভাবে, কেন সেটা ভুল, আর সঠিক চিন্তা কী।
উত্তর দেখুন আগে নিজে ভাবুন
সবাই যেভাবে ভাবে
“Hit rate কমলে DB তে বেশি request যায়, তাই DB একটু ধীর হয়।”
এই চিন্তা ঠিক দিকে যাচ্ছে, কিন্তু আসল বিপদটা এখানে miss করছে।
আসল হিসাব দেখুন
ধরুন system প্রতি second এ ১০,০০০ request সামলায়।
- ৯৫% hit rate এ: ৯,৫০০টা cache থেকে আসে, DB তে যায় ৫০০টা query।
- ৫০% hit rate এ: ৫,০০০টা cache থেকে আসে, DB তে যায় ৫,০০০টা query। DB এর load ১০ গুণ হয়ে যায়।
DB কে বানানো হয়েছিলো প্রতি second এ ৫০০টা query সামলানোর জন্য। এখন আসছে ৫,০০০টা। কী হবে?
- DB ধীর হয়, query timeout হয়, connection জমতে থাকে।
- DB এর CPU ১০০% এ পৌঁছায়, আর DB down হয়ে যায়।
Death Spiral: যে চক্র নিজে থামে না
DB overloaded হলে query ধীর হয়। ফলে cache এ নতুন data পৌঁছাতে দেরি হয়। Cache miss আরো বাড়ে, আর hit rate আরো নামে। এতে আরো request DB তে যায়। আগে থেকেই চাপে থাকা DB তে আরো load পড়ে। শেষে DB পুরোপুরি down হয়ে যায়।
Cache hit rate শুধু efficiency মাপার সংখ্যা না। এটা একটা safety সীমা। DB এর ক্ষমতা সাধারণত এটা ধরে নিয়েই ঠিক করা হয় যে cache বেশিরভাগ traffic সামলাবে।
উত্তর দেখুন আগে নিজে ভাবুন
সবাই যেভাবে ভাবে
“User profile cache করবো। বাকি কিছু না।”
এই উত্তর খুব ছোট, আর এতে কোনো যুক্তি নেই। প্রতিটা case আলাদা করে বিচার করতে হবে। বিচারের প্রশ্ন তিনটা: data টা কি প্রায়ই read হয়, ঘন ঘন বদলায় কিনা, আর একটু পুরোনো হলে চলে কিনা।
প্রতিটা case চেক
| Item | রায় | কেন |
|---|---|---|
| User profile | CACHE | প্রায়ই read হয়, কম বদলায়, একটু পুরোনো হলেও চলে |
| Search results | CACHE (সাবধানে) | জনপ্রিয় query বারবার আসে, short TTL দিন। Google, Amazon প্রচুর cache করে। |
| Bank balance | CACHE করবেন না | পুরোনো হলে আইনি ঝামেলা হতে পারে |
| Live chat messages | CACHE করবেন না | সারাক্ষণ বদলায়; websocket বা push ব্যবহার করুন (browser আর server এর মধ্যে খোলা connection, যেটা দিয়ে server নিজেই নতুন message পাঠায়) |
“সবকিছু cache” কেন বিপজ্জনক
কারণগুলো সেশনের ০৭ নম্বর অংশে (“সবকিছু cache করুন” কেন বিপজ্জনক) দেখেছি: memory এর খরচ, পুরোনো data এর ক্ষতি, খুব দ্রুত বদলানো data, আর প্রতি request এ আলাদা data।
“কোথায় ঠিক, কোথায় ভুল” জিজ্ঞেস করলে প্রতিটা case ধরে ধরে বিশ্লেষণ করুন। প্রতিটা সিদ্ধান্তের পেছনে যুক্তি দিন।
উত্তর দেখুন আগে নিজে ভাবুন
সবাই যেভাবে ভাবে
“সবচেয়ে নিরাপদ হলো write-through। Trade-off হলো: write-through এ write ধীর, delete-on-write এ cache miss, আর TTL এ পুরোনো data।”
এই চিন্তা আসল সমস্যাটাই ধরতে পারেনি।
আসল সমস্যা চিনুন
এখানে আসল সমস্যা হলো মানুষের ভুল। কেউ একটা code path এ invalidation লিখতে ভুলে গেছে। যেমন একটা admin script সরাসরি DB তে price বদলেছে, cache এ হাত দেয়নি। তাহলে সঠিক প্রশ্ন হলো: কোন strategy কারো মনে রাখার উপর নির্ভর করে না?
কোনটা code ছাড়া কাজ করে
- Write-through: DB তে write করার সময় code কেই cache এ write করতে হয়। যে code path এটা করতে ভুলে গেছে, সেখানে write-through কোনো সাহায্য করে না।
- Delete-on-write: Code কেই cache থেকে entry ডিলিট করতে হয়। একই কারণে ভুলে যাওয়া code path এ এটাও কাজ করে না।
- TTL: Cache নিজেই entry expire করে দেয়, কোনো code লাগে না। তাই কেউ ভুলে গেলেও পুরোনো price সর্বোচ্চ TTL এর সময় পর্যন্ত থাকে, তারপর নিজে থেকেই ঠিক হয়ে যায়।
অর্থাৎ এই scenario তে শুধু TTL কাজ করে।
কোন strategy কখন fail করে (trade-off)
| Strategy | Failure mode |
|---|---|
| Write-through | কোনো code path cache এ write না করলে, বা cache write fail করলে, cache এ পুরোনো data থেকে যায়, কেউ টের পায় না |
| Delete-on-write | কোনো code path delete না করলে, বা delete fail করলে (কম ঘটে, কিন্তু সম্ভব), cache এ পুরোনো data থেকে যায় |
| TTL only | কাউকে কিছু মনে রাখতে হয় না, কিন্তু TTL শেষ না হওয়া পর্যন্ত পুরোনো data দেখানোর একটা সময় থাকবেই |
আসল উত্তর: একসাথে ব্যবহার
অভিজ্ঞ team গুলো দুটো একসাথে ব্যবহার করে:
- Delete-on-write হলো মূল mechanism: Data বদলালে সাথে সাথে cache ঠিক হয়ে যায়। ভুলে যাওয়ার সুযোগ কমাতে এই code এক জায়গায় রাখুন, যাতে price বদলানোর সব পথ সেই এক জায়গা দিয়েই যায়।
- Short TTL হলো safety net: কেউ ভুলে গেলে বা delete fail করলে TTL নিশ্চিত করে যে পুরোনো data বেশিক্ষণ থাকবে না।
বেশিরভাগ real system এ এই approach ই ব্যবহার হয়।
সবসময় ভাবুন, fail হলে কী হবে? Real system এ speed এর চেয়ে failure সামলানো বেশি জরুরি।
১১ যে টার্মগুলো শিখলাম
| টার্ম | মানে |
|---|---|
| Cache | সময় বা খরচ লাগে এমন কাজের result একটা দ্রুত storage এ রাখা। |
| Cache hit | Data cache এ পাওয়া গেছে, তাই দ্রুত উত্তর আসে। |
| Cache miss | Data cache এ ছিলো না, মূল DB তে যেতে হয়। |
| Hit rate | মোট request এর কত শতাংশ cache থেকে উত্তর পেলো। এটা একটা জরুরি safety মাপকাঠি। |
| Cache-aside | Application আগে cache দেখে, miss হলে DB থেকে এনে cache এ রাখে। সবচেয়ে common pattern। |
| Write-through | DB আর cache একই কাজে একসাথে update হয়। |
| Delete-on-write | DB update এর পর cache এর entry ডিলিট করা। |
| TTL (Time To Live) | নির্দিষ্ট সময় পর cache entry নিজে থেকে expire হয়। |
| Cache invalidation | Cache কে source of truth এর সাথে মিলিয়ে রাখা। |
| Eviction | Cache full হলে entry সরানো। |
| LRU / LFU / FIFO | Eviction policy: সবচেয়ে বেশি সময় read না হওয়া / সবচেয়ে কম read হওয়া / সবার আগে আসা entry সরানো। |
| Cache stampede | জনপ্রিয় entry expire হলে একসাথে অনেক miss। |
| Cache penetration | DB তে নেই এমন data এর জন্য বারবার query। |
| Cache avalanche | অনেক entry একসাথে expire হওয়া, বা cache server down হওয়া। |
| TTL jitter | প্রতিটা entry এর TTL এ একটু random পার্থক্য রাখা। |
| Stale-while-revalidate | একটা request fresh data আনার সময় বাকিদের পুরোনো value দেওয়া। |
| Cold cache | খালি cache। তখন DB পুরো load পায়। |
| Cache warming | Traffic আসার আগেই cache ভরে রাখা। |
| Bloom filter | সম্ভাবনার ভিত্তিতে কাজ করা একটা structure, যেটা “এই key নিশ্চিতভাবে নেই” বলতে পারে। |
| Redis / Memcached | জনপ্রিয় distributed cache system, যেগুলো data RAM এ key-value আকারে রাখে। |
১২ শর্ট সামারি
- Caching মানে খরচের কাজের result দ্রুত memory তে রেখে দেওয়া, যাতে কাজটা আবার করতে না হয়। এতে ধীর কাজ প্রায় সাথে সাথে শেষ হওয়া একটা memory lookup এ বদলে যায়।
- Caching নিজে কঠিন না। কঠিন হলো invalidation (cache fresh রাখা) আর eviction (কী সরাবো)। Cache-aside, delete-on-write আর TTL একসাথে ব্যবহার করাই সবচেয়ে common।
- Cache এর failure গুলোর নাম আছে: stampede, penetration, avalanche। প্রতিটার জানা সমাধানও আছে।
১৩ মনে রাখুন
- Cache hit rate একটা safety মাপকাঠি, শুধু performance এর না: Hit rate নামলে DB down হয়ে যেতে পারে।
- “এটা কি cache করবো?” এর জন্য একটা নিয়ম মেনে চলুন: Data টা প্রায়ই read হয় কিনা, ঘন ঘন বদলায় কিনা, আর একটু পুরোনো হলে চলে কিনা, এই তিনটা প্রশ্ন করুন।
- কোনো invalidation strategy ই একা যথেষ্ট না: Delete-on-write আর short TTL একসাথে ব্যবহার করুন।
- সবসময় ভাবুন, fail হলে কী হবে: Speed এর চেয়ে failure mode বেশি জরুরি।
- Cache failure এর নামগুলো জানুন: stampede, penetration, avalanche। সেই সাথে প্রতিটার সমাধানও জানুন।
- DB ই source of truth: Cache শুধু গতি বাড়ানোর layer, উল্টোটা কখনো না।
- Cold cache বিপজ্জনক: Cache restart এর পর traffic আসার আগেই cache ভরে নিন।