Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Redis

.NET Core API में Redis कैशिंग एकीकरण: प्रदर्शन और स्केलेबिलिटी के लिए

परिचय

हम .NET Core में कैशिंग पर चर्चा करने जा रहे हैं और यह कैसे काम करता है। तो, हम निम्नलिखित चीजों को एक-एक करके देखेंगे।

  • कैशिंग का परिचय
  • कैश क्या है
  • कैश के प्रकार
  • कैश कार्यान्वयन

कैशिंग आजकल सॉफ्टवेयर उद्योग में बहुत लोकप्रिय है क्योंकि यह एप्लिकेशन के प्रदर्शन और स्केलेबिलिटी में सुधार करता है। हम Gmail और Facebook जैसे कई वेब एप्लिकेशन का उपयोग करते हैं और देखते हैं कि वे कितने प्रतिक्रियाशील हैं, और हमारे पास एक शानदार उपयोगकर्ता अनुभव है। इंटरनेट का उपयोग करने वाले बहुत सारे उपयोगकर्ता हैं और यदि किसी एप्लिकेशन में भारी नेटवर्क ट्रैफिक और मांग है, तो हमें कई चीजों का ध्यान रखना होगा जो एप्लिकेशन के प्रदर्शन और प्रतिक्रियाशीलता को बेहतर बनाने में मदद करती हैं। इसलिए, उसके कारण, कैशिंग का समाधान है, और इसीलिए कैशिंग तस्वीर में आता है।

तो, आइए एक-एक करके शुरू करते हैं।

कैशिंग क्या है?

कैश वह मेमोरी स्टोरेज है जिसका उपयोग अक्सर एक्सेस किए जाने वाले डेटा को अस्थायी भंडारण में स्टोर करने के लिए किया जाता है, यह प्रदर्शन को काफी हद तक सुधारता है, अनावश्यक डेटाबेस हिट से बचाता है और जब भी हमें इसकी आवश्यकता होती है, बार-बार उपयोग किए जाने वाले डेटा को बफर में स्टोर करता है।

.NET Core API में Redis कैशिंग एकीकरण: प्रदर्शन और स्केलेबिलिटी के लिए

.NET Core API में Redis कैशिंग एकीकरण: प्रदर्शन और स्केलेबिलिटी के लिए

जैसा कि आप ऊपर की छवि में देख सकते हैं, दो परिदृश्य हैं, एक कैश का उपयोग किए बिना, और दूसरा कैश के साथ। तो यहां, जब हम कैश का उपयोग नहीं करते हैं, तो उस मामले में, मान लीजिए उपयोगकर्ता डेटा चाहते हैं, तो वे हर बार डेटाबेस को हिट करेंगे, और यह समय जटिलता बढ़ाएगा और प्रदर्शन को कम करेगा यदि कुछ स्थिर डेटा है जो उपयोगकर्ता चाहते हैं, और यह सभी उपयोगकर्ताओं के लिए समान है। उस मामले में, जब हम कैश का उपयोग नहीं करते हैं, तो हर कोई डेटा लाने के लिए अनावश्यक रूप से डेटाबेस को हिट करता है। दूसरी तरफ, जैसा कि आप देख सकते हैं, हम कैश का उपयोग करते हैं, और उस मामले में, यदि सभी उपयोगकर्ताओं के लिए समान स्थिर और समान डेटा है, तो केवल पहला उपयोगकर्ता डेटाबेस को हिट करेगा, डेटा लाएगा, और इसे कैश मेमोरी में स्टोर करेगा और फिर अन्य दो उपयोगकर्ता डेटाबेस को अनावश्यक रूप से हिट किए बिना कैश से इसका उपयोग करेंगे।

कैश के प्रकार

मूल रूप से, .NET Core दो प्रकार के कैशिंग का समर्थन करता है।

  1. इन-मेमोरी कैशिंग
  2. वितरित कैशिंग

जब हम इन-मेमोरी कैश का उपयोग करते हैं, तो उस मामले में डेटा एप्लिकेशन सर्वर मेमोरी में संग्रहीत होता है, और जब भी हमें इसकी आवश्यकता होती है, हम उससे डेटा लाते हैं और जहां भी हमें इसकी आवश्यकता होती है इसका उपयोग करते हैं। और वितरित कैशिंग में, Redis जैसे कई तृतीय-पक्ष तंत्र हैं। लेकिन इस खंड में, हम Redis Cache को विस्तार से देखते हैं और यह .NET Core में कैसे काम करता है।

वितरित कैशिंग

.NET Core API में Redis कैशिंग एकीकरण: प्रदर्शन और स्केलेबिलिटी के लिए

  • मूल रूप से, वितरित कैशिंग में, डेटा कई सर्वरों के बीच संग्रहीत और साझा किया जाता है
  • साथ ही, जब हम मल्टी-टेनेंट एप्लिकेशन का उपयोग करते हैं तो कई सर्वरों के बीच लोड प्रबंधित करके एप्लिकेशन की स्केलेबिलिटी और प्रदर्शन में सुधार करना आसान होता है
  • मान लीजिए, भविष्य में, यदि एक सर्वर क्रैश हो जाता है और पुनः आरंभ होता है तो एप्लिकेशन पर कोई प्रभाव नहीं पड़ता क्योंकि कई सर्वर हमारी आवश्यकता के अनुसार होते हैं

