Cloudflare এর হাতেখড়ি (পর্ব ৮) – KV পরিচিতি: কী-ভ্যালু ক্যাশ ও সেটিংস

Cloudflare KV পরিচিতি কী-ভ্যালু ক্যাশ ও সেটিংস

আগের পর্বে R2 দিয়ে ফাইল স্টোরেজ শিখেছিলাম। এবার একদম ভিন্ন ধরনের একটা স্টোরেজ — KV (Key-Value)। এটা ছবি বা বড় ফাইলের জন্য না, বরং ছোট ছোট ডেটা — সেটিংস, ফ্ল্যাগ, ক্যাশড রেসপন্স — যা খুব দ্রুত পড়তে হয়, সারা বিশ্বের যেকোনো জায়গা থেকে।

KV কী এবং RTDB থেকে কীভাবে আলাদা

Firebase এর হাতেখড়ি সিরিজে আমরা RTDB শিখেছিলাম — রিয়েল-টাইম, জটিল query করা যায়, কিন্তু প্রতিটা read একটা নেটওয়ার্ক রাউন্ড-ট্রিপ। KV পুরোপুরি ভিন্ন দর্শনে বানানো — এটা eventually consistent (সাথে সাথে সব জায়গায় আপডেট নাও হতে পারে, কয়েক সেকেন্ড লাগতে পারে), কিন্তু বিনিময়ে read অস্বাভাবিক দ্রুত, কারণ ডেটা Cloudflare-এর গ্লোবাল নেটওয়ার্কের প্রতিটা লোকেশনে ক্যাশড থাকে।

KV vs RTDB — কখন কোনটা

বিষয় RTDB KV
ডেটা আপডেট দেখা যায় সাথে সাথে (রিয়েল-টাইম) কিছু সেকেন্ড দেরি হতে পারে
Query ক্ষমতা orderByChild, ফিল্টার শুধু key দিয়ে সরাসরি খোঁজা
Read গতি দ্রুত অতি দ্রুত (এজ ক্যাশড)
সেরা ব্যবহার লাইভ চ্যাট, ইউজার ডেটা, Todo সেটিংস, ফিচার ফ্ল্যাগ, API রেসপন্স ক্যাশ

সহজ নিয়ম — যদি ডেটা প্রায়ই বদলায় আর সাথে সাথে সবাইকে দেখাতে হয়, RTDB। যদি ডেটা কম বদলায় কিন্তু বারবার পড়তে হয় (আর দ্রুততম হতে হয়), KV।

Namespace তৈরি করা

KV-তে ডেটা রাখার জায়গাকে বলে Namespace — R2-এর bucket, বা RTDB-এর পুরো ডেটাবেজের মতোই একটা কনটেইনার।

wrangler kv namespace create "SITE_SETTINGS"

# আউটপুটে একটা id পাওয়া যাবে, সেটা wrangler.toml-এ বসাতে হবে
# wrangler.toml
name = "my-worker"
main = "src/index.js"

[[kv_namespaces]]
binding = "SITE_SETTINGS"
id = "abc123def456..."   # wrangler kv namespace create থেকে পাওয়া id

ডেটা লেখা ও পড়া

R2-এর মতোই put() আর get(), কিন্তু এখানে ফাইলের বদলে টেক্সট/JSON।

export default {
  async fetch(request, env, ctx) {
    // লেখা
    await env.SITE_SETTINGS.put("maintenance_mode", "false");

    // পড়া
    const value = await env.SITE_SETTINGS.get("maintenance_mode");

    return new Response(`Maintenance mode: ${value}`);
  },
};

JSON রাখতে চাইলে JSON.stringify/JSON.parse নিজে করতে হয় (Advanced JS-এর প্যাটার্ন), অথবা সরাসরি get(key, "json") ব্যবহার করা যায়।

// লেখা
await env.SITE_SETTINGS.put("homepage_config", JSON.stringify({
  theme: "dark",
  featuredBook: "অপরাজিত",
}));

// পড়া — সরাসরি অবজেক্ট হিসেবে
const config = await env.SITE_SETTINGS.get("homepage_config", "json");
console.log(config.theme); // "dark"

Expiration — নিজে থেকে মুছে যাওয়া ডেটা

KV-এর একটা শক্তিশালী ফিচার — একটা নির্দিষ্ট সময় পর ডেটা নিজে থেকেই মুছে যেতে পারে, ক্যাশিং-এর জন্য এটা খুবই কাজের।

