আপনার menu page-টা প্রতিদিন হাজার বার দেখা হয়, কিন্তু menu বদলায় সপ্তাহে একবার। তবু প্রতিটা view-তেই database-এ একই query ছুটছে, একই data আসছে। এটা অনেকটা এরকম - একই ঠিকানা বারবার খাতা খুলে খোঁজা, অথচ ঠিকানাটা ফোনে সেভ করলেই হতো। Cache হলো সেই সেভ করা ব্যবস্থা: ঘন ঘন লাগা data দ্রুত জায়গা (Redis - memory-তে থাকে) রেখে দেওয়া, যাতে database-এর কাছে প্রতিবার যেতে না হয়।
Cache-aside pattern - সবচেয়ে বেশি ব্যবহৃত ছক
async function getMenu() {
const cached = await redis.get("menu:all");
if (cached) return JSON.parse(cached); // cache hit
const menu = await db.menu.findMany(); // cache miss - database থেকে
await redis.set("menu:all", JSON.stringify(menu), "EX", 300); // ৫ মিনিট TTL
return menu;
}ছকটা সরল: প্রথমে cache-এ খুঁজুন, পেলে সঙ্গে সঙ্গে ফেরত দিন। না পেলে database থেকে এনে cache-এ রেখে দিন, যাতে পরের জন পেয়ে যায়। EX 300 হলো TTL - ৫ মিনিট পর cache নিজে থেকেই মুছে যাবে, পরের request-এ টাটকা data আসবে।
Invalidation - cache-এর আসল কঠিন সমস্যা
Cache-এর সবচেয়ে জটিল প্রশ্নটা হলো: data বদলে গেলে পুরনো cache কখন সরাবেন? Admin menu-তে দাম বদলালেন, কিন্তু cache-এ পুরনো দাম রয়ে গেল - customer ভুল দাম দেখবে। দুটো অস্ত্র আছে: TTL (নিজে থেকে expire হওয়া - মাঝে মাঝে পুরনো data দেখা মেনে নেওয়া যায় এমন জায়গায়), আর সক্রিয় invalidation - data বদলালেই সংশ্লিষ্ট cache key মুছে দেওয়া।
// দাম বদলালেই menu cache ফেলে দিন
async function updateMenuItem(id, data) {
const item = await db.menu.update({ where: { id }, data });
await redis.del("menu:all");
return item;
}কী cache করবেন সেটাও বিচার: যা ঘন ঘন পড়া হয় কিন্তু কম বদলায় (menu, settings, জনপ্রিয় product) - সেগুলো। যা প্রতিবারই আলাদা বা সবসময় নির্ভুল থাকতেই হবে (bank balance, stock-এর শেষ অবস্থা) - সেখানে সাবধান, কিংবা cache-ই করবেন না।
সবাই যে ভুলটা করে
Cache করে TTL বা invalidation-এর ব্যবস্থা না রাখা - তাহলে পুরনো data অনন্তকাল ধরে ঘুরতে থাকে। উল্টোটাও ভুল: সবকিছু cache করা। Cache যত বাড়ে, stale data-র ঝুঁকি তত বাড়ে। যেখানে সুবিধা পরিষ্কার, শুধু সেখানেই cache।
আজকের Practice
আপনার API-তে Redis বসিয়ে menu বা product list endpoint-এ cache-aside pattern যোগ করুন। তারপর দুইবার request পাঠিয়ে সময় মাপুন - প্রথমবার database থেকে, দ্বিতীয়বার cache থেকে। শেষে একটা আইটেম আপডেট করে দেখুন invalidation কাজ করছে কিনা।
Interview-এ কীভাবে বলবেন
আমি cache-aside pattern ব্যবহার করি - আগে Redis-এ খুঁজি, না পেলে database থেকে এনে TTL দিয়ে রেখে দিই। Invalidation-এর জন্য যেখানে data বদলানো সঙ্গে সঙ্গে দেখাতেই হবে, সেখানে update-এর সময় key মুছে দিই; যেখানে সামান্য পুরনো data চলবে, সেখানে শুধু TTL-ই যথেষ্ট।