Redis आजकल कई कंपनियों द्वारा एप्लिकेशन के प्रदर्शन और स्केलेबिलिटी को बेहतर बनाने के लिए उपयोग किया जाने वाला सबसे लोकप्रिय कैश है। तो, हम Redis और इसके उपयोग पर एक-एक करके चर्चा करने जा रहे हैं।

Redis Cache

  • Redis एक ओपन सोर्स (BSD लाइसेंस्ड) इन-मेमोरी डेटा स्ट्रक्चर स्टोर है जिसे डेटाबेस के रूप में उपयोग किया जाता है।
  • मूल रूप से, इसका उपयोग बार-बार उपयोग किए जाने वाले और कुछ स्थिर डेटा को कैश के अंदर स्टोर करने और उपयोगकर्ता की आवश्यकता के अनुसार उपयोग और आरक्षित करने के लिए किया जाता है।
  • Redis में कई डेटा संरचनाएं मौजूद हैं जिनका उपयोग हम List, Set, Hashing, Stream, और कई अन्य जैसे डेटा स्टोर करने के लिए कर सकते हैं।

Redis Cache का इंस्टॉलेशन

चरण 1. निम्नलिखित URL का उपयोग करके Redis सर्वर डाउनलोड करें।

https://github.com/microsoftarchive/redis/releases/tag/win-3.0.504

चरण 2. ज़िप फाइल निकालें और बाद में Redis सर्वर और Redis CLI खोलें।

.NET Core API में Redis कैशिंग एकीकरण: प्रदर्शन और स्केलेबिलिटी के लिए

.NET Core API का उपयोग करके Redis Cache का कार्यान्वयन

चरण 1. .NET Core API वेब एप्लिकेशन बनाएं

चरण 2. निम्नलिखित NuGet पैकेज इंस्टॉल करें, जिनकी हमारे एप्लिकेशन में चरण-दर-चरण आवश्यकता है

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Design
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Swashbuckle.AspNetCore
  • StackExchange.Redis

चरण 3. Model फोल्डर बनाएं और उसमें Product क्लास बनाएं जिसमें विवरण हों।

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 Cache संबंधित उपयोग के लिए ICacheService इंटरफेस और CacheService क्लास बनाने जा रहे हैं।

using System;
namespace RedisCacheDemo.Cache
{
    public interface ICacheService
    {
        T GetData<T>(string key);
        bool SetData<T>(string key, T value, DateTimeOffset expirationTime);
        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. ProductController क्लास बनाएं और नीचे दिखाए अनुसार निम्नलिखित मेथड बनाएं।

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 Server कनेक्शन स्ट्रिंग और 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. अगला, Startup क्लास के ConfigureServices मेथड में 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; }
        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" });
            });
        }
        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. ऐप सेटिंग को कॉन्फ़िगर करने के लिए एक ConfigurationManager क्लास बनाएं।

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 कनेक्शन के लिए एक ConnectionHelper क्लास बनाएं।

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 Server के अंदर डेटाबेस बनाएगा जैसा कि आपने appsetting.json में कनेक्शन स्ट्रिंग में डाला है।

चरण 12. अंत में, एप्लिकेशन चलाएं और Swagger UI का उपयोग करके डेटा जोड़ें और फिर जांचें कि उत्पाद और उत्पाद एंडपॉइंट के अंदर कैशिंग कैसे काम करता है।

मूल रूप से, मैंने उत्पाद और उत्पादों एंडपॉइंट्स में कंट्रोलर में कैश जोड़ा; जैसा कि आप देख सकते हैं, जब उपयोगकर्ता सभी उत्पादों का डेटा लाना चाहता है, तो सबसे पहले, यह जांच करेगा कि डेटा Redis Cache के अंदर मौजूद है या नहीं और यदि यह कैश के अंदर मौजूद है तो उस डेटा को उपयोगकर्ता को वापस कर दें, और यदि डेटा कैश के अंदर मौजूद नहीं है, तो यह डेटाबेस से डेटा लाएगा और साथ ही, इसे कैश में सेट करेगा। ताकि अगली बार उपयोगकर्ता को वह केवल कैश से मिले और डेटाबेस को अनावश्यक रूप से हिट करने से बचें।

साथ ही, जब उपयोगकर्ता उत्पाद ID का उपयोग करके डेटा लाना चाहता है, जैसा कि आप कंट्रोलर में दूसरे उत्पाद एंडपॉइंट में देखते हैं, हम सभी उत्पादों के कैश से डेटा लाते हैं और फिर उत्पाद ID का उपयोग करके फ़िल्टर करते हैं। यदि वह मौजूद है, तो हम कैश से उपयोगकर्ता को वापस करते हैं; यदि नहीं, तो हम डेटाबेस से लाते हैं और फ़िल्टर लागू करने के बाद उपयोगकर्ता को वापस करते हैं।

