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


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

- মূলত, বিতরণ করা ক্যাশে, জি ডেটা একাধিক সার্ভারের মধ্যে সংরক্ষণ এবং ভাগ করা হয়
- এছাড়া, যখন আমরা একটি মাল্টি-টেন্যান্ট অ্যাপ্লিকেশন ব্যবহার করি তখন একাধিক সার্ভারের মধ্যে লোড পরিচালনা করার পরে অ্যাপ্লিকেশনটির স্কেলেবিলিটি এবং কর্মক্ষমতা উন্নত করা সহজ হয়
- ধরুন, ভবিষ্যতে যদি একটি সার্ভার ক্র্যাশ হয়ে পুনরায় চালু হয় তাহলে অ্যাপ্লিকেশনটির কোনো প্রভাব পড়বে না কারণ আমরা চাইলে একাধিক সার্ভার আমাদের প্রয়োজন অনুযায়ী আছে
রেডিস হল সবচেয়ে জনপ্রিয় ক্যাশে, যা আজকাল অনেক কোম্পানি ব্যবহার করে অ্যাপ্লিকেশনের কর্মক্ষমতা এবং স্কেলেবিলিটি উন্নত করতে। তাই, আমরা একে একে রেডিস এবং এর ব্যবহার নিয়ে আলোচনা করতে যাচ্ছি।
রিডিস ক্যাশে
- রেডিস একটি ওপেন সোর্স (বিএসডি লাইসেন্সপ্রাপ্ত) ইন-মেমরি ডেটা স্ট্রাকচার স্টোর একটি ডাটাবেস হিসাবে ব্যবহৃত হয়৷
- মূলত, এটি প্রায়শই ব্যবহৃত এবং কিছু স্ট্যাটিক ডেটা ক্যাশের ভিতরে সংরক্ষণ করতে এবং ব্যবহারকারীর প্রয়োজন অনুসারে ব্যবহার ও সংরক্ষণ করতে ব্যবহৃত হয়।
- Redis-এ অনেক ডেটা স্ট্রাকচার রয়েছে যা আমরা ডাটা সংরক্ষণের জন্য তালিকা, সেট, হ্যাশিং, স্ট্রিম এবং আরও অনেক কিছু ব্যবহার করতে পারি।
রেডিস ক্যাশে ইনস্টলেশন
ধাপ 1। নিম্নলিখিত URL ব্যবহার করে Redis সার্ভার ডাউনলোড করুন৷
৷https://github.com/microsoftarchive/redis/releases/tag/win-3.0.504
ধাপ 2। জিপ ফাইলটি বের করুন এবং পরে রেডিস সার্ভার এবং রেডিস সিএলআই খুলুন।

