কম্পিউটার টিউটোরিয়াল

রেডিস ক্যাশিং দিয়ে গ্লোবাল ডাটাবেস পারফরম্যান্স ত্বারান্বিত করুন

একটি সফটওয়্যার অ্যাপ্লিকেশন শুধু ততটুকু 가치 থাকে যতটুকু সেটি তার কাস্টমারদের চাহিদা পূরণ করতে পারে। কাস্টমারদের চাহিদা বিবেচনা করলে, প্রথম দাবি যা আমরা পাই সেটি হলো অ্যাপ্লিকেশনের গতি এবং ডেটা নির্ভরযোগ্যতা। য وكيفে অ্যাপ্লিকেশন বৃদ্ধি পায় এবং গ্লোবালি বিস্তৃত হয়, SQL ডাটাবেস বাড়তি কোয়েরি ভলিউম, উচ্চ লেটেন্সি, এবং ভৌগলিকভাবে ছড়ানো ইউজার বেসের কারণে প্রায়শই পারফরম্যান্স বটলনেক হয়ে ওঠে।

অ্যাপ্লিকেশন বৃদ্ধি পেলে এই সমস্যাগুলো সমাধানের জন্য, ক্যাশিং হলো প্রথম সমাধান যা প্রাইমারি ডাটাবেসের লোড কমায় রিপিটেড কোয়েরির জন্য এবং লেটেন্সি কমায় যখন ইউজার কোয়েরি সাবমিট করে। ক্যাশ বললে সবার মনে একই টুল আসে, সঠিক? হ্যাঁ, সেটি রেডিস। রেডিস ডেটা ক্যাশ করার জন্য একটি পারফেক্ট টুল যা লোড কমায় এবং অ্যাপ্লিকেশনকে দ্রুত করে। আপস্ট্যাশও রেডিস রেপ্লিকেশন গ্লোবালি ডিস্ট্রিবিউটেড প্রদান করে, যা অ্যাপ্লিকেশনকে একটি রেগুলার ক্যাশের চেও দ্রুত করে।

এই ব্লগে, আমরা গ্লোবাল রেডিসকে SQL ডাটাবেসের সাথে ইন্টিগ্রেট করার টেকনিক্যাল সুবিধাগুলো এক্সপ্লোর করব, লেটেন্সি এবং স্কেলেবিলিটির ওপর এর প্রভাব আলোচনা করব, এবং পোস্টগ্রেসকিউএল এবং MySQL-এর সাথে গ্লোবাল রেডিস ব্যবহার করার হ্যান্ডস-অন উদাহরণ দেব।

ক্যাশিংয়ের সুবিধা

প্রথমে দেখি কেন আমাদের ক্যাশিং ব্যবহার করা উচিত।

ক্যাশিংয়ের দুটি প্রধান সুবিধা আছে যা আমি এই ব্লগে উল্লেখ করতে চাই: ডাটাবেস লোড কমানো এবং ইউজারদের জন্য লেটেন্সি কমানো।

ডাটাবেস লোড কমানো

SQL ডাটাবেস স্ট্রাকচার্ড ডেটা এবং জটিল কোয়েরি ম্যানেজ করতে দক্ষ, কিন্তু ভারী লোডের অধীনে তারা একটি বটলনেক হতে পারে। একই ডেটার জন্য রিপিটেড কোয়েরির উচ্চ ভলিউম — যেমন প্রোডাক্ট ডিটেইলস, ইউজার প্রোফাইল, বা ঘন ঘন অ্যাক্সেসড সেটিংস — উল্লেখযোগ্য CPU এবং I/O রিসোর্স খরচ করে। এই রেজাল্টগুলো ক্যাশ করলে ডাটাবেসে হিট হওয়া কোয়েরির সংখ্যা 劇的に কমে যায়, যা ডাটাবেসকে আরও ক্রিটিক্যাল টাস্কের মতো ট্রানজ্যাকশন প্রসেসিং এবং আপডেটে ফোকাস করতে দেয়।

