🚀 کشینگ در ASP.NET Core (قسمت ۵):
مشکل Cache Stampede و آینده کشینگ در 9 Net.
تا اینجا با انواع کشینگ آشنا شدیم. اما وقتی ترافیک سیستم خیلی بالا میره، یه مشکل خطرناک و پنهان به اسم Cache Stampede (ازدحام کش) میتونه تمام زحمات ما رو به باد بده!
در قسمت آخر این سری، با این مشکل و راه حلهای مدرنش آشنا میشیم.
1️⃣ مشکل Cache Stampede چیست؟ 🔥
تصور کنید یه آیتم خیلی پرطرفدار (مثلاً صفحه اول سایت) در کش شما منقضی میشه. در یک لحظه، صدها یا هزاران درخواست همزمان میبینن که کش خالیه و همهشون با هم به سمت دیتابیس هجوم میارن تا اون داده رو بگیرن!
این هجوم ناگهانی، دیتابیس و اپلیکیشن شما رو از پا در میاره و عملاً مزیت کشینگ رو از بین میبره.
2️⃣ یک راه حل (ناقص): قفلگذاری با SemaphoreSlim 🔒
یک راه حل رایج، استفاده از قفلگذاری (Locking) هست. یعنی فقط به اولین درخواست اجازه بدیم که بره داده رو از دیتابیس بگیره و بقیه منتظر بمونن تا کش دوباره پر بشه.
میتونیم متد GetOrCreateAsync خودمون رو با SemaphoreSlim به این شکل تغییر بدیم:
public static class DistributedCacheExtensions
{
private static readonly SemaphoreSlim Semaphore = new(1, 1);
public static async Task<T> GetOrCreateAsync<T>(
this IDistributedCache cache, string key, Func<Task<T>> factory)
{
var cachedData = await cache.GetStringAsync(key);
if (cachedData is not null) return JsonSerializer.Deserialize<T>(cachedData);
try
{
await Semaphore.WaitAsync(); // منتظر قفل بمون
// دوباره کش رو چک کن، شاید درخواست قبلی پرش کرده باشه
cachedData = await cache.GetStringAsync(key);
if (cachedData is not null) return JsonSerializer.Deserialize<T>(cachedData);
// اگه هنوز خالی بود، از دیتابیس بگیر و کش رو پر کن
var data = await factory();
await cache.SetStringAsync(key, JsonSerializer.Serialize(data), ...);
return data;
}
finally
{
Semaphore.Release(); // قفل رو آزاد کن
}
}
}
🚫مشکل این راه حل: این کد از یه قفل سراسری برای تمام کلیدها استفاده میکنه. یعنی اگه ۱۰۰ تا درخواست برای ۱۰۰ تا کلید مختلف هم بیان، باز هم باید برای هم صبر کنن! این کارایی رو به شدت کم میکنه. (راه حل بهتر، قفلگذاری بر اساس key هست که پیچیدهتره).
3️⃣ آینده کشینگ: HybridCache در 9 Net. ✨
تیم داتنت برای حل این مشکلات (و مشکلات دیگه)، در 9 Net. یه ابزار جدید و خیلی قدرتمند به اسم HybridCache معرفی کرده.
این ابزار به صورت داخلی، مشکل Cache Stampede رو به روشی بهینه حل میکنه و ترکیبی از IMemoryCache (برای سرعت) و IDistributedCache (برای توزیعشدگی) رو به بهترین شکل ممکن ارائه میده.
جمعبندی سری و نظر شما 🤔
با این پست، مینی-سریال ما در مورد کشینگ به پایان میرسه. ما از مبانی شروع کردیم و به پیشرفتهترین مشکلات و جدیدترین راه حلها رسیدیم.
🔖 هشتگها:
#ASPNETCore #Caching