کش کردن اطلاعات در دات نت - Chaching in .Net

کش کردن اطلاعات در دات نت - Chaching in .Net

اهمیت caching در بهبود عملکرد برنامه

قبل از اینکه به ریزه کاری های کش در دات نت بپردازیم، بیایید بفهمیم که چرا کش برای افزایش عملکرد برنامه ها بسیار مهم است. در اینجا چند دلیل کلیدی وجود دارد که چرا caching نقش حیاتی در بهبود عملکرد برنامه دارد:

  • کاهش تاخیر: caching با ارائه نسخه ذخیره شده به جای محاسبه مجدد یا واکشی از منبع اصلی، به بازیابی سریعتر داده ها کمک می کند، در نتیجه تأخیر را کاهش می دهد و زمان پاسخ را بهبود می بخشد.
  • استفاده بهینه از منابع: با اجتناب از محاسبات اضافی یا واکشی داده‌ها، کش کردن استفاده از منابع را بهینه می‌کند، به‌ویژه در سناریوهایی که شامل عملیات پیچیده‌ای مانند کوئری‌های پایگاه داده یا درخواست‌های شبکه است.
  • مقیاس پذیری: caching در زمان افزایش تعداد کارران یا درخواست ها با توزیع کارآمد بار ، به بهبود مقیاس پذیری کمک می کند و تضمین می کند که برنامه پاسخگو و کارآمد باقی می ماند.
  • بهبود تجربه کاربری: زمان‌های پاسخ سریع‌تر ناشی از caching منجر به تجربه کاربری بهتری می‌شود و برنامه‌ها را جذاب‌تر و کاربرپسندتر می‌کند.
  • صرفه جویی در هزینه: caching به بهینه سازی استفاده از منابع، کاهش محاسبات اضافی و کاهش هزینه های عملیاتی کمک می کند و آن را به یک راه حل مقرون به صرفه در محیط های cloud-based یا سناریوهایی با metered resources تبدیل می کند.

استفاده های رایج caching

caching با ذخیره و استفاده مجدد از داده هایی که اغلب به آنها دسترسی پیدا می شود نقش حیاتی در بهینه سازی عملکرد برنامه دارد. بیایید به برخی از موارد استفاده رایج برای کش کردن در برنامه‌های NET عمیق‌تر بپردازیم:

افزایش سرعت محاسبات تکراری

سناریو: در برنامه هایی که محاسبات پیچیده به طور مکرر تکرار می شوند، ذخیره نتایج می تواند زمان پردازش را به میزان قابل توجهی کاهش دهد.

مثال: فرض کنید یک تابع ریاضی دارید که به محاسبات سنگین نیاز دارد. با کش کردن نتایج محاسبه‌شده، فراخوانی‌های بعدی تابع با همان ورودی را می‌توان از حافظه پنهان انجام داد و از محاسبات اضافی اجتناب کرد.

// Example caching computed results to speed up repetitive computations

public int CalculateFactorial(int n)

{

    var cacheKey = $"Factorial_{n}";

    if (memoryCache.TryGetValue(cacheKey, out int result))

    {

        return result;

    }

    result = CalculateFactorialInternal(n);

    memoryCache.Set(cacheKey, result, TimeSpan.FromMinutes(30));

    return result;

}

کاهش فراخوانی های پایگاه داده یا API

سناریو: وقتی یک برنامه به طور مکرر به منابع داده خارجی مانند پایگاه‌های داده یا APIها دسترسی پیدا می‌کند، ذخیره داده‌های بازیابی شده در حافظه پنهان می‌تواند تعداد تماس‌ها را کاهش داده و زمان پاسخ را بهبود بخشد.

مثال: یک پلتفرم تجارت الکترونیک را در نظر بگیرید که اطلاعات محصول را از پایگاه داده دریافت می کند. با کش کردن داده های محصول، درخواست های متعدد برای جزئیات یک محصول مشابه می تواند از حافظه پنهان ارائه شود و نیاز به پرس و جوهای مکرر پایگاه داده را از بین ببرد.

// Example caching API responses to reduce database/API calls
public async Task<Product> GetProductDetails(string productId)
{
    var cacheKey = $"Product_{productId}";
    var product = distributedCache.Get(cacheKey);
    if (product == null)
    {
        product = await apiClient.GetProductDetails(productId);
        distributedCache.Set(cacheKey, product, TimeSpan.FromMinutes(60));
    }
    return product;
}

ذخیره سازی داده های پر استفاده

سناریو: برنامه‌ها اغلب دارای داده‌هایی هستند که مکررا به آن‌ها دسترسی پیدا می‌شود اما به ندرت تغییر می‌کنند. ذخیره سازی این داده ها در حافظه پنهان می تواند با ارائه سریع آن به کاربران، عملکرد را بهبود بخشد.

مثال: در یک برنامه خبررسانی، ذخیره عناوین برتر در حافظه پنهان می‌تواند زمان بارگذاری را برای کاربرانی که مرتباً به آخرین اخبار دسترسی دارند، افزایش دهد. برای اطمینان از تازگی، تیترها را می توان برای یک دوره خاص ذخیره کرد.

public List<NewsHeadline> GetTopHeadlines()
{
    var cacheKey = "TopHeadlines";
    if (memoryCache.TryGetValue(cacheKey, out List<NewsHeadline> headlines))
    {
        return headlines;
    }
    headlines = newsService.GetTopHeadlines();
    memoryCache.Set(cacheKey, headlines, TimeSpan.FromMinutes(15));
    return headlines;
}