উদাহরণস্বরূপ:

  • ক্যাশ ছাড়া: একটি ওয়েবসাইটের জনপ্রিয় ফিচার দৈনিক মিলিয়ন মিলিয়ন অভিন্ন ডাটাবেস কোয়েরি জেনারেট করে, অন্যান্য অপারেশনের পারফরম্যান্স ধীর করে।
  • ক্যাশ সহ: ঘন ঘন অ্যাক্সেসড কোয়েরি রেজাল্ট হাই-स্পিড ক্যাশে রেডিসের মতো সংরক্ষিত থাকে, ডাটাবেস কোয়েরি রেট ৯০% এর বেশি কমিয়ে দেয়।

লেটেন্সি কমানো

ডাটাবেস লোড কমানো ছিল সিস্টেম হেলথের জন্য ডেটা নির্ভরযোগ্যতা নিশ্চিত করতে। ক্যাশিং ইউজার রিকোয়েস্ট এবং কোয়েরি নেওয়ার সময়ও উন্নত করে।

যখন অ্যাপ্লিকেশন একই ডেটার জন্য বারবার ডাটাবেস কোয়েরি করে, ডেটা রিট্রিভাল সবসময় বেশি সময় নেয়। বিশেষ করে যদি এই কোয়েরিগুলো ডাটাবেসের ওপর বড় লোড তৈরি করে, সব এই দেরি আরও বাড়তে পারে। এটি বিশেষভাবে সমস্যাকারী那些 অ্যাপ্লিকেশনের জন্য যারা রিয়েল-টাইম ডেটা অ্যাক্সেস বা হাই কোয়ারি ভলিউম হ্যান্ডেল করে, যেখানে ছোট দেরিও পারফরম্যান্সে উল্লেখযোগ্য প্রভাব ফেলতে পারে।

ক্যাশিং এই সমস্যাটি সমাধান করে ঘন ঘন অ্যাক্সেসড ডেটা মেমরিতে সংরক্ষণ করে, যা ডাটাবেস কোয়েরি করার চেয়ে অনেক দ্রুত রিট্রিভ করা যায়। রিপিটেড রিকোয়েস্টের জন্য ডাটাবেস কোয়েরির ওপর নির্ভরতা কমিয়ে, ক্যাশিং নেটওয়ার্ক ট্রাভেল কমায় এবং জটিল কোয়েরি এক্সিকিউট করার কম্পিউটেশনাল ওভারহেড এড়িয়ে যায়। ফলস্বরূপ, রেসপন্স টাইম 劇的に উন্নত হয়, অ্যাপ্লিকেশনকে ভারী লোড বা ডিস্ট্রিবিউটেড এনভায়রনমেন্টে যেটি দ্রুত, আরও কনসিস্টেন্ট পারফরম্যান্স দিতে সক্ষম করে।

সাধারণ ক্যাশিং কৌশল

অ্যাপ্লিকেশন পারফরম্যান্স অপ্টিমাইজেশনে ব্যবহৃত দুটি প্রাইমারি ক্যাশিং কৌশল বুঝতে গুরুত্বপূর্ণ: cache-aside এবং write-through। প্রতিটি অ্যাপ্লিকেশনের চাহিদা অনুযায়ী তার ইউজ কেস এবং ট্রেড-অফ আছে।

Cache-aside সবচেয়ে সাধারণ ক্যাশিং টেকনিক। এই টেকনিকে, অ্যাপ্লিকেশন প্রথমে ডেটার জন্য ক্যাশ চেক করে। যদি ডেটা ক্যাশে না থাকে (ক্যাশ মিস), তবে এটি ডাটাবেস থেকে ডেটা রিট্রিভ করে এবং ভবিষ্যতের জন্য ক্যাশে লিখে।

এখানে একটি সিম্পল ডায়াগ্রাম যা দেখায় ক্যাশ-অসাইড কীভাবে কাজ করে, যা আপনি সবাই এই ব্লগে আসার আগে কোথাও দেখে থাকতে পারেন।