जैसा कि आप Product Controller के अपडेट, डिलीट, और पोस्ट एंडपॉइंट्स के अंदर देखते हैं, हम कैश से उत्पाद कुंजी डेटा को हटाने के लिए रिमूव मेथड का उपयोग करते हैं। कई परिदृश्य और मेमोरी कैश के उपयोग हैं जिनका उपयोग आप अपनी आवश्यकताओं और जरूरतों के अनुसार कर सकते हैं। मैंने यहां केवल Redis Cache की मूल बातें और यह .NET Core के अंदर कैसे काम करता है, इसे कवर किया है।

साथ ही, एक परिदृश्य है जिसका आपको कैशिंग का उपयोग करते समय ध्यान रखने की आवश्यकता है। मान लीजिए दो उपयोगकर्ता आपके एप्लिकेशन का उपयोग कर रहे हैं। तो निम्नलिखित परिदृश्य होंगे।

  • जब पहला उपयोगकर्ता सभी उत्पादों का डेटा लाने के लिए अनुरोध भेजता है, तो पहला अनुरोध आता है, और फिर यह जांच करेगा कि डेटा कैश के अंदर मौजूद है या नहीं। यदि डेटा कैश के अंदर मौजूद है, तो यह डेटाबेस से डेटा लाएगा और इसे कैश में भी सेट करेगा।
  • इस बीच, दूसरा उपयोगकर्ता उत्पाद विवरण प्राप्त करने के लिए अनुरोध भेजता है। क्या होता है कि पहला उपयोगकर्ता का अनुरोध पूरा होने से पहले अनुरोध भी डेटाबेस को हिट करता है, और इसके कारण दूसरा उपयोगकर्ता भी उत्पाद विवरण लाने के लिए डेटाबेस को हिट करता है।
  • तो, इसके लिए एक समाधान है लॉक मैकेनिज्म का उपयोग करना जैसा कि नीचे दिखाया गया है

क्लास के शीर्ष पर लॉक का यह प्राइवेट ऑब्जेक्ट बनाएं।

private static object _lock = new object()

अगला, Get मेथड को संशोधित करें जैसा कि मैंने नीचे दिखाया है।

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 Core API में Redis कैशिंग एकीकरण: प्रदर्शन और स्केलेबिलिटी के लिए

तो, यहां आप देख सकते हैं कि कई कमांड हैं जो हमें Redis Cache में मौजूद कुंजियों के बारे में जानकारी प्रदान करती हैं।

यह .NET Core में Redis Cache के बारे में सब कुछ है। मुझे आशा है कि आप इससे संबंधित चीजों को समझ गए होंगे।

हैप्पी कोडिंग!

  1. Android में PreferenceScreen पर बटन कैसे जोड़ें? Android में PreferenceScreen पर बटन कैसे जोड़ें?

    AndroidX Preference लाइब्रेरी का उपयोग करके सेटिंग्स स्क्रीन में कस्टम एक्शन बटन जोड़ने का तरीका। चरण 1: नया प्रोजेक्ट बनाएं Android Studio में नया प्रोजेक्ट बनाएं। चरण 2: एक्टिविटी लेआउट res/layout/activity_main.xml - Fragment कंटेनर: <LinearLayout xmlns:android=https://schemas.android.com/apk

  1. रियल-टाइम AI/ML का अनुकूलन: बेंचमार्क, आर्किटेक्चर, और सिद्ध फीचर स्टोर केस स्टडीज़ रियल-टाइम AI/ML का अनुकूलन: बेंचमार्क, आर्किटेक्चर, और सिद्ध फीचर स्टोर केस स्टडीज़

    धोखाधड़ी रोकथाम और अनुशंसा जैसे रियल-टाइम आर्टिफिशियल इंटेलिजेंस/मशीन लर्निंग (AI/ML) उपयोग के मामले बढ़ रहे हैं, और फीचर स्टोर्स उन्हें सफलतापूर्वक उत्पादन में तैनात करने में महत्वपूर्ण भूमिका निभाते हैं। लोकप्रिय ओपन सोर्स फीचर स्टोर Feast के अनुसार, उनके कम्युनिटी Slack में उपयोगकर्ताओं द्वारा पू

  1. एंड्रॉइड में डिफ़ॉल्ट सिम सीरियल नंबर कैसे प्राप्त करें? एंड्रॉइड में डिफ़ॉल्ट सिम सीरियल नंबर कैसे प्राप्त करें?

    एंड्रॉइड में सिम सीरियल नंबर (ICCID) प्राप्त करने का गाइड यह ट्यूटोरियल दिखाता है कि एंड्रॉइड ऐप में TelephonyManager का उपयोग करके सिम कार्ड का सीरियल नंबर (ICCID) कैसे प्राप्त करें। चरण 1: नया प्रोजेक्ट बनाएं Android Studio में File → New Project चुनें और प्रोजेक्ट विवरण भरें। चरण 2: लेआउट फ़ाइल