با استفاده موثر از کش در این سناریوهای رایج، توسعه دهندگان می توانند عملکرد برنامه را بهبود بخشند، زمان پاسخ را کاهش دهند و تجربه کلی کاربر را بهبود بخشند.

انواع Caching در .Net

کش In-Memory با استفاده از MemoryCache

در دات نت MemoryCache یک روش موثر برای کش کردن داده به صورت in-memory فراهم می کند. در مثال زیر میتونید روشی که داده با استفاده از MemoryCache کشده را ملاحظه کنید.

// Example caching data in MemoryCache
var cacheKey = "myCachedData";
var cachedData = MemoryCache.Default.Get(cacheKey) as string;
if (cachedData == null)
{
    // Data not in cache, fetch and cache it  
    cachedData = FetchDataFromSource();
    MemoryCache.Default.Add(cacheKey, cachedData, DateTimeOffset.Now.AddMinutes(30));
}
// Use cachedData...

در این مثال، با استفاده از یک کلید خاص، داده‌ها را از کش واکشی می‌کنیم و اگر داده‌ها در کش وجود نداشت، آن‌ها را از منبع داده واکشی می‌کنیم، با استفاده از MemoryCache آن‌ها را کش می‌کنیم و سپس از داده‌های کش استفاده می‌کنیم.

کش توزیع شده با استفاده از Redis

Redis یک راه حل محبوب caching توزیع شده است که می تواند با برنامه های NET ادغام شود. به مثال زیر نگاهی بیندازید که کش توزیع شده با Redis را نشان می دهد:

// Example of distributed caching with Redis using StackExchange.Redis
var cacheKey = "myCachedData";
var cachedData = await distributedCache.GetStringAsync(cacheKey);
if (cachedData == null)
{
    // Data not in cache, fetch and cache it
    cachedData = FetchDataFromSource();
    await distributedCache.SetStringAsync(cacheKey, cachedData, new DistributedCacheEntryOptions
    {
        AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30)
    });
}
// Use cachedData...

در این مثال، نحوه اجرای کش توزیع شده با استفاده از Redis در یک برنامه دات نت را نشان می دهیم و بازیابی و ذخیره داده ها را در یک محیط توزیع شده نشان می دهیم.

کش خروجی در Asp.Net

در ASP.NET، caching خروجی یک ویژگی ارزشمند است که به توسعه دهندگان اجازه می دهد خروجی یک کنترلر را در cache ذخیره کنند و عملکرد را با ارائه محتوای کش شده به جای تولید مجدد آن در هر درخواست، افزایش دهند. بیایید کش خروجی در ASP.NET را با مثالی دقیق تر بررسی کنیم:

// Example of output caching in an MVC controller action
[OutputCache(Duration = 3600, VaryByParam = "none")]
public ActionResult Index()
{
    // Code for generating view...  
    return View();
}

در قطعه کد بالا، attribute [OutputCache] به اکشن Index در یک کنترلر MVC اعمال می شود. attribute مشخص می کند که خروجی این اکشن باید به مدت 3600 ثانیه (1 ساعت) بدون تغییر بر اساس هیچ پارامتری در کش بماند. این مکانیسم کش با استفاده مجدد از خروجی کش به جای اجرای منطق عمل در هر درخواست، به بهبود پاسخگویی برنامه کمک می کند.

انقضا و باطل شدن کش

انقضای کش و باطل شدن آن جنبه های ضروری حفظ انسجام و کارایی کش در برنامه ها هستند. بیایید نگاهی دقیق‌تر به نحوه اجرای انقضای کش در MemoryCache بیندازیم:

// Example of setting cache expiration in MemoryCache
MemoryCache.Default.Add(cacheKey, cachedData, DateTimeOffset.Now.AddMinutes(30));

در قطعه کد بالا، از متد Add MemoryCache برای کش کردن cachedData با cacheKey مشخص و زمان انقضا 30 دقیقه از زمان فعلی استفاده می شود. این تضمین می کند که داده های ذخیره شده در کش به طور خودکار پس از دوره انقضای تعریف شده باطل و حذف می شوند و به حفظ تازگی و سازگاری کش کمک می کند.

با استفاده از کش خروجی در ASP.NET و اجرای استراتژی‌های مناسب انقضای کش، توسعه‌دهندگان می‌توانند به طور موثری عملکرد برنامه را بهبود بخشند، بار سرور را کاهش دهند و تجربه کاربر را با ارائه به موقع و کارآمد محتوای کش افزایش دهند.

Best practice ها و ملاحظات

هنگام پیاده سازی کش در برنامه های دات نت، بهترین روش ها و ملاحظات زیر را در نظر بگیرید:

  • ملاحظات اندازه کش برای جلوگیری از مشکلات حافظه
  • مدیریت موثر cache miss برای به حداقل رساندن تأثیرات روی عملکرد.
  • نظارت و مدیریت سلامت کش برای اطمینان از عملکرد بهینه.
  • استراتژی caching مناسب را بر اساس نیازمندیهای برنامه خود انتخاب کنید.

در نتیجه، کش کردن یک تکنیک قدرتمند است که می تواند عملکرد، مقیاس پذیری و مقرون به صرفه بودن برنامه های دات نت را به طور قابل توجهی افزایش دهد. با پیاده‌سازی یک استراتژی موثر کش کردن و پیروی از بهترین روش‌ها، می‌توانید پتانسیل کامل ذخیره‌سازی را در بهینه‌سازی عملکرد برنامه خود باز کنید.

 

منبع: https://dev.to/bytehide/caching-in-net-full-guide-31j4

 

اشتراک گذاری