রেডিস ক্যাশিং দিয়ে গ্লোবাল ডাটাবেস পারফরম্যান্স ত্বারান্বিত করুন

এই ক্যাশিংয়ের সুবিধা হলো ক্যাশ সাইজ অপ্টিমাইজড থাকে, এবং ক্যাশ ডেটা ইউজারদের দরকার হলে রিলোড হয়। অন্যদিকে, অসুবিধা হলো ক্যাশ ক্লিন হলে যখন এর TTL শেষ হয়, তখন ডেটা উপলব্ধ থাকে না। সে সময়, ক্যাশ রিলোড হবে যখন ইউজার সেই ডেটা রিকোয়েস্ট করবে। এই কেসে, সেই ইউজারকে কোয়েরি সম্পন্ন হওয়ার জন্য অপেক্ষা করতে হবে। কিন্তু অবশ্যই, পরবর্তী রিকোয়েস্টগুলো আবার ক্যাশ থেকে ডেটা পাবে।

Write-through কৌশলে, ডাটাবেসে প্রতিটি রাইট অপারেশন সাথে সাথে ক্যাশেও লিখা হয়। এটি নিশ্চিত করে যে ক্যাশ সবসময় ডাটাবেস থেকে লেটেস্ট ডেটা দিয়ে আপ-টু-ডেট থাকে।

রাইট-থ্রু ক্যাশিং-এর একটি সিম্পল ডায়াগ্রাম:

রেডিস ক্যাশিং দিয়ে গ্লোবাল ডাটাবেস পারফরম্যান্স ত্বারান্বিত করুন

এই কৌশল ক্যাশ এবং ডাটাবেসের মধ্যে ডেটা কনসিস্টেন্সি নিশ্চিত করে এবং কোনো রিকোয়েস্ট বেশি লেটেন্সি অনুভব করে না কারণ ডেটা ইতিমধ্যে উপলব্ধ থাকে ইউজার রিকোয়েস্টের জন্য অপেক্ষা করার প্রয়োজন নেই। তবে, অসুবিধা হলো ক্যাশে সকল ডেটা থাকে, এমনকি যদি তা দরকার না হয়। এর পাশাপাশি, প্রতিটি রাইট অপারেশন লেটেন্সি পাবে কারণ ডেটা ক্যাশেও লিখা হবে।

গ্লোবাল রেডিস কী? গ্লোবাল রেডিসের সুবিধা

এখন তদনার.SQL ডাটাবেসের পারফরম্যান্স আরও উন্নত করার উপায় দেখি।

লেটেন্সির আরেকটি উৎস হলো ডাটাবেসের লোকেশন। অধিকাংশ ক্ষেত্রে, প্রাইমারি ডাটাবেস নির্দিষ্ট রিজনে অবস্থিত। কিন্তু ডেটা নিকটতম লোকেশনে পৌঁছানো উচিত যাতে ডেটা স্টোরের দূরত্বের কারণে হোনা যাওয়া ডিলে মিনিমাইজ করা যায়।

এই সমস্যা আপস্ট্যাশ প্রদত্ত গ্লোবালি ডিস্ট্রিবিউটেড রেডিস ব্যবহার করে প্রতিরোধ করা যায়।

গ্লোবাল রেডিস একটি ডিস্ট্রিবিউটেড ক্যাশিং সমাধান যা ডেটা একাধিক ভৌগলিক লোকেশনে রেপ্লিকেট করে, গ্লোবালি ডিস্ট্রিবিউটেড অ্যাপ্লিকেশনের জন্য লো-লেটেন্সি অ্যাক্সেস নিশ্চিত করে।

দ্রুত দেখি কীভাবে গ্লোবাল রেডিস তৈরি করতে হয়। প্রথমে, আপস্ট্যাশ কনসোলে লগইন করুন।