// ৬০ সেকেন্ড পর নিজে থেকে মুছে যাবে
await env.SITE_SETTINGS.put("temp_token", "xyz123", {
  expirationTtl: 60, // সেকেন্ডে
});

বাস্তব ব্যবহার — API রেসপন্স ক্যাশ করা

পর্ব ৬-এ আমরা Worker থেকে RTDB কল করেছিলাম। ধরা যাক /api/books-এ বারবার একই রিকোয়েস্ট আসছে — প্রতিবার RTDB-তে না গিয়ে, KV-তে কিছুক্ষণের জন্য ক্যাশ করে রাখা যায়।

export default {
  async fetch(request, env, ctx) {
    // প্রথমে ক্যাশ চেক করা
    const cached = await env.SITE_SETTINGS.get("books_list", "json");
    if (cached) {
      return new Response(JSON.stringify(cached), {
        headers: { "content-type": "application/json", "x-cache": "HIT" },
      });
    }

    // ক্যাশে না থাকলে RTDB থেকে আনা
    const res = await fetch("https://my-first-app-default-rtdb.firebasedatabase.app/books.json");
    const books = await res.json();

    // পরের বারের জন্য ৫ মিনিট ক্যাশ করে রাখা
    await env.SITE_SETTINGS.put("books_list", JSON.stringify(books), { expirationTtl: 300 });

    return new Response(JSON.stringify(books), {
      headers: { "content-type": "application/json", "x-cache": "MISS" },
    });
  },
};

এই প্যাটার্নে প্রথম রিকোয়েস্টের পর পরবর্তী ৫ মিনিটে যত রিকোয়েস্টই আসুক, RTDB-তে না গিয়ে সরাসরি KV থেকে অতি দ্রুত রেসপন্স পাওয়া যাবে — RTDB-এর ওপর চাপ কমে, রেসপন্স টাইমও কমে।

ইন্টারেক্টিভ — Cache Hit/Miss সিমুলেশন

নিচে বারবার "রিকোয়েস্ট পাঠাও" চেপে দেখো প্রথমবার MISS (RTDB থেকে আনা), পরেরবারগুলো HIT (KV থেকে দ্রুত) কীভাবে দেখায়।

ভালো অভ্যাস

  • KV-তে ঘন ঘন বদলানো ডেটা রাখবেন না — eventually consistent হওয়ায় সাথে সাথে সব জায়গায় নাও দেখাতে পারে; সেটার জন্য RTDB উপযুক্ত
  • ক্যাশিং-এ সবসময় একটা যুক্তিসঙ্গত expirationTtl দিন — নাহলে পুরনো ডেটা অনির্দিষ্টকাল থেকে যেতে পারে
  • সেনসিটিভ, ঘন ঘন-বদলানো ইউজার ডেটার জন্য KV না, RTDB বা D1 (পরের পর্ব) ব্যবহার করুন

নিজে চেষ্টা করো

Exercise:

  1. একটা KV namespace তৈরি করো, নিজের Worker-এ binding যোগ করো।
  2. একটা সেটিংস অবজেক্ট (যেমন থিম, ফিচার্ড কনটেন্ট) JSON আকারে KV-তে সেভ করো, তারপর ফিরে পেয়ে দেখো।
  3. উপরের ক্যাশিং প্যাটার্ন দিয়ে নিজের কোনো RTDB নোড ৫ মিনিটের জন্য ক্যাশ করে দেখো — x-cache হেডার চেক করে HIT/MISS যাচাই করো।
  4. expirationTtl দিয়ে একটা টেম্পোরারি ডেটা সেভ করো, কিছুক্ষণ পর সেটা সত্যিই মুছে গেছে কিনা চেক করো।

পরের পর্বে যা থাকছে

পরের পর্বে আমরা শিখব D1 পরিচিতি — Cloudflare-এর SQLite-ভিত্তিক ডেটাবেজ, যেখানে RTDB-এর JSON ট্রি-এর বদলে চেনা SQL টেবিল-স্টাইলে ডেটা রাখা যায়, আর কখন এটা RTDB/KV-এর চেয়ে ভালো পছন্দ।

একটি মন্তব্য পোস্ট করুন

নবীনতর পূর্বতন

যোগাযোগ ফর্ম