.NET Core API ব্যবহার করে Redis ক্যাশে বাস্তবায়ন
ধাপ 1। .NET কোর API ওয়েব অ্যাপ্লিকেশন তৈরি করুন
ধাপ 2। নিম্নলিখিত NuGet প্যাকেজগুলি ইনস্টল করুন, যার জন্য আমাদের অ্যাপ্লিকেশনে ধাপে ধাপে প্রয়োজন
- Microsoft.EntityFrameworkCore
- Microsoft.EntityFrameworkCore.Design
- Microsoft.EntityFrameworkCore.SqlServer
- Microsoft.EntityFrameworkCore.Tools
- Swashbuckle.AspNetCore
- StackExchange.Redis
ধাপ 3। মডেল ফোল্ডার তৈরি করুন এবং বিস্তারিত সহ একটি পণ্য ক্লাস তৈরি করুন।
namespace RedisCacheDemo.Model
{
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public string ProductDescription { get; set; }
public int Stock { get; set; }
}
}
ধাপ 4। এরপরে, ডাটাবেস অপারেশনের জন্য DbContextClass ক্লাস তৈরি করুন, যেমনটি আমি নীচে দেখিয়েছি।
using Microsoft.EntityFrameworkCore;
using RedisCacheDemo.Model;
namespace RedisCacheDemo.Data {
public class DbContextClass: DbContext {
public DbContextClass(DbContextOptions < DbContextClass > options): base(options) {}
public DbSet < Product > Products {
get;
set;
}
}
} ধাপ 5। এখন, আমরা Redis ক্যাশে-সম্পর্কিত ব্যবহারের জন্য ICacheService ইন্টারফেস এবং CacheService ক্লাস তৈরি করতে যাচ্ছি।
using System;
namespace RedisCacheDemo.Cache
{
public interface ICacheService
{
/// <summary>
/// Get Data using key
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
T GetData<T>(string key);
/// <summary>
/// Set Data with Value and Expiration Time of Key
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expirationTime"></param>
/// <returns></returns>
bool SetData<T>(string key, T value, DateTimeOffset expirationTime);
/// <summary>
/// Remove Data
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
object RemoveData(string key);
}
}
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
namespace RedisCacheDemo.Cache {
public class CacheService: ICacheService {
private IDatabase _db;
public CacheService() {
ConfigureRedis();
}
private void ConfigureRedis() {
_db = ConnectionHelper.Connection.GetDatabase();
}
public T GetData < T > (string key) {
var value = _db.StringGet(key);
if (!string.IsNullOrEmpty(value)) {
return JsonConvert.DeserializeObject < T > (value);
}
return default;
}
public bool SetData < T > (string key, T value, DateTimeOffset expirationTime) {
TimeSpan expiryTime = expirationTime.DateTime.Subtract(DateTime.Now);
var isSet = _db.StringSet(key, JsonConvert.SerializeObject(value), expiryTime);
return isSet;
}
public object RemoveData(string key) {
bool _isKeyExist = _db.KeyExists(key);
if (_isKeyExist == true) {
return _db.KeyDelete(key);
}
return false;
}
}
} ধাপ 6। প্রোডাক্ট কন্ট্রোলার ক্লাস তৈরি করুন এবং নিচে দেখানো পদ্ধতিটি তৈরি করুন।
using Microsoft.AspNetCore.Mvc;
using RedisCacheDemo.Cache;
using RedisCacheDemo.Data;
using RedisCacheDemo.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace RedisCacheDemo.Controllers {
[Route("api/[controller]")]
[ApiController]
public class ProductController: ControllerBase {
private readonly DbContextClass _dbContext;
private readonly ICacheService _cacheService;
public ProductController(DbContextClass dbContext, ICacheService cacheService) {
_dbContext = dbContext;
_cacheService = cacheService;
}
[HttpGet("products")]
public IEnumerable < Product > Get() {
var cacheData = _cacheService.GetData < IEnumerable < Product >> ("product");
if (cacheData != null) {
return cacheData;
}
var expirationTime = DateTimeOffset.Now.AddMinutes(5.0);
cacheData = _dbContext.Products.ToList();
_cacheService.SetData < IEnumerable < Product >> ("product", cacheData, expirationTime);
return cacheData;
}
[HttpGet("product")]
public Product Get(int id) {
Product filteredData;
var cacheData = _cacheService.GetData < IEnumerable < Product >> ("product");
if (cacheData != null) {
filteredData = cacheData.Where(x => x.ProductId == id).FirstOrDefault();
return filteredData;
}
filteredData = _dbContext.Products.Where(x => x.ProductId == id).FirstOrDefault();
return filteredData;
}
[HttpPost("addproduct")]
public async Task < Product > Post(Product value) {
var obj = await _dbContext.Products.AddAsync(value);
_cacheService.RemoveData("product");
_dbContext.SaveChanges();
return obj.Entity;
}
[HttpPut("updateproduct")]
public void Put(Product product) {
_dbContext.Products.Update(product);
_cacheService.RemoveData("product");
_dbContext.SaveChanges();
}
[HttpDelete("deleteproduct")]
public void Delete(int Id) {
var filteredData = _dbContext.Products.Where(x => x.ProductId == Id).FirstOrDefault();
_dbContext.Remove(filteredData);
_cacheService.RemoveData("product");
_dbContext.SaveChanges();
}
}
} ধাপ 7। appsetting.json এর ভিতরে SQL সার্ভার সংযোগ স্ট্রিং এবং Redis URL যোগ করুন।
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"RedisURL": "127.0.0.1:6379",
"ConnectionStrings": {
"DefaultConnection": "Data Source=Server;Initial Catalog=RedisCache;User Id=sa;Password=***;"
}
} ধাপ 8। এর পরে, স্টার্টআপ ক্লাসের কনফিগার পরিষেবা পদ্ধতির মধ্যে ICacheService নিবন্ধন করুন এবং আমাদের API শেষ পয়েন্টগুলি পরীক্ষা করতে Swagger সম্পর্কিত কিছু কনফিগারেশন যোগ করুন৷
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using RedisCacheDemo.Cache;
using RedisCacheDemo.Data;
namespace RedisCacheDemo {
public class Startup {
public Startup(IConfiguration configuration) {
Configuration = configuration;
}
public IConfiguration Configuration {
get;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) {
services.AddControllers();
services.AddScoped < ICacheService, CacheService > ();
services.AddDbContext < DbContextClass > (options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new OpenApiInfo {
Title = "RedisCacheDemo", Version = "v1"
});
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "RedisCacheDemo v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
});
}
}
} ধাপ 9। সেখানে অ্যাপ সেটিং কনফিগার করতে একটি ConfigurationManger ক্লাস তৈরি করুন
using Microsoft.Extensions.Configuration;
using System.IO;
namespace RedisCacheDemo {
static class ConfigurationManager {
public static IConfiguration AppSetting {
get;
}
static ConfigurationManager() {
AppSetting = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").Build();
}
}
} ধাপ 10। এরপরে, Redis কানেকশনের জন্য একটি কানেকশন হেল্পার ক্লাস তৈরি করুন।
using StackExchange.Redis;
using System;
namespace RedisCacheDemo.Cache {
public class ConnectionHelper {
static ConnectionHelper() {
ConnectionHelper.lazyConnection = new Lazy < ConnectionMultiplexer > (() => {
return ConnectionMultiplexer.Connect(ConfigurationManager.AppSetting["RedisURL"]);
});
}
private static Lazy < ConnectionMultiplexer > lazyConnection;
public static ConnectionMultiplexer Connection {
get {
return lazyConnection.Value;
}
}
}
} ধাপ 11। প্যাকেজ ম্যানেজার কনসোলে নিম্নলিখিত কমান্ডগুলি ব্যবহার করে DB তৈরির জন্য মাইগ্রেশন এবং ডেটাবেস আপডেটগুলি সম্পাদন করুন৷
add-migration “FirstMigration”
update-database সুতরাং, আপনি যখন এই কমান্ডটি প্রবেশ করবেন এবং কার্যকর করবেন, তখন এটি মাইগ্রেশন সম্পর্কিত কিছু জিনিস তৈরি করবে এবং SQL সার্ভারের মধ্যে ডাটাবেস তৈরি করবে যেমন আপনি appsetting.json-এ কানেকশন স্ট্রিং এর ভিতরে রাখবেন।
ধাপ 12। অবশেষে, অ্যাপ্লিকেশনটি চালান এবং swagger UI ব্যবহার করে ডেটা যোগ করুন এবং তারপর পণ্য এবং পণ্যের শেষ পয়েন্টের ভিতরে ক্যাশিং কীভাবে কাজ করে তা পরীক্ষা করুন৷
মূলত, আমি কন্ট্রোলারে পণ্য এবং পণ্যের শেষ পয়েন্টগুলিতে ক্যাশে যুক্ত করেছি; যেমন আপনি দেখতে পাচ্ছেন, ব্যবহারকারী যখন সমস্ত পণ্যের ডেটা আনতে চায়, তখন প্রথমে, এটি Redis ক্যাশের ভিতরে ডেটা উপস্থিত আছে কিনা তা পরীক্ষা করবে এবং যদি এটি ক্যাশের ভিতরে থাকে তবে সেই ডেটা ব্যবহারকারীকে ফেরত দেয়, এবং যদি ডেটা ক্যাশের ভিতরে উপস্থিত না থাকে তবে এটি ডাটাবেস থেকে ডেটা আনবে এবং ক্যাশে সেট করবে। তাই পরের বার ব্যবহারকারী এটি শুধুমাত্র ক্যাশে থেকে পাবেন এবং অপ্রয়োজনীয়ভাবে ডাটাবেস আঘাত করা এড়াবেন
এছাড়াও, যখন ব্যবহারকারী পণ্য আইডি ব্যবহার করে ডেটা আনতে চায়, যেমন আপনি পণ্যের দ্বিতীয় এন্ডপয়েন্টের কন্ট্রোলারে দেখেন, আমরা সমস্ত পণ্যের ক্যাশে থেকে ডেটা নিয়ে আসি এবং তারপর পণ্য আইডি ব্যবহার করে ফিল্টার করি। যদি এটি উপস্থিত থাকে, আমরা ক্যাশে থেকে ব্যবহারকারীর কাছে ফিরে আসি; যদি না হয়, আমরা ডাটাবেস থেকে নিয়ে আসি এবং ফিল্টার প্রয়োগ করার পরে ব্যবহারকারীর কাছে ফিরে আসি।
আপনি প্রোডাক্ট কন্ট্রোলারের আপডেট, ডিলিট এবং পোস্ট এন্ডপয়েন্টের ভিতরে দেখেন, আমরা ক্যাশে থেকে প্রোডাক্ট কী ডেটা মুছে ফেলার জন্য রিমুভ পদ্ধতি ব্যবহার করি। মেমরি ক্যাশের অনেক পরিস্থিতি এবং ব্যবহার রয়েছে যা আপনি আপনার প্রয়োজন এবং প্রয়োজনীয়তা অনুসারে ব্যবহার করতে পারেন। আমি শুধু Redis ক্যাশের মূল বিষয়গুলি এবং এটি কীভাবে .NET কোরের ভিতরে কাজ করে তা আমি এখানে কভার করেছি।
এছাড়াও, ক্যাশিং ব্যবহার করার সময় আপনাকে একটি পরিস্থিতির যত্ন নিতে হবে। ধরুন দুইজন ব্যবহারকারী আপনার অ্যাপ্লিকেশন ব্যবহার করছেন। তারপর নিম্নলিখিত পরিস্থিতি ঘটবে৷
৷- যখন প্রথম ব্যবহারকারী সমস্ত পণ্যের ডেটা আনার অনুরোধ পাঠায়, তখন প্রথম অনুরোধ আসে, এবং তারপরে এটি পরীক্ষা করবে যে ডেটা ক্যাশের ভিতরে উপস্থিত আছে কি না। যদি ডেটা ক্যাশের ভিতরে থাকে, তাহলে এটি ডাটাবেস থেকে ডেটা আনবে এবং ক্যাশে সেটও করবে৷
- এদিকে, দ্বিতীয় ব্যবহারকারী পণ্যের বিবরণ পেতে অনুরোধ পাঠান। কি হয়েছে যে অনুরোধটি প্রথম ব্যবহারকারীর অনুরোধটি সম্পূর্ণ করার আগে ডাটাবেসে আঘাত করে এবং সেই কারণে দ্বিতীয় ব্যবহারকারীও পণ্যের বিবরণ আনতে ডাটাবেসে আঘাত করে।
- সুতরাং, নীচে দেখানো হিসাবে লক মেকানিজম ব্যবহার করার জন্য এর জন্য একটি সমাধান রয়েছে
ক্লাসের উপরে লকের এই ব্যক্তিগত বস্তুটি তৈরি করুন।
private static object _lock = new object() এরপরে, আমি নীচের মত গেট পদ্ধতি পরিবর্তন করুন।
public IEnumerable < Product > Get() {
var cacheData = _cacheService.GetData < IEnumerable < Product >> ("product");
if (cacheData != null) {
return cacheData;
}
lock(_lock) {
var expirationTime = DateTimeOffset.Now.AddMinutes(5.0);
cacheData = _dbContext.Products.ToList();
_cacheService.SetData < IEnumerable < Product >> ("product", cacheData, expirationTime);
}
return cacheData;
} তাই এখানে, যেমন আপনি দেখতে পাচ্ছেন, প্রথমে আমরা পরীক্ষা করি যে ডেটা ক্যাশের ভিতরে আছে কি না। যদি ডেটা পাওয়া যায়, তাহলে সেটি ফেরত দিন। এরপরে, যদি Redis ক্যাশে মানটি উপস্থিত না থাকে, তাহলে আমরা সেখানে লকটি প্রয়োগ করি এবং তারপর অনুরোধটি লক করা হয় এবং বিভাগে প্রবেশ করে ডাটাবেস থেকে পণ্যের বিবরণ আনয়ন করে এবং তারপরে এটি ক্যাশে সেট করে এবং ডেটা ফেরত দেয়। সুতরাং, ব্যবহারকারীর অনুরোধ সম্পূর্ণ হওয়ার আগে দ্বিতীয় ব্যবহারকারী একটি অনুরোধ পাঠালে কী হবে? সুতরাং, সেই ক্ষেত্রে, দ্বিতীয় অনুরোধটি সারিতে রয়েছে এবং প্রথম ব্যবহারকারীর অনুরোধটি সম্পূর্ণ করার পরে, দ্বিতীয় অনুরোধটি ছবিতে আসে
এছাড়াও, আপনি মূল বিবরণ দেখতে পারেন যা ইতিমধ্যে Redis CLI ব্যবহার করে Redis-এর ভিতরে উপস্থিত রয়েছে, যেমন নীচে দেখানো হয়েছে

সুতরাং, এখানে আপনি দেখতে পাচ্ছেন যে অনেকগুলি কমান্ড রয়েছে যা আমাদের রেডিস ক্যাশে উপস্থিত কীগুলি সম্পর্কে তথ্য সরবরাহ করে৷
এটি .NET কোরে রেডিস ক্যাশে সম্পর্কে। আমি আশা করি আপনি এর সাথে সম্পর্কিত বিষয়গুলি বুঝতে পেরেছেন৷
শুভ কোডিং!