<पी> यह आलेख Azure Redis Cache की मूल बातें और .NET कोर वेब API का उपयोग करके उनके कार्यान्वयन पर चर्चा करता है। एजेंडा
- परिचय
- कैश क्या है?
- कैश के प्रकार
- रेडिस कैश
- Azure Redis कैश सेटअप
- चरण-दर-चरण कार्यान्वयन
<पी> पूर्वापेक्षाएँ पी> - विजुअल स्टूडियो 2022
- Azure खाता
- .NET कोर 6
परिचय
<पी> आजकल सॉफ्टवेयर उद्योग में कैशिंग बहुत लोकप्रिय है क्योंकि यह एप्लिकेशन के प्रदर्शन और स्केलेबिलिटी में सुधार करेगा। हम जीमेल और फेसबुक जैसे कई वेब एप्लिकेशन का उपयोग करते हैं और देखते हैं कि वे कितने प्रतिक्रियाशील हैं और हमारे पास एक शानदार उपयोगकर्ता अनुभव है। इंटरनेट का उपयोग करने वाले बहुत सारे उपयोगकर्ता हैं और यदि किसी एप्लिकेशन में भारी नेटवर्क ट्रैफ़िक और मांग है, तो हमें कई चीजों का ध्यान रखना होगा जो हमें एप्लिकेशन के प्रदर्शन और प्रतिक्रिया को बेहतर बनाने में मदद करते हैं। तो, उसके कारण, कैशिंग का समाधान है और इसीलिए कैशिंग तस्वीर में आती है। कैश क्या है?
<पी> कैश वह मेमोरी स्टोरेज है जिसका उपयोग बार-बार एक्सेस किए जाने वाले डेटा को अस्थायी स्टोरेज में संग्रहीत करने के लिए किया जाता है, यह प्रदर्शन में काफी सुधार करेगा और अनावश्यक डेटाबेस हिट से बचाएगा और अक्सर उपयोग किए जाने वाले डेटा को कैश में संग्रहीत करेगा। <पी>
<पी>
<पी> जैसा कि आप उपरोक्त छवि में देख सकते हैं, दो परिदृश्य हैं, एक कैश का उपयोग किए बिना है और दूसरा कैश के साथ है। तो यहां जब हम कैश का उपयोग नहीं करते हैं, उस स्थिति में, मान लीजिए कि उपयोगकर्ता डेटा चाहते हैं तो वे हर बार डेटाबेस पर हिट करेंगे और इससे समय की जटिलता बढ़ जाएगी और प्रदर्शन कम हो जाएगा यदि कुछ स्थिर डेटा है जो उपयोगकर्ता चाहते हैं और यह सभी उपयोगकर्ताओं के लिए समान है। जब हम कैश का उपयोग नहीं करते हैं, तो प्रत्येक डेटा लाने के लिए अनावश्यक डेटाबेस से टकराता है। दूसरी ओर। आप देख सकते हैं कि हम कैश का उपयोग करते हैं, और उस स्थिति में, यदि सभी उपयोगकर्ताओं के लिए समान स्थिर और समान डेटा है, तो केवल पहला उपयोगकर्ता डेटाबेस को हिट करेगा और डेटा लाएगा और इसे कैश मेमोरी में संग्रहीत करेगा, और फिर अन्य दो उपयोगकर्ताओं ने डेटा लाने के लिए डेटाबेस को अनावश्यक रूप से हिट किए बिना कैश से इसका उपयोग किया। कैश के प्रकार
<पी> मूल रूप से, कैशिंग दो प्रकार की होती है .NET कोर सपोर्ट - इन-मेमोरी कैशिंग
- वितरित कैशिंग
<पी> जब हम इन-मेमोरी कैश का उपयोग करते हैं, तो डेटा एप्लिकेशन सर्वर मेमोरी में संग्रहीत होता है; जब भी हमें इसकी आवश्यकता होती है, हम उससे डेटा लाते हैं और जहां भी हमें इसकी आवश्यकता होती है, उसका उपयोग करते हैं। और डिस्ट्रीब्यूटेड कैशिंग में रेडिस और कई अन्य जैसे कई तृतीय-पक्ष तंत्र हैं। लेकिन इस अनुभाग में, हम रेडिस कैश पर विस्तार से नज़र डालते हैं और यह .NET कोर में कैसे काम करता है <पी> वितरित कैशिंग पी> <पी>
- मूल रूप से, वितरित कैशिंग में डेटा को कई सर्वरों के बीच संग्रहीत और साझा किया जाता है
- इसके अलावा, जब हम मल्टी-टेनेंट एप्लिकेशन का उपयोग करते हैं, तो कई सर्वरों के बीच लोड को प्रबंधित करने के बाद एप्लिकेशन की स्केलेबिलिटी और प्रदर्शन में सुधार करना आसान होता है
- मान लीजिए, भविष्य में, यदि एक सर्वर क्रैश हो जाता है और पुनरारंभ होता है तो एप्लिकेशन पर कोई प्रभाव नहीं पड़ता है क्योंकि यदि हम चाहें तो एकाधिक सर्वर हमारी आवश्यकता के अनुसार हैं
<पी> रेडिस सबसे लोकप्रिय कैश है जिसका उपयोग आजकल कई कंपनियां एप्लिकेशन के प्रदर्शन और स्केलेबिलिटी को बेहतर बनाने के लिए करती हैं। तो, हम एक-एक करके रेडिस और इसके उपयोग पर चर्चा करने जा रहे हैं। <पी> रेडिस कैश पी> - रेडिस एक ओपन सोर्स (बीएसडी लाइसेंस प्राप्त) इन-मेमोरी डेटा स्ट्रक्चर स्टोर है जिसका उपयोग डेटाबेस के रूप में किया जाता है।
- मूल रूप से, इसका उपयोग अक्सर उपयोग किए जाने वाले और कुछ स्थिर डेटा को कैश के अंदर संग्रहीत करने और उपयोगकर्ता की आवश्यकता के अनुसार उपयोग और आरक्षित करने के लिए किया जाता है।
- रेडिस में कई डेटा संरचनाएं मौजूद हैं जिनका उपयोग हम डेटा को स्टोर करने के लिए लिस्ट, सेट, हैशिंग, स्ट्रीम और कई अन्य चीजों का उपयोग कर सकते हैं।
Azure Redis कैश सेटअप
<पी> चरण 1 पी> <पी> Azure पोर्टल में लॉग इन करें। <पी> चरण 2 पी> <पी> बाज़ार में Redis के लिए Azure कैश खोजें और इसे खोलें। <पी>
<पी> चरण 3 पी> <पी> क्रिएट पर क्लिक करें और अन्य जानकारी प्रदान करें। <पी>
<पी>
<पी>
<पी>
<पी> चरण 4 पी> <पी> इसके बाद कैश के अंदर एक्सेस कुंजी अनुभाग पर जाएं जिसे हमने पहले बनाया था और प्राथमिक कनेक्शन स्ट्रिंग को कॉपी करें जिसकी हमें .NET कोर वेब एपीआई के अंदर आवश्यकता है। <पी>
चरण-दर-चरण कार्यान्वयन
<पी> चरण 1 पी> <पी> विज़ुअल स्टूडियो खोलें और एक नया .NET कोर वेब एपीआई प्रोजेक्ट बनाएं। <पी>
<पी> चरण 2 पी> <पी> एक नया प्रोजेक्ट कॉन्फ़िगर करें. <पी>
<पी> चरण 3 पी> <पी> अतिरिक्त विवरण प्रदान करें. <पी>
<पी> चरण 4 पी> <पी> परियोजना संरचना. <पी>
<पी> चरण 5 पी> <पी> उत्पाद विवरण वर्ग बनाएं.
namespace AzureRedisCacheDemo.Models {
public class ProductDetails {
public int Id {
get;
set;
}
public string ProductName {
get;
set;
}
public string ProductDescription {
get;
set;
}
public int ProductPrice {
get;
set;
}
public int ProductStock {
get;
set;
}
}
}
<पी> चरण 6 पी> <पी> इसके बाद, डेटा फ़ोल्डर के अंदर डीबी कॉन्टेक्स्ट क्लास जोड़ें।
using AzureRedisCacheDemo.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
namespace AzureRedisCacheDemo.Data {
public class DbContextClass: DbContext {
public DbContextClass(DbContextOptions < DbContextClass > options): base(options) {}
public DbSet < ProductDetails > Products {
get;
set;
}
}
}
<पी> चरण 7 पी> <पी> उसके बाद, सीड डेटा क्लास जोड़ें जिसका उपयोग हम शुरुआत में कुछ डेटा डालने के लिए करते हैं।
using AzureRedisCacheDemo.Models;
using Microsoft.EntityFrameworkCore;
namespace AzureRedisCacheDemo.Data
{
public class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var context = new DbContextClass(
serviceProvider.GetRequiredService<DbContextOptions<DbContextClass>>()))
{
if (context.Products.Any())
{
return;
}
context.Products.AddRange(
new ProductDetails
{
Id = 1,
ProductName = "IPhone",
ProductDescription = "IPhone 14",
ProductPrice = 120000,
ProductStock = 100
},
new ProductDetails
{
Id = 2,
ProductName = "Samsung TV",
ProductDescription = "Smart TV",
ProductPrice = 400000,
ProductStock = 120
});
context.SaveChanges();
}
}
}
}
<पी> चरण 8 पी> <पी> Appsettings.json फ़ाइल के अंदर Azure Redis Cache कनेक्शन स्ट्रिंग को कॉन्फ़िगर करें।
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"RedisURL": "<valuefromportal>"
}
<पी> चरण 9 पी> <पी> हेल्पर फ़ोल्डर के अंदर कॉन्फ़िगरेशन मैनेजर और कनेक्शन हेल्पर क्लास बनाएं जिसका उपयोग हम कनेक्शन उद्देश्यों के लिए करते हैं। <पी> कॉन्फ़िगरेशन प्रबंधक पी>
namespace AzureRedisCacheDemo.Helper {
static class ConfigurationManager {
public static IConfiguration AppSetting {
get;
}
static ConfigurationManager() {
AppSetting = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").Build();
}
}
}
<पी> कनेक्शन सहायक पी>
using StackExchange.Redis;
namespace AzureRedisCacheDemo.Helper {
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;
}
}
}
}
<पी> चरण 10 पी> <पी> इसके बाद, रिपॉजिटरी के अंदर IProductService जोड़ें।
using AzureRedisCacheDemo.Models;
namespace AzureRedisCacheDemo.Repositories {
public interface IProductService {
public Task < List < ProductDetails >> ProductListAsync();
public Task < ProductDetails > GetProductDetailByIdAsync(int productId);
public Task < bool > AddProductAsync(ProductDetails productDetails);
public Task < bool > UpdateProductAsync(ProductDetails productDetails);
public Task < bool > DeleteProductAsync(int productId);
}
}
<पी> चरण 11 पी> <पी> इसके बाद, ProductService क्लास बनाएं और उसके अंदर IProductService इंटरफ़ेस लागू करें।
using AzureRedisCacheDemo.Data;
using AzureRedisCacheDemo.Models;
using Microsoft.EntityFrameworkCore;
using System.Linq;
namespace AzureRedisCacheDemo.Repositories {
public class ProductService: IProductService {
private readonly DbContextClass dbContextClass;
public ProductService(DbContextClass dbContextClass) {
this.dbContextClass = dbContextClass;
}
public async Task < List < ProductDetails >> ProductListAsync() {
return await dbContextClass.Products.ToListAsync();
}
public async Task < ProductDetails > GetProductDetailByIdAsync(int productId) {
return await dbContextClass.Products.Where(ele => ele.Id == productId).FirstOrDefaultAsync();
}
public async Task < bool > AddProductAsync(ProductDetails productDetails) {
await dbContextClass.Products.AddAsync(productDetails);
var result = await dbContextClass.SaveChangesAsync();
if (result > 0) {
return true;
} else {
return false;
}
}
public async Task < bool > UpdateProductAsync(ProductDetails productDetails) {
var isProduct = ProductDetailsExists(productDetails.Id);
if (isProduct) {
dbContextClass.Products.Update(productDetails);
var result = await dbContextClass.SaveChangesAsync();
if (result > 0) {
return true;
} else {
return false;
}
}
return false;
}
public async Task < bool > DeleteProductAsync(int productId) {
var findProductData = dbContextClass.Products.Where(_ => _.Id == productId).FirstOrDefault();
if (findProductData != null) {
dbContextClass.Products.Remove(findProductData);
var result = await dbContextClass.SaveChangesAsync();
if (result > 0) {
return true;
} else {
return false;
}
}
return false;
}
private bool ProductDetailsExists(int productId) {
return dbContextClass.Products.Any(e => e.Id == productId);
}
}
}
<पी> चरण 12 पी> <पी> एक IRedisCache इंटरफ़ेस बनाएं।
namespace AzureRedisCacheDemo.Repositories.AzureRedisCache {
public interface IRedisCache {
T GetCacheData < T > (string key);
bool SetCacheData < T > (string key, T value, DateTimeOffset expirationTime);
object RemoveData(string key);
}
}
<पी> चरण 13 पी> <पी> उसके बाद, एक RedisCache क्लास बनाएं और उसके अंदर इंटरफ़ेस विधि लागू करें जो हमने पहले बनाई थी।
using AzureRedisCacheDemo.Helper;
using Newtonsoft.Json;
using StackExchange.Redis;
namespace AzureRedisCacheDemo.Repositories.AzureRedisCache
{
public class RedisCache : IRedisCache
{
private IDatabase _db;
public RedisCache()
{
ConfigureRedis();
}
private void ConfigureRedis()
{
_db = ConnectionHelper.Connection.GetDatabase();
}
public T GetCacheData<T>(string key)
{
var value = _db.StringGet(key);
if (!string.IsNullOrEmpty(value))
{
return JsonConvert.DeserializeObject<T>(value);
}
return default;
}
public object RemoveData(string key)
{
bool _isKeyExist = _db.KeyExists(key);
if (_isKeyExist == true)
{
return _db.KeyDelete(key);
}
return false;
}
public bool SetCacheData<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;
}
}
}
<पी> चरण 14 पी> <पी> एक नया उत्पाद नियंत्रक बनाएं.
using AzureRedisCacheDemo.Models;
using AzureRedisCacheDemo.Repositories;
using AzureRedisCacheDemo.Repositories.AzureRedisCache;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace AzureRedisCacheDemo.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
private readonly IProductService _productService;
private readonly IRedisCache _redisCache;
public ProductsController(IProductService productService, IRedisCache redisCache)
{
_productService = productService;
_redisCache = redisCache;
}
/// <summary>
/// Product List
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<ActionResult<List<ProductDetails>>> ProductListAsync()
{
var cacheData = _redisCache.GetCacheData<List<ProductDetails>>("product");
if (cacheData != null)
{
return new List<ProductDetails>(cacheData);
}
var productList = await _productService.ProductListAsync();
if(productList != null)
{
var expirationTime = DateTimeOffset.Now.AddMinutes(5.0);
_redisCache.SetCacheData<List<ProductDetails>>("product", productList, expirationTime);
return Ok(productList);
}
else
{
return NoContent();
}
}
/// <summary>
/// Get Product By Id
/// </summary>
/// <param name="productId"></param>
/// <returns></returns>
[HttpGet("{productId}")]
public async Task<ActionResult<ProductDetails>> GetProductDetailsByIdAsync(int productId)
{
var cacheData = _redisCache.GetCacheData<List<ProductDetails>>("product");
if (cacheData != null)
{
ProductDetails filteredData = cacheData.Where(x => x.Id == productId).FirstOrDefault();
return new ActionResult<ProductDetails>(filteredData);
}
var productDetails = await _productService.GetProductDetailByIdAsync(productId);
if(productDetails != null)
{
return Ok(productDetails);
}
else
{
return NotFound();
}
}
/// <summary>
/// Add a new product
/// </summary>
/// <param name="productDetails"></param>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> AddProductAsync(ProductDetails productDetails)
{
var isProductInserted = await _productService.AddProductAsync(productDetails);
_redisCache.RemoveData("product");
if (isProductInserted)
{
return Ok(isProductInserted);
}
else
{
return BadRequest();
}
}
/// <summary>
/// Update product details
/// </summary>
/// <param name="productDetails"></param>
/// <returns></returns>
[HttpPut]
public async Task<IActionResult> UpdateProductAsync(ProductDetails productDetails)
{
var isProductUpdated = await _productService.UpdateProductAsync(productDetails);
_redisCache.RemoveData("product");
if (isProductUpdated)
{
return Ok(isProductUpdated);
}
else
{
return BadRequest();
}
}
/// <summary>
/// Delete product by id
/// </summary>
/// <param name="productId"></param>
/// <returns></returns>
[HttpDelete]
public async Task<IActionResult> DeleteProductAsync(int productId)
{
var isProductDeleted = await _productService.DeleteProductAsync(productId);
_redisCache.RemoveData("product");
if (isProductDeleted)
{
return Ok(isProductDeleted);
}
else
{
return BadRequest();
}
}
}
}
<पी> चरण 15 पी> <पी> प्रोग्राम क्लास के अंदर कुछ सेवाएँ पंजीकृत करें।
using AzureRedisCacheDemo.Data;
using AzureRedisCacheDemo.Models;
using AzureRedisCacheDemo.Repositories;
using AzureRedisCacheDemo.Repositories.AzureRedisCache;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using System;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddScoped < IProductService, ProductService > ();
builder.Services.AddDbContext < DbContextClass > (o => o.UseInMemoryDatabase("RedisCacheDemo"));
builder.Services.AddScoped < IRedisCache, RedisCache > ();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
using(var scope = app.Services.CreateScope()) {
var services = scope.ServiceProvider;
var context = services.GetRequiredService < DbContextClass > ();
SeedData.Initialize(services);
}
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
<पी> चरण 16 पी> <पी> अंत में, एप्लिकेशन चलाएं और हम अपने एपीआई के एंडपॉइंट के साथ स्वैगर यूआई देख सकते हैं। <पी>
<पी> चरण 17 पी> <पी> उत्पाद समापन बिंदु प्राप्त करें को दबाएं और Azure पोर्टल के अंदर Redis CLI खोलें और वहां आप देख सकते हैं कि जब हम पहली बार समापन बिंदु पर पहुंचेंगे तो उत्पाद सूची संग्रहीत हो जाएगी। <पी>
<पी> इस मामले में, सबसे पहले, हम जांचते हैं कि डेटा कैश में मौजूद है या नहीं। यदि नहीं तो हम डेटाबेस से डेटा प्राप्त करते हैं और इसे कैश में भी सहेजते हैं। उससे संबंधित कोड हम पहले से ही कंट्रोलर के अंदर लिख देते हैं। तो, अगली बार हमें कैश से डेटा मिलेगा। यदि आप कंट्रोलर के अंदर डिबगर लगाते हैं तो आप आसानी से समझ सकते हैं कि चीजें कैसे काम करने वाली हैं। <पी> गिटहब यूआरएल पी> <पी> https://github.com/Jayदीप-007/AzureRedisCacheDemo/tree/master/AzureRedisCacheDemo निष्कर्ष
<पी> यहां हमने एज़्योर पर कैश परिचय और उनके कॉन्फ़िगरेशन पर ध्यान दिया। साथ ही, .NET कोर वेब एपीआई का उपयोग करके चरण-दर-चरण कार्यान्वयन।