লগইন করার পর, এখানে একটি রেডিস ডাটাবেস তৈরি করতে পারবেন। আপস্ট্যাশ রিড রেপ্লিকার লোকেট করার জন্য একাধিক লোকেশন প্রদান করে।

রেডিস ক্যাশিং দিয়ে গ্লোবাল ডাটাবেস পারফরম্যান্স ত্বারান্বিত করুন

রিড লোকেশন সিলেক্ট করার পর, আপনি আপনার প্ল্যান সিলেক্ট করতে পারেন এবং অবশেষে আপনার রেডিস ডাটাবেস তৈরি করতে পারেন। এটাই সব!

কনসোলে, ডাটাবেস তৈরি হওয়ার পরও আপনি রিজন যোগ/বাদ দিতে পারেন।

রেডিস ক্যাশিং দিয়ে গ্লোবাল ডাটাবেস পারফরম্যান্স ত্বারান্বিত করুন

গ্লোবাল রেডিস ডাটাবেস প্রধানত গ্লোবালি ডিস্ট্রিবিউটেড অ্যাপ্লিকেশন এবং এজ রানটাইমে চলমান অ্যাপ্লিকেশন দ্বারা ব্যবহৃত হয়।

গ্লোবালি ডিস্ট্রিবিউটেড অ্যাপ্লিকেশনের জন্য কম লেটেন্সি

গ্লোবালি ডিস্ট্রিবিউটেড সিস্টেমে, লেটেন্সি প্রায়শই একটি বটলনেক হয়ে ওঠে ইউজার এবং সেন্ট্রাল ডাটাবেস বা ক্যাশের মধ্যে ভৌতিক দূরত্বের কারণে। গ্লোবাল রেডিস একাধিক ভৌগলিকভাবে ডিস্ট্রিবিউটেড নোড জুড়ে ডেটা রেপ্লিকেট করে এটি সমাধান করে।

যখন একটি ইউজার ডেটা রিকোয়েস্ট করে, সবচেয়ে নিকটবর্তী ক্যাশ নোড রিকোয়েস্ট সার্ভ করে, নেটওয়ার্ক ট্রাভেল টাইম 劇的に কমিয়ে দেয়। এই লোকালাইজড অ্যাক্সেস দ্রুত রেসপন্স টাইম এবং একটি কনসিস্টেন্ট ইউজার এক্সপেরিয়েন্স নিশ্চিত করে, ইউজারের লোকেশন নির্বিশেষে।

মান লই, যদি একজন ইউজার টোকিওতে থাকে, কিন্তু ডাটাবেস ডাব্লিনে থাকে, তাহলে দূরত্ব ইউজারের রেসপন্স দেরি করবে। যদি আপস্ট্যাশ রেডিসের একটি রিড রেপ্লিকা ইউরোপে থাকে, তবে রিকোয়েস্ট সবচেয়ে নিকটবর্তী রিড রেপ্লিকায় রাউট করা যায়, যা এই কেসে ইউরোপের সেটি।

এজ রানটাইমের জন্য কম লেটেন্সি ডেটা (যেমন Cloudflare Workers)

এজ রানটাইম হলো এমন এনভায়রনমেন্ট যা কোড এক্সিকিউট করে নেটওয়ার্কের এজে, এন্ড ইউজারের কাছাকাছি। এজ রানটাইম অ্যাপ্লিকেশন লজিক বিশ্বব্যাপী একাধিক এজ লোকেশনে ডিস্ট্রিবিউট করে। এই আর্কিটেকচার ইউজার এবং তাদের রিকোয়েস্ট এক্সিকিউশনের মধ্যে ভৌতিক দূরত্ব কমায়, লেটেন্সি উল্লেখযোগ্যভাবে কমিয়ে পারফরম্যান্স উন্নত করে।

যদিও এজ রানটাইম কম্পিউটেশন ইউজারের কাছে আনে, অধিকাংশ অপারেশনের জন্য সেটিকে ডেটা অ্যাক্সেসের প্রয়োজন পড়ে, যেন ইউজার-স্পেসিফিক ইনফরমেশন, সেশন টোকেন, বা কনফিগারেশন রিট্রিভ করা যায়। একটি ক্যাশিং লেয়ার ছাড়া, প্রতিটি রিকোয়েস্ট এখনও একটি সেন্ট্রাল ডাটাবেসে রাউন্ড ট্রিপ করবে, লেটেন্সি সুবিধার অনেক অংশ নাল করে দেবে। এটি হলো যেখানে গ্লোবাল রেডিস একটি গুরুত্বপূর্ণ ভূমিকা পালন করে, কারণ সেগুলো ঘন ঘন ব্যবহৃত ডেটা এজে রেপ্লিকেট করে, লো-লেটেন্সি অ্যাক্সেস নিশ্চিত করে।

উদাহরণ কোড ১: Node.js-এ PostgreSQL

গ্লোবাল রেডিসের সাথে ক্যাশিং পারফেক্ট। এখন, আমরা একটি কোড স্যাম্পল দেখব যা আপস্ট্যাশ রেডিস এবং একটি পোস্টগ্রেসকিউএল ডাটাবেসের সাথে ক্যাশ-অসাইড কৌশল ইমপ্লিমেন্ট করে।

প্রথমে আমাদের সেই SDK গুলো ইনস্টল করতে হবে যেগুলো ডেটা স্টোরের সাথে কানেক্ট করার জন্য ব্যবহার করা হবে।

npm install pg upstash/redis 

একবার ডিপেন্ডেন্সি ইনস্টল হলে, আমরা ডেটা স্টোরের সাথে কানেক্ট করতে পারি, আপস্ট্যাশ রেডিস এবং পোস্টগ্রেস।

const { Redis } = require('@upstash/redis'); // Upstash Redis SDK const { Client } = require('pg'); const redis = new Redis({ url: <UPSTASH_REDIS_REST_URL>, token: <UPSTASH_REDIS_REST_TOKEN>, }) const client = new Client({ user: 'username', password: 'password', host: 'host', port: 'port_number', database: 'database_name', }); client.connect();

এখন আমাদের ডেটা অ্যাক্সেস লেয়ারের ফাংশন লিখি। এই ফাংশন আপনার চাহিদা অনুযায়ী মডিফাই করা যায়।

মান লই, আমরা ইউজার ইনফরমেশন আপনার ওয়েবসাইটে userId দিয়ে দেখাতে চাই। এই কেসে, আমাদের একটি ফাংশন থাকা উচিত যা userId প্যারামিটার হিসেবে নেয়

