مقدمه
بهینهسازی عملکرد برنامهها از اهمیت ویژهای برخوردار است. یکی از تکنیکهای کلیدی برای دستیابی به این هدف، استفاده از حافظه نهان (Caching) است که با ذخیرهسازی دادههای پرکاربرد، زمان دسترسی به اطلاعات را کاهش میدهد و بار روی پایگاه داده یا سرویسهای خارجی را کم میکند. در اکوسیستم داتنت (.NET)، دو کتابخانه برجسته برای پیادهسازی حافظه نهان ترکیبی (Hybrid Caching) وجود دارند: FusionCache و HybridCache. این دو ابزار، با ترکیب حافظه نهان محلی (In-Memory Cache) و حافظه نهان توزیعشده (Distributed Cache)، عملکرد و قابلیت اطمینان بالایی را فراهم میکنند. اما تفاوتهای این دو کتابخانه در چیست و کدام یک برای پروژه شما مناسبتر است؟ این مقاله به مقایسه جامع FusionCache و HybridCache میپردازد، ویژگیها، مزایا و معایب هر یک را بررسی میکند و با ارائه مثالهای عملی، به توسعهدهندگان کمک میکند تا انتخابی آگاهانه داشته باشند.
حافظه نهان ترکیبی چیست و چرا مهم است؟
حافظه نهان ترکیبی (Hybrid Caching) رویکردی است که مزایای حافظه نهان محلی (L1 Cache) و حافظه نهان توزیعشده (L2 Cache) را ترکیب میکند. حافظه نهان محلی، که معمولاً در حافظه RAM سرور ذخیره میشود، سرعت بالایی دارد اما محدود به یک سرور است و در محیطهای چندسروری ممکن است ناسازگاری داده ایجاد کند. از سوی دیگر، حافظه نهان توزیعشده، مانند Redis، امکان اشتراک دادهها بین چندین سرور را فراهم میکند اما به دلیل تأخیر شبکه، کندتر است.
حافظه نهان ترکیبی با استفاده از الگوی دوسطحی عمل میکند:
- سطح اول (L1): دادهها در حافظه محلی ذخیره میشوند و دسترسی به آنها بسیار سریع است. معمولاً این دادهها برای مدت کوتاهی (مثلاً 5 دقیقه) نگهداری میشوند.
- سطح دوم (L2): دادهها در یک سیستم توزیعشده مانند Redis ذخیره میشوند و برای مدت طولانیتر (مثلاً 1 ساعت) در دسترس هستند.
این رویکرد باعث میشود برنامه ابتدا حافظه محلی را بررسی کند، سپس به حافظه توزیعشده مراجعه کند و در نهایت، در صورت عدم وجود داده، به منبع اصلی (مانند پایگاه داده) رجوع کند. این الگو از مشکلاتی مانند «هجوم به حافظه نهان» (Cache Stampede)، که در آن درخواستهای همزمان متعدد به پایگاه داده فشار وارد میکنند، جلوگیری میکند.
معرفی FusionCache و HybridCache
FusionCache
FusionCache یک کتابخانه متنباز (Open-Source) تحت مجوز MIT است که توسط جامعه توسعهدهندگان پشتیبانی میشود. این کتابخانه با بیش از 2,100 ستاره در GitHub و بیش از 7 میلیون دانلود از NuGet، یکی از گزینههای محبوب برای پیادهسازی حافظه نهان ترکیبی در داتنت است. FusionCache ویژگیهای پیشرفتهای مانند محافظت در برابر هجوم (Stampede Protection)، پشتیبانی از Backplane برای هماهنگی بین گرهها، و گزینههای زمانبندی پیشرفته (Advanced Timeouts) ارائه میدهد.
HybridCache
HybridCache کتابخانهای رسمی از مایکروسافت است که با هدف سادهسازی پیادهسازی حافظه نهان ترکیبی در داتنت طراحی شده است. این کتابخانه، که با نسخه 9.3 داتنت در مارس 2025 بهصورت رسمی منتشر شد، با اکوسیستم داتنت کاملاً یکپارچه است و از پشتیبانی رسمی مایکروسافت برخوردار است. اگرچه HybridCache ویژگیهای کمتری نسبت به FusionCache دارد، اما سادگی و پایداری آن، آن را به گزینهای جذاب برای پروژههای جدید تبدیل کرده است.
مقایسه ویژگیها
جدول زیر ویژگیهای کلیدی FusionCache و HybridCache را مقایسه میکند:
| ویژگی | FusionCache | HybridCache |
| توسعهدهنده | جامعه (ZiggyCreatures) | مایکروسافت |
| مجوز | MIT | MIT |
| ستارههای GitHub | 2,100+ | - (فقط در NuGet) |
| دانلودهای NuGet | 7M+ | 1M+ (تا مه 2025) |
| پشتیبانی از L1+L2 | بله | بله |
| محافظت در برابر هجوم | بله | بله |
| برچسبگذاری/ابطال | بله | خیر |
| حالت ایمن در برابر خطا | بله | خیر |
| زمانبندی پیشرفته | بله | خیر |
| Backplane (هماهنگی گرهها) | بله | خیر |
| حافظههای نامگذاریشده | بله | خیر |
| پشتیبانی از OpenTelemetry | بله | بله |
| پشتیبانی رسمی | خیر | بله |
نحوه راهاندازی و استفاده
هر دو کتابخانه از الگوهای مشابهی برای استفاده بهره میبرند، اما تفاوتهایی در پیکربندی و جزئیات پیادهسازی دارند. در ادامه، مثالهایی از راهاندازی و استفاده از هر کتابخانه ارائه میشود.
راهاندازی FusionCache
برای استفاده از FusionCache، ابتدا باید سرویس را در فایل Program.cs ثبت کنید و یک سریالساز (Serializer) مشخص کنید، زیرا FusionCache بهطور پیشفرض سریالساز ندارد. کد زیر یک نمونه پیکربندی را نشان میدهد:
services.AddFusionCache()
.WithDefaultEntryOptions(new FusionCacheEntryOptions
{
Duration = TimeSpan.FromMinutes(5), // انقضای L1: 5 دقیقه
DistributedCacheDuration = TimeSpan.FromHours(1) // انقضای L2: 1 ساعت
})
.WithDistributedCache(new RedisCache(new RedisCacheOptions
{
Configuration = "REDIS_CONNECTION_STRING"
}))
.WithSerializer(new FusionCacheSystemTextJsonSerializer());برای استفاده، میتوانید از متد GetOrSetAsync برای دریافت یا ذخیره داده در حافظه نهان استفاده کنید:
var result = await fusionCache.GetOrSetAsync(
key,
async _ => await LoadDataAsync(),
options: new FusionCacheEntryOptions
{
Duration = TimeSpan.FromMinutes(5), // انقضای L1 برای این کلید
DistributedCacheDuration = TimeSpan.FromHours(1) // انقضای L2 برای این کلید
},
token: cancellationToken
);این کد ابتدا بررسی میکند که آیا داده با کلید مشخص در حافظه نهان موجود است یا خیر. اگر دادهای وجود نداشته باشد، تابع LoadDataAsync فراخوانی میشود و نتیجه در حافظه نهان ذخیره میشود.
راهاندازی HybridCache
برای HybridCache، ابتدا باید حافظه توزیعشده (مانند Redis) را ثبت کنید و سپس سرویس HybridCache را اضافه کنید. کد زیر یک نمونه پیکربندی را نشان میدهد:
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("REDIS_CONNECTION_STRING");
});
builder.Services.AddHybridCache(options =>
{
options.DefaultEntryOptions = new HybridCacheEntryOptions
{
LocalCacheExpiration = TimeSpan.FromMinutes(5), // انقضای L1: 5 دقیقه
Expiration = TimeSpan.FromHours(1) // انقضای L2: 1 ساعت
};
})
.AddSerializer<System.Text.Json.JsonSerializerOptions, SystemTextJsonHybridCacheSerializer>();برای استفاده، از متد GetOrCreateAsync استفاده میشود:
var result = await hybridCache.GetOrCreateAsync(
key,
async _ => await LoadDataAsync(),
options: new HybridCacheEntryOptions
{
LocalCacheExpiration = TimeSpan.FromMinutes(5), // انقضای L1 برای این کلید
Expiration = TimeSpan.FromHours(1) // انقضای L2 برای این کلید
},
cancellationToken
);این کد عملکردی مشابه FusionCache دارد، اما به دلیل یکپارچگی با اکوسیستم داتنت، پیکربندی آن سادهتر است.
تفاوتهای کلیدی
- ویژگیهای پیشرفته: FusionCache با ارائه قابلیتهایی مانند حالت ایمن در برابر خطا (Fail-Safe)، پشتیبانی از Backplane برای هماهنگی بین گرهها، و برچسبگذاری (Tagging) برای مدیریت پیشرفتهتر حافظه نهان، گزینهای قدرتمند برای پروژههای پیچیده است. در مقابل، HybridCache روی سادگی و یکپارچگی تمرکز دارد و برخی از این ویژگیهای پیشرفته را ارائه نمیدهد.
- پشتیبانی رسمی: HybridCache از پشتیبانی رسمی مایکروسافت برخوردار است، که احتمال پایداری طولانیمدت و بهروزرسانیهای مداوم را افزایش میدهد. FusionCache، اگرچه توسط جامعهای فعال پشتیبانی میشود، ممکن است در معرض تغییرات یا عدم تداوم توسعه باشد.
- انعطافپذیری در برابر سادگی: FusionCache برای توسعهدهندگانی که به کنترل دقیقتر و ویژگیهای سفارشی نیاز دارند مناسب است. HybridCache برای پروژههایی که به راهحلی ساده و استاندارد نیاز دارند، ایدهآل است.
کدام را انتخاب کنیم؟
انتخاب بین FusionCache و HybridCache به نیازهای پروژه شما بستگی دارد:
FusionCache را انتخاب کنید اگر:
- به ویژگیهای پیشرفته مانند Backplane، برچسبگذاری، یا حالت ایمن در برابر خطا نیاز دارید.
- پروژه شما نیاز به انعطافپذیری بالا و کنترل دقیق بر رفتار حافظه نهان دارد.
- با استفاده از یک کتابخانه جامعهمحور مشکلی ندارید.
HybridCache را انتخاب کنید اگر:
- سادگی و یکپارچگی با اکوسیستم داتنت برای شما اولویت دارد.
- به پشتیبانی رسمی مایکروسافت اهمیت میدهید.
- پروژه شما به ویژگیهای پیشرفته نیاز ندارد و یک راهحل استاندارد کافی است.
با توجه به اینکه HybridCache به عنوان بخشی از داتنت 9 و نسخههای بعدی در حال تبدیل شدن به استاندارد است، احتمالاً در آینده پذیرش بیشتری خواهد داشت. اما FusionCache با سابقه طولانیتر و ویژگیهای غنیتر، همچنان گزینهای قدرتمند برای پروژههای پیچیده است.
نتیجهگیری
حافظه نهان ترکیبی راهحلی قدرتمند برای بهبود عملکرد برنامههای داتنت است که با ترکیب سرعت حافظه محلی و قابلیت اطمینان حافظه توزیعشده، تجربهای بهینه را برای کاربران فراهم میکند. FusionCache و HybridCache هر دو ابزارهای ارزشمندی برای این منظور هستند، اما تفاوتهای آنها در ویژگیها، پیچیدگی و پشتیبانی، انتخاب را به نیازهای خاص پروژه وابسته میکند. FusionCache با ارائه قابلیتهای پیشرفته و انعطافپذیری بالا، برای پروژههای پیچیده مناسب است، در حالی که HybridCache با سادگی و پشتیبانی رسمی، گزینهای ایدهآل برای پروژههای استاندارد و جدید است. توسعهدهندگان باید با ارزیابی نیازهای پروژه خود، از جمله مقیاسپذیری، پیچیدگی و اهمیت پشتیبانی رسمی، تصمیم بگیرند که کدام کتابخانه برای آنها مناسبتر است.