async function getUserData(userId) { // প্রথমে ক্যাশ চেক করুন const cachedData = await redis.get(userId); if (cachedData) { console.log('Cache hit'); return JSON.parse(cachedData); } // ডাটাবেসে ফলব্যাক console.log('Cache miss'); const query = 'SELECT * FROM users WHERE id = $1'; const { rows } = await client.query(query, [userId]); await redis.set(userId, JSON.stringify(rows), { EX: 300 }); // ৫ মিনিট ক্যাশ করুন return rows; }

হয়েছে! এখন এই ফাংশন প্রথমে চেক করবে ইউজার ইনফরমেশন রিকোয়েস্টারের রিজনের নিকটতম রেডিস ডাটাবেসে উপলব্ধ কিনা। যদি উপলব্ধ না থাকে, তবে এটি রিকোয়েস্ট করা ডেটা পোস্টগ্রেসকিউএল ডাটাবেস থেকে কোয়েরি করবে এবং রিটার্ন করা ডেটা আপস্ট্যাশ রেডিস প্রাইমারি রিজনে লিখবে। প্রাইমারি রিজনে লিখা ডেটা স্বয়ংক্রিয়ভাবে সব রিড রেপ্লিকায় কপি হয়ে যাবে।

উদাহরণ কোড ২: Python-এ MySQL

এখন, আরেকটি উদাহরণ দেখি। এইবার, আমরা সেম ক্যাশ ইমপ্লিমেন্টেশন করব, কিন্তু মেন ডাটাবেস হবে MySQL। এছাড়া, আমরা এই ফাংশন পাইথনে লিখব যাতে পাইথন-ভিত্তিক অ্যাপ্লিকেশনে কীভাবে কাজ করে তা দেখা যায়।

সদায়ের মত, প্রথমে ডাটাবেস কানেক্ট করার জন্য ব্যবহৃত ডিপেন্ডেন্সি ডাউনলোড করব।

pip install upstash-redis upstash-redis 

এখন, আমরা ক্লায়েন্ট ইনিশিয়ালাইজ এবং কানেক্ট করতে পারি।

import upstash_redis import mysql.connector import json # Initialize Upstash Redis client redis_client = upstash_redis.Redis( url='<your-upstash-redis-url>', token='<your-upstash-token>' ) # Initialize MySQL client db = mysql.connector.connect( host="<your-mysql-host>", user="<your-mysql-user>", password="<your-mysql-password>", database="<your-database-name>" ) cursor = db.cursor(dictionary=True)

কানেকশন প্রস্তুত। এখন আমরা পূর্বের সেকশনে ইমপ্লিমেন্ট করা সিমিলার ফাংশন ইমপ্লিমেন্ট করব।

def get_user_data(userId): # ক্যাশে ডেটা চেক করুন cache_data = redis_client.get(key) if cache_data: print("Cache hit") return json.loads(cache_data) # যদি ক্যাশ মিস, MySQL ডাটাবেস কোয়েরি করুন print("Cache miss") cursor.execute("SELECT * FROM users WHERE key = %s", (userId)) result = cursor.fetchone() if result: # ১ ঘন্টার TTL সহ ডেটা ক্যাশে সংরক্ষণ করুন redis_client.set(key, json.dumps(result), ex=3600) return result

উপসংহার

আপনার আর্কিটেকচারে গ্লোবাল রেডিস ইন্টিগ্রেট করে, আপনি SQL-ভিত্তিক অ্যাপ্লিকেশনের জন্য উল্লেখযোগ্য পারফরম্যান্স গেইন অর্জন করতে পারেন, বিশেষ করে গ্লোবালি ডিস্ট্রিবিউটেড এনভায়রনমেন্টে। লো-লেটেন্সি অ্যাক্সেস, কম ডাটাবেস লোড, এবং এজ রানটাইমের সাথে কম্প্যাটিবিলিটি নিয়ে গ্লোবাল রেডিস SQL ডাটাবেস সহ অ্যাপ্লিকেশনের পারফরম্যান্স চ্যালেঞ্জ সমাধান করতে পারে।

এই ব্লগ পোস্টে, আমরা গ্লোবাল রেডিসের সাথে ক্যাশিংয়ের সুবিধা ও কিছু উদাহরণ দেখেছি। এইগুলোরা শুধু বেসিক উদাহরণ যা আপনার চাহিদা অনুযায়ী আরও এক্সটেন্ড করা যায়।

আশা করি এই ব্লগ আপনাকে গ্লোবাল রেডিসের শক্তি লিভারেজ করা শুরু করার জন্য একটি ভালো শুরু দেয়।


  1. অ্যান্ড্রয়েড WebView-এ অভ্যন্তরীণ পেজ নেভিগেশন (Internal Page Navigation) কিভাবে সক্ষম করবেন?

  2. অ্যান্ড্রয়েড SQLite-এ DISTINCT এবং COUNT ব্যবহার করা

  3. AWS Elastic Beanstalk এবং RDS-এ Rails 6 স্মূথলি ডিপ্লয় করুন: সম্পূর্ণ গাইড

  4. জাভাস্ক্রিপ্টে অন্য অবজেক্ট দিয়ে অবজেক্ট অ্যাক